diff --git a/build.gradle b/build.gradle index 5d35e7aa..92e3f5b5 100644 --- a/build.gradle +++ b/build.gradle @@ -1,34 +1,44 @@ buildscript { repositories { - jcenter() - maven { url = "http://files.minecraftforge.net/maven" } + mavenCentral() + maven { + name = "forge" + url = "http://files.minecraftforge.net/maven" + } + maven { + name = "sonatype" + url = "https://oss.sonatype.org/content/repositories/snapshots/" + } } dependencies { - classpath 'net.minecraftforge.gradle:ForgeGradle:2.2-SNAPSHOT' + classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT' } } -apply plugin: 'net.minecraftforge.gradle.forge' -//Only edit below this line, the above code adds and enables the nessasary things for Forge to be setup. +apply plugin: 'forge' -version = " 2.1.2 - MC 1.10.2" +version = " 1.1.4 - MC 1.7.10" group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = "Electroblob's Wizardry " -srcCompat = JavaVersion.VERSION_1_8 -targetCompat = JavaVersion.VERSION_1_8 - minecraft { - version = "1.10.2-12.18.3.2185" - runDir = "run" - - // the mappings can be changed at any time, and must be in the following format. - // snapshot_YYYYMMDD snapshot are built nightly. - // stable_# stables are built at the discretion of the MCP team. - // Use non-default mappings at your own risk. they may not allways work. - // simply re-run your setup task after changing the mappings to update your workspace. - mappings = "snapshot_20161111" - // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. + version = "1.7.10-10.13.4.1558-1.7.10" + runDir = "eclipse" +} + +task deobfJar(type: Jar) { // Generate deobfuscated + from sourceSets.main.output + classifier = 'deobf' +} +task sourceJar(type: Jar) { // Generate sources + from sourceSets.main.allSource + classifier = 'sources' +} +tasks.build.dependsOn('sourceJar', 'deobfJar') +artifacts { + archives deobfJar + archives sourceJar + archives jar } dependencies { @@ -41,14 +51,6 @@ dependencies { //compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env //compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env - // the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime. - //provided 'com.mod-buildcraft:buildcraft:6.0.8:dev' - - // the deobf configurations: 'deobfCompile' and 'deobfProvided' are the same as the normal compile and provided, - // except that these dependencies get remapped to your current MCP mappings - //deobfCompile 'com.mod-buildcraft:buildcraft:6.0.8:dev' - //deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev' - // for more info... // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html // http://www.gradle.org/docs/current/userguide/dependency_management.html diff --git a/gradle.properties b/gradle.properties deleted file mode 100644 index e9b9fd5a..00000000 --- a/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -# Sets default memory used for gradle commands. Can be overridden by user or command line properties. -# This is required to provide enough memory for the Minecraft decompilation process. -org.gradle.jvmargs=-Xmx3G diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 30d399d8..b7612167 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e18cba72..678d9d8d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Sep 14 12:28:28 PDT 2015 +#Wed Jul 02 15:54:47 CDT 2014 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.0-bin.zip diff --git a/libs/antiqueatlas-1.7.10-4.2.10-deobf.jar b/libs/antiqueatlas-1.7.10-4.2.10-deobf.jar new file mode 100644 index 00000000..f7cf509b Binary files /dev/null and b/libs/antiqueatlas-1.7.10-4.2.10-deobf.jar differ diff --git a/libs/antiqueatlas-1.7.10-4.2.10-sources.jar b/libs/antiqueatlas-1.7.10-4.2.10-sources.jar new file mode 100644 index 00000000..04f3576c Binary files /dev/null and b/libs/antiqueatlas-1.7.10-4.2.10-sources.jar differ diff --git a/src/main/java/electroblob/wizardry/CommonProxy.java b/src/main/java/electroblob/wizardry/CommonProxy.java index 1ae24b85..b7bb373e 100644 --- a/src/main/java/electroblob/wizardry/CommonProxy.java +++ b/src/main/java/electroblob/wizardry/CommonProxy.java @@ -1,54 +1,81 @@ package electroblob.wizardry; -import electroblob.wizardry.item.ItemSpectralBow; +import java.util.HashMap; +import java.util.Map; +import java.util.Vector; + +import cpw.mods.fml.common.FMLCommonHandler; import electroblob.wizardry.packet.PacketCastContinuousSpell; import electroblob.wizardry.packet.PacketCastSpell; import electroblob.wizardry.packet.PacketClairvoyance; import electroblob.wizardry.packet.PacketGlyphData; -import electroblob.wizardry.packet.PacketNPCCastSpell.Message; import electroblob.wizardry.packet.PacketPlayerSync; import electroblob.wizardry.packet.PacketTransportation; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.registry.WizardryItems; import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.WizardryParticleType; -import net.minecraft.block.state.IBlockState; +import net.minecraft.block.Block; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.model.ModelBiped; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; -import net.minecraft.util.SoundEvent; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.translation.I18n; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.StatCollector; +import net.minecraft.util.Vec3; import net.minecraft.world.World; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.config.Property; -/** - * The common proxy for wizardry, serving the usual purpose of dealing with all things that need to be handled +/** The common proxy for wizardry, serving the usual purpose of dealing with all things that need to be handled * differently on the client and the server. A lot of the methods here appear to do absolutely nothing; this is * because they do client-only things which are only handled in the client proxy. - * @see {@link electroblob.wizardry.client.ClientProxy} - * @author Electroblob - * @since Wizardry 1.0 - * */ -@SuppressWarnings("deprecation") + * @see {@link electroblob.wizardry.client.ClientProxy} */ public class CommonProxy { + + /** Used to store IExtendedEntityProperties data temporarily between player death and respawn */ + private static final Map extendedEntityData = new HashMap(); - // SECTION Registry - // =============================================================================================================== - public void registerRenderers(){} - - public void initialiseLayers(){} public void registerKeyBindings(){} public void registerSpellHUD(){} - public net.minecraft.client.model.ModelBiped getWizardArmourModel(){ return null; } - - public void initMixedFontRenderer(){} + public ModelBiped getWizardArmourModel(){ + return null; + } - // SECTION Particles - // =============================================================================================================== + /** + * Adds an entity's custom data to the map for temporary storage + * @param compound An NBT Tag Compound that stores the IExtendedEntityProperties data only + */ + public static void storeEntityData(String name, NBTTagCompound compound){ + extendedEntityData.put(name, compound); + } + + /** + * Removes the compound from the map and returns the NBT tag stored for name or null if none exists + */ + public static NBTTagCompound getEntityData(String name){ + return extendedEntityData.remove(name); + } + + public double getPlayerEyesPos(EntityPlayer player){ + return player.posY + player.eyeHeight; + } + + /** Gets the absolute coordinates of the tip of the wand belonging to the given entity. If this is a client in + * first person view, the coordinates will instead be the entity's position + 1.2. */ + public Vec3 getWandTipPosition(EntityLivingBase entity){ + + // 0.7 forwards, 0.4 to the right, and 1.35 upwards. + + double x = entity.posX - 0.7*Math.sin(Math.toRadians(entity.renderYawOffset)) - 0.4*Math.cos(Math.toRadians(entity.renderYawOffset)); + double y = entity.boundingBox.minY + 1.35; + double z = entity.posZ + 0.7*Math.cos(Math.toRadians(entity.renderYawOffset)) - 0.4*Math.sin(Math.toRadians(entity.renderYawOffset)); + + return Vec3.createVectorHelper(x, y, z); + } /** * Spawns a custom particle of the specified type. @@ -62,13 +89,13 @@ public class CommonProxy { * @param velY Particle y velocity * @param velZ Particle z velocity * @param maxAge Lifetime of the particle in ticks - * @param r Red component of particle colour; will be clamped to between 0 and 1 - * @param g Red component of particle colour; will be clamped to between 0 and 1 - * @param b Red component of particle colour; will be clamped to between 0 and 1 + * @param r Red component of particle colour + * @param g Red component of particle colour + * @param b Red component of particle colour * @param doGravity Whether the particle is affected by gravity (only affects SPARKLE at the moment) * @param radius The radius of the particle's motion, for cirular motion particles */ - public void spawnParticle(WizardryParticleType type, World world, double x, double y, double z, double velX, double velY, double velZ, int maxAge, float r, float g, float b, boolean doGravity, double radius){ + public void spawnParticle(EnumParticleType type, World world, double x, double y, double z, double velX, double velY, double velZ, int maxAge, float r, float g, float b, boolean doGravity, double radius){ // Does nothing since particles are client-side only } @@ -85,11 +112,11 @@ public class CommonProxy { * @param velY Particle y velocity * @param velZ Particle z velocity * @param maxAge Lifetime of the particle in ticks - * @param r Red component of particle colour; will be clamped to between 0 and 1 (unless this is a MAGIC_FIRE particle, in which case this is the scale) - * @param g Red component of particle colour; will be clamped to between 0 and 1 - * @param b Red component of particle colour; will be clamped to between 0 and 1 + * @param r Red component of particle colour (unless this is a MAGIC_FIRE particle, in which case this is the scale) + * @param g Red component of particle colour + * @param b Red component of particle colour */ - public void spawnParticle(WizardryParticleType type, World world, double x, double y, double z, double velX, double velY, double velZ, int maxAge, float r, float g, float b){ + public void spawnParticle(EnumParticleType type, World world, double x, double y, double z, double velX, double velY, double velZ, int maxAge, float r, float g, float b){ this.spawnParticle(type, world, x, y, z, velX, velY, velZ, maxAge, r, g, b, false, 0); } @@ -107,16 +134,41 @@ public class CommonProxy { * @param velZ Particle z velocity * @param maxAge Lifetime of the particle in ticks */ - public void spawnParticle(WizardryParticleType type, World world, double x, double y, double z, double velX, double velY, double velZ, int maxAge){ + public void spawnParticle(EnumParticleType type, World world, double x, double y, double z, double velX, double velY, double velZ, int maxAge){ this.spawnParticle(type, world, x, y, z, velX, velY, velZ, maxAge, 1, 1, 1, false, 0); } - public void spawnTornadoParticle(World world, double x, double y, double z, double velX, double velZ, double radius, int maxAge, IBlockState block, BlockPos pos){} + public void spawnDigParticle(World world, double x, double y, double z, double velX, double velY, double velZ, Block block){} - // SECTION Items - // =============================================================================================================== - - public net.minecraft.client.gui.FontRenderer getFontRenderer(ItemStack stack) { + public void spawnTornadoParticle(World world, double x, double y, double z, double velX, double velZ, double radius, int maxAge, Block block, int metadata){} + + /** Plays a sound which moves with the given entity. + * + * @param entity The source of the sound + * @param soundName String resource path of the sound + * @param volume Volume relative to 1 + * @param pitch Pitch relative to 1 + * @param repeat Whether to repeat the sound for as long as the entity is alive (or until stopped manually) + */ + public void playMovingSound(Entity entity, String soundName, float volume, float pitch, boolean repeat){} + + public void handleCastSpellPacket(PacketCastSpell.Message message){} + + public double getWandDisplayDamage(ItemStack stack){ + return 1.0d; + } + + public int getConjuredItemDisplayDamage(ItemStack stack){ + return 0; + } + + public void registerEventHandlers(){ + MinecraftForge.EVENT_BUS.register(new WizardryEventHandler()); + } + + public void handleTransportationPacket(PacketTransportation.Message message){} + + public FontRenderer getFontRenderer(ItemStack stack) { return null; } @@ -128,49 +180,24 @@ public class CommonProxy { // I have now learnt that the server side I18n always translates to the default en_US, so I could just return // a hardcoded name in English instead. - Wizardry.logger.info("A mod has called ItemScroll#getItemStackDisplayName from the server side. Using the" - + "deprecated server-side translation methods as a fallback."); + //Wizardry.logger.info("A mod has called ItemScroll#getItemStackDisplayName from the server side. Using the" + // + "deprecated server-side translation methods as a fallback."); // Displays [Empty slot] if spell is continuous. Spell spell = Spell.get(scroll.getItemDamage()); - if(spell.isContinuous) spell = Spells.none; + if(spell.isContinuous) spell = WizardryRegistry.none; - return I18n.translateToLocalFormatted("item.wizardry:wizardry:scroll.name", I18n.translateToLocal("spell." + spell.getUnlocalisedName())).trim(); + return StatCollector.translateToLocalFormatted("item.scroll.name", StatCollector.translateToLocal("spell." + spell.getUnlocalisedName())).trim(); } - public double getConjuredBowDurability(ItemStack stack){ - return ((ItemSpectralBow)WizardryItems.spectral_bow).getDefaultDurabilityForDisplay(stack); - } - - // SECTION Packet Handlers - // =============================================================================================================== - public void handlePlayerSyncPacket(PacketPlayerSync.Message message){} + public void handleGlyphDataPacket(PacketGlyphData.Message message){} - public void handleCastSpellPacket(PacketCastSpell.Message message){} + public void handleCastContinuousSpellPacket(PacketCastContinuousSpell.Message message){} - public void handleNPCCastSpellPacket(Message message){} - public void handleTransportationPacket(PacketTransportation.Message message){} - public void handleClairvoyancePacket(PacketClairvoyance.Message message){} - - // SECTION Misc - // =============================================================================================================== public void setToNumberSliderEntry(Property property){} - //public void setToEntityNameEntry(Property property){} - - /** Plays a sound which moves with the given entity. - * - * @param entity The source of the sound - * @param sound The SoundEvent to play - * @param volume Volume relative to 1 - * @param pitch Pitch relative to 1 - * @param repeat Whether to repeat the sound for as long as the entity is alive (or until stopped manually) - */ - public void playMovingSound(Entity entity, SoundEvent sound, float volume, float pitch, boolean repeat){} - - /** Gets the client side world using Minecraft.getMinecraft().theWorld. Only to be called client side! - * Returns null on the server side. */ - public World getTheWorld(){ return null; } + + public void handleClairvoyancePacket(PacketClairvoyance.Message message){} } \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/EnumElement.java b/src/main/java/electroblob/wizardry/EnumElement.java new file mode 100644 index 00000000..d440fd96 --- /dev/null +++ b/src/main/java/electroblob/wizardry/EnumElement.java @@ -0,0 +1,39 @@ +package electroblob.wizardry; + +import net.minecraft.util.StatCollector; + +public enum EnumElement { + + MAGIC("\u00A77", "simple"), + FIRE("\u00A74", "fire"), + ICE("\u00A7b", "ice"), + LIGHTNING("\u00A73", "lightning"), + NECROMANCY("\u00A75", "necromancy"), + EARTH("\u00A72", "earth"), + SORCERY("\u00A7a", "sorcery"), + HEALING("\u00A7e", "healing"); + + /** Display colour for this element */ + public final String colour; + /** Unlocalised name for this element */ + public final String unlocalisedName; + + private EnumElement(String colour, String name){ + this.colour = colour; + this.unlocalisedName = name; + } + + public EnumElement get(int id){ + return this.values()[id]; + } + + /** Returns the translated display name of this element, without formatting. */ + public String getDisplayName() { + return StatCollector.translateToLocal("element." + unlocalisedName); + } + + /** Returns the translated display name for wizards of this element, shown in the trading GUI */ + public String getWizardName() { + return StatCollector.translateToLocal("element." + unlocalisedName + ".wizard"); + } +} diff --git a/src/main/java/electroblob/wizardry/EnumParticleType.java b/src/main/java/electroblob/wizardry/EnumParticleType.java new file mode 100644 index 00000000..52d990f6 --- /dev/null +++ b/src/main/java/electroblob/wizardry/EnumParticleType.java @@ -0,0 +1,16 @@ +package electroblob.wizardry; + +public enum EnumParticleType { + BLIZZARD, + BRIGHT_DUST, + DARK_MAGIC, + DUST, + ICE, + LEAF, + MAGIC_BUBBLE, + MAGIC_FIRE, + PATH, + SNOW, + SPARK, + SPARKLE +} diff --git a/src/main/java/electroblob/wizardry/EnumSpellType.java b/src/main/java/electroblob/wizardry/EnumSpellType.java new file mode 100644 index 00000000..30d294c0 --- /dev/null +++ b/src/main/java/electroblob/wizardry/EnumSpellType.java @@ -0,0 +1,21 @@ +package electroblob.wizardry; + +import net.minecraft.util.StatCollector; + +public enum EnumSpellType { + + ATTACK("attack"), + DEFENCE("defence"), + UTILITY("utility"), + MINION("minion"); + + private final String unlocalisedName; + + EnumSpellType(String name){ + this.unlocalisedName = name; + } + + public String getDisplayName() { + return StatCollector.translateToLocal("spelltype." + unlocalisedName); + } +} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/EnumTier.java b/src/main/java/electroblob/wizardry/EnumTier.java new file mode 100644 index 00000000..98c72e81 --- /dev/null +++ b/src/main/java/electroblob/wizardry/EnumTier.java @@ -0,0 +1,38 @@ +package electroblob.wizardry; + +import net.minecraft.util.StatCollector; + +public enum EnumTier { + + BASIC(700, 3, "\u00A7f", "basic"), + APPRENTICE(1000, 4, "\u00A7b", "apprentice"), + ADVANCED(1500, 5, "\u00A71", "advanced"), + MASTER(2500, 6, "\u00A75", "master"); + + /** Maximum mana a wand of this tier can store. */ + public final int maxCharge; + /** Just an ordinal. Shouldn't really be needed but no point changing it now. */ + public final int level; + /** The maximum number of upgrades that can be applied to a wand of this tier. */ + public final int upgradeLimit; + /** The colour of text associated with this tier */ + public final String colour; + + private final String unlocalisedName; + + private EnumTier(int maxCharge, int upgradeLimit, String colour, String name){ + this.maxCharge = maxCharge; + this.level = ordinal(); + this.upgradeLimit = upgradeLimit; + this.colour = colour; + this.unlocalisedName = name; + } + + public String getDisplayName() { + return StatCollector.translateToLocal("tier." + unlocalisedName); + } + + public String getDisplayNameWithFormatting() { + return this.colour + StatCollector.translateToLocal("tier." + unlocalisedName); + } +} diff --git a/src/main/java/electroblob/wizardry/ExtendedPlayer.java b/src/main/java/electroblob/wizardry/ExtendedPlayer.java new file mode 100644 index 00000000..9942fece --- /dev/null +++ b/src/main/java/electroblob/wizardry/ExtendedPlayer.java @@ -0,0 +1,485 @@ +package electroblob.wizardry; + +import java.lang.ref.WeakReference; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Random; +import java.util.UUID; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import electroblob.wizardry.MagicDamage.DamageType; +import electroblob.wizardry.entity.EntityShield; +import electroblob.wizardry.entity.living.EntitySummonedCreature; +import electroblob.wizardry.packet.PacketCastContinuousSpell; +import electroblob.wizardry.packet.PacketPlayerSync; +import electroblob.wizardry.packet.PacketTransportation; +import electroblob.wizardry.packet.WizardryPacketHandler; +import electroblob.wizardry.spell.None; +import electroblob.wizardry.spell.Spell; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagString; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.world.World; +import net.minecraftforge.common.IExtendedEntityProperties; +import net.minecraftforge.common.util.Constants.NBT; + +/** IExtendedEntityProperties for players. Everything player-data-related that is needed by wizardry is handled here, + * including the ADS, soulbinding, conjured items, summoned wolves and horses, transportation and clairvoyance. */ +public class ExtendedPlayer implements IExtendedEntityProperties { + + public final static String name = "WizardryExtendedPlayer"; + + private final EntityPlayer player; + + public int damageToApply; + + // These were originally done using the item damage directly, but this caused the annoying re-equip animation + // to keep happening so they were moved to here instead. + public int conjuredSwordDuration; + public int conjuredPickaxeDuration; + public int conjuredBowDuration; + public int conjuredArmourDuration; + public int flamingAxeDuration; + public int frostAxeDuration; + public int magicWeaponDuration; + public int flamingWeaponDuration; + public int freezingWeaponDuration; + public boolean hasSpiritWolf; + public boolean hasSpiritHorse; + + /** Whether this player is currently casting a continuous spell via commands. Not saved over world reload + * and reset on player death. */ + private Spell currentlyCasting; + /** The time for which this player has been casting a continuous spell via commands. Increments by 1 each tick. + * Not saved over world reload and reset on player death. */ + private int castingTick; + /** The damage multiplier for the current continuous spell cast via commands. Not saved over world reload and + * reset on player death. */ + private float spellDamageMultiplier; + /** The range multiplier for the current continuous spell cast via commands. Not saved over world reload and + * reset on player death. */ + private float spellRangeMultiplier; + /** The duration multiplier for the current continuous spell cast via commands. Not saved over world reload and + * reset on player death. */ + private float spellDurationMultiplier; + /** The blast multiplier for the current continuous spell cast via commands. Not saved over world reload and + * reset on player death. */ + private float spellBlastMultiplier; + + /** Coordinate for the saved transportation stone location. Will be -1 if no location is saved. */ + public int transportX, transportY, transportZ; + /** Dimension id which the saved stone circle is in. */ + public int transportDimension; + /** Time left until the player teleports under the effect of transportation */ + public int tpTimer; + + /** Coordinate for the saved clairvoyance location. Will be -1 if no location is saved. */ + public int clairvoyanceX, clairvoyanceY, clairvoyanceZ; + /** Dimension id which the saved clairvoyance point is in. */ + public int clairvoyanceDimension; + + public EntityShield shield; + + public WeakReference selectedMinion; + + public HashSet spellsDiscovered; + + private HashSet allies; + /** List of usernames of this player's allies. May not be accurate 100% of the time. This is here so that a player + * can view the usernames of their allies even when those allies are not online. + * Do not use this for any other purpose than displaying the names! */ + public HashSet allyNames; + + private HashSet soulboundCreatures; + + public ExtendedPlayer(EntityPlayer player){ + this.player = player; + this.damageToApply = 0; + this.conjuredSwordDuration = 0; + this.conjuredPickaxeDuration = 0; + this.conjuredBowDuration = 0; + this.conjuredArmourDuration = 0; + this.flamingAxeDuration = 0; + this.frostAxeDuration = 0; + this.magicWeaponDuration = 0; + this.flamingWeaponDuration = 0; + this.freezingWeaponDuration = 0; + this.spellsDiscovered = new HashSet(); + // All players can recognise magic missile. This is not done using discoverSpell because that seems to cause + // a crash on load occasionally (probably something to do with achievements being initalised) + this.spellsDiscovered.add(WizardryRegistry.magicMissile); + this.hasSpiritWolf = false; + this.hasSpiritHorse = false; + this.currentlyCasting = WizardryRegistry.none; + this.spellDamageMultiplier = 1; + this.spellRangeMultiplier = 1; + this.spellDurationMultiplier = 1; + this.spellBlastMultiplier = 1; + this.castingTick = 0; + this.transportX = -1; + this.transportY = -1; + this.transportZ = -1; + this.transportDimension = 0; + this.clairvoyanceX = -1; + this.clairvoyanceY = -1; + this.clairvoyanceZ = -1; + this.clairvoyanceDimension = 0; + this.tpTimer = 0; + this.allies = new HashSet(); + this.allyNames = new HashSet(); + this.soulboundCreatures = new HashSet(); + } + + public boolean hasSpellBeenDiscovered(Spell spell){ + return spellsDiscovered.contains(spell) || spell instanceof None; + } + + /** + * Adds the spell to the list of discovered spells for this player. Automatically takes into account + * whether the spell has been discovered. Use this method rather than adding directly to the list + * because it handles the mage of all trades achievement. + * @param spell + */ + public void discoverSpell(Spell spell){ + + if(spellsDiscovered == null){ + spellsDiscovered = new HashSet(); + } + + if(!(spell instanceof None)){ + spellsDiscovered.add(spell); + } + + if(spellsDiscovered.containsAll(Spell.getSpells(Spell.enabledSpells))){ + this.player.triggerAchievement(Wizardry.allSpells); + } + + for(EnumElement element : EnumElement.values()){ + if(element != EnumElement.MAGIC && spellsDiscovered.containsAll(Spell.getSpells(new Spell.TierElementFilter(null, element)))){ + this.player.triggerAchievement(Wizardry.elementMaster); + } + } + } + + /** Sets the player's saved transportation stone location. */ + public void setStoneLocation(int x, int y, int z, int dimensionID){ + this.transportX = x; + this.transportY = y; + this.transportZ = z; + this.transportDimension = dimensionID; + } + + /** Sets the player's saved clairvoyance location. */ + public void setClairvoyancePoint(int x, int y, int z, int dimensionID){ + this.clairvoyanceX = x; + this.clairvoyanceY = y; + this.clairvoyanceZ = z; + this.clairvoyanceDimension = dimensionID; + } + + /** Adds the given player to the list of allies belonging to the associated player, or removes the player if + * they are already in the list of allies. Returns true if the player was added, false if they were removed. */ + public boolean toggleAlly(EntityPlayer player){ + if(this.isPlayerAlly(player)){ + this.allies.remove(player.getUniqueID()); + // The remove method uses .equals() rather than == so this will work fine. + this.allyNames.remove(player.getCommandSenderName()); + return false; + }else{ + this.allies.add(player.getUniqueID()); + this.allyNames.add(player.getCommandSenderName()); + return true; + } + } + + /** Returns whether the given player is in this player's list of allies, or is on the same team as this player. */ + public boolean isPlayerAlly(EntityPlayer player){ + return this.allies.contains(player.getUniqueID()) || this.player.isOnSameTeam(player); + } + + /** Adds the given entity to this player's list of soulbound creatures, and returns whether it succeeded. */ + public boolean soulbind(EntityLivingBase target){ + return this.soulboundCreatures.add(target.getUniqueID()); + } + + /** Returns whether the given entity has been soulbound to this player. */ + public boolean isCreatureSoulbound(EntityPlayer target){ + return this.soulboundCreatures.contains(target.getUniqueID()); + } + + /** Damages all creatures soulbound to this player by the given amount, and removes from the list any that no + * longer exist. */ + public void damageAllSoulboundCreatures(float damage){ + + for(Iterator iterator = this.soulboundCreatures.iterator(); iterator.hasNext();){ + + Entity entity = WizardryUtilities.getEntityByUUID(this.player.worldObj, iterator.next()); + + if(entity == null) iterator.remove(); + + if(entity instanceof EntityLivingBase){ + if(entity.attackEntityFrom(MagicDamage.causeDirectMagicDamage(this.player, DamageType.MAGIC), damage)){ + // Sound only plays if the damage succeeds + player.worldObj.playSoundAtEntity(entity, "mob.wither.hurt", 1.0F, player.worldObj.rand.nextFloat() * 0.2F + 1.0F); + } + } + } + } + + /** Starts casting the given spell with the given modifiers. */ + public void startCastingContinuousSpell(Spell spell, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ + this.currentlyCasting = spell; + this.spellDamageMultiplier = damageMultiplier; + this.spellRangeMultiplier = rangeMultiplier; + this.spellDurationMultiplier = durationMultiplier; + this.spellBlastMultiplier = blastMultiplier; + + if(!this.player.worldObj.isRemote){ + PacketCastContinuousSpell.Message message = new PacketCastContinuousSpell.Message(this.player.getEntityId(), spell.id(), damageMultiplier, rangeMultiplier, blastMultiplier); + WizardryPacketHandler.net.sendToDimension(message, this.player.worldObj.provider.dimensionId); + } + } + + /** Stops casting the current spell. */ + public void stopCastingContinuousSpell(){ + this.currentlyCasting = WizardryRegistry.none; + this.castingTick = 0; + this.spellDamageMultiplier = 1; + this.spellRangeMultiplier = 1; + this.spellDurationMultiplier = 1; + this.spellBlastMultiplier = 1; + + if(!this.player.worldObj.isRemote){ + PacketCastContinuousSpell.Message message = new PacketCastContinuousSpell.Message(this.player.getEntityId(), WizardryRegistry.none.id(), 1, 1, 1); + WizardryPacketHandler.net.sendToDimension(message, this.player.worldObj.provider.dimensionId); + } + } + + /** Returns whether this player is currently casting a continuous spell via commands. */ + public boolean isCasting(){ + return this.currentlyCasting != null && this.currentlyCasting != WizardryRegistry.none; + } + + /** Returns the continuous spell this player is currently casting via commands, or the 'none' spell if they aren't + * casting anything. */ + public Spell currentlyCasting(){ + return currentlyCasting; + } + + /** Called from the event handler each time the associated player is updated. */ + public void update(EntityPlayer entityplayer){ + + if(this.selectedMinion != null && this.selectedMinion.get() == null) this.selectedMinion = null; + + Random random = entityplayer.worldObj.rand; + + // Annoyingly, it seems that the armour inventory is dealt with completely separately. + if(entityplayer.inventory.hasItem(Wizardry.spectralHelmet) + || entityplayer.inventory.hasItem(Wizardry.spectralChestplate) + || entityplayer.inventory.hasItem(Wizardry.spectralLeggings) + || entityplayer.inventory.hasItem(Wizardry.spectralBoots) + || (entityplayer.inventory.armorInventory[3] != null && entityplayer.inventory.armorInventory[3].getItem() == Wizardry.spectralHelmet) + || (entityplayer.inventory.armorInventory[2] != null && entityplayer.inventory.armorInventory[2].getItem() == Wizardry.spectralChestplate) + || (entityplayer.inventory.armorInventory[1] != null && entityplayer.inventory.armorInventory[1].getItem() == Wizardry.spectralLeggings) + || (entityplayer.inventory.armorInventory[0] != null && entityplayer.inventory.armorInventory[0].getItem() == Wizardry.spectralBoots)){ + + this.conjuredArmourDuration++; + + }else{ + this.conjuredArmourDuration = 0; + } + + if(!entityplayer.worldObj.isRemote){ + if(tpTimer == 1){ + entityplayer.setPositionAndUpdate(this.transportX + 0.5, this.transportY, this.transportZ + 0.5); + entityplayer.worldObj.playSoundAtEntity(entityplayer, "portal.travel", 1.0f, 1.0f); + entityplayer.addPotionEffect(new PotionEffect(Potion.blindness.id, 50, 0)); + IMessage msg = new PacketTransportation.Message(entityplayer.getEntityId()); + WizardryPacketHandler.net.sendToDimension(msg, entityplayer.worldObj.provider.dimensionId); + } + + if(tpTimer > 0){ + tpTimer--; + } + } + + if(this.currentlyCasting != null && this.currentlyCasting.isContinuous){ + this.currentlyCasting.cast(player.worldObj, player, castingTick++, spellDamageMultiplier, spellRangeMultiplier, spellDurationMultiplier, spellBlastMultiplier); + }else{ + this.castingTick = 0; + } + } + + /** Called from the event handler each time the associated player dies. Used to reset any variables that shouldn't + * persist over player death. */ + public void onPlayerDeath(){ + this.conjuredSwordDuration = 0; + this.conjuredPickaxeDuration = 0; + this.conjuredBowDuration = 0; + this.conjuredArmourDuration = 0; + this.flamingAxeDuration = 0; + this.frostAxeDuration = 0; + this.magicWeaponDuration = 0; + this.flamingWeaponDuration = 0; + this.freezingWeaponDuration = 0; + // Death cancels transportation spell. + this.tpTimer = 0; + this.soulboundCreatures = new HashSet(); + this.currentlyCasting = WizardryRegistry.none; + this.castingTick = 0; + this.spellDamageMultiplier = 1; + this.spellRangeMultiplier = 1; + this.spellDurationMultiplier = 1; + this.spellBlastMultiplier = 1; + } + + /** + * Returns the string key to be used when saving and loading the extended player data on respawn. + */ + public static String getSaveKey(EntityPlayer player) { + return player.getUniqueID().toString() + ":" + name; + } + + /** + * Used to register these extended properties for the player during EntityConstructing event + * This method is for convenience only; it will make your code look nicer + */ + public static final void register(EntityPlayer player){ + player.registerExtendedProperties(ExtendedPlayer.name, new ExtendedPlayer(player)); + } + + /** + * Returns the ExtendedPlayer properties for the specified player. + */ + public static final ExtendedPlayer get(EntityPlayer player){ + return (ExtendedPlayer) player.getExtendedProperties(name); + } + + /** Sends a packet to this player's client to synchronise necessary information. Only called server side. */ + public void sync(){ + if(this.player instanceof EntityPlayerMP){ + int id = -1; + if(this.selectedMinion != null && this.selectedMinion.get() != null) id = this.selectedMinion.get().getEntityId(); + IMessage msg = new PacketPlayerSync.Message(this.spellsDiscovered, id); + WizardryPacketHandler.net.sendTo(msg, (EntityPlayerMP)this.player); + } + } + + @Override + public void saveNBTData(NBTTagCompound compound) { + + // NBTTagCompound is for Maps, NBTTagList is for Lists/Sets + + NBTTagCompound properties = new NBTTagCompound(); + properties.setInteger("conjuredSwordDuration", this.conjuredSwordDuration); + properties.setInteger("conjuredPickaxeDuration", this.conjuredPickaxeDuration); + properties.setInteger("conjuredBowDuration", this.conjuredBowDuration); + properties.setInteger("conjuredArmourDuration", this.conjuredArmourDuration); + properties.setInteger("flamingAxeDuration", this.flamingAxeDuration); + properties.setInteger("frostAxeDuration", this.frostAxeDuration); + properties.setInteger("magicWeaponDuration", this.magicWeaponDuration); + properties.setInteger("flamingWeaponDuration", this.flamingWeaponDuration); + properties.setInteger("freezingWeaponDuration", this.freezingWeaponDuration); + properties.setBoolean("hasSpiritWolf", this.hasSpiritWolf); + properties.setBoolean("hasSpiritHorse", this.hasSpiritHorse); + properties.setInteger("x", this.transportX); + properties.setInteger("y", this.transportY); + properties.setInteger("z", this.transportZ); + properties.setInteger("dimension", this.transportDimension); + properties.setInteger("x2", this.clairvoyanceX); + properties.setInteger("y2", this.clairvoyanceY); + properties.setInteger("z2", this.clairvoyanceZ); + properties.setInteger("dimension2", this.clairvoyanceDimension); + properties.setInteger("tpTimer", this.tpTimer); + + NBTTagList tagList = new NBTTagList(); + for(UUID id : this.allies){ + tagList.appendTag(new NBTTagString(id.toString())); + } + properties.setTag("allies", tagList); + + NBTTagList tagList2 = new NBTTagList(); + for(String name : this.allyNames){ + tagList2.appendTag(new NBTTagString(name)); + } + properties.setTag("allyNames", tagList2); + + NBTTagList tagList3 = new NBTTagList(); + for(UUID id : this.soulboundCreatures){ + tagList3.appendTag(new NBTTagString(id.toString())); + } + properties.setTag("soulboundCreatures", tagList3); + + int[] spells = new int[this.spellsDiscovered.size()]; + int i=0; + for(Spell spell : this.spellsDiscovered){ + spells[i] = spell.id(); + i++; + } + properties.setIntArray("discoveredSpells", spells); + + compound.setTag(name, properties); + } + + @Override + public void loadNBTData(NBTTagCompound compound) { + NBTTagCompound properties = (NBTTagCompound) compound.getTag(name); + if(properties != null){ + this.conjuredSwordDuration = properties.getInteger("conjuredSwordDuration"); + this.conjuredPickaxeDuration = properties.getInteger("conjuredPickaxeDuration"); + this.conjuredBowDuration = properties.getInteger("conjuredBowDuration"); + this.conjuredArmourDuration = properties.getInteger("conjuredArmourDuration"); + this.flamingAxeDuration = properties.getInteger("flamingAxeDuration"); + this.frostAxeDuration = properties.getInteger("frostAxeDuration"); + this.magicWeaponDuration = properties.getInteger("magicWeaponDuration"); + this.flamingWeaponDuration = properties.getInteger("flamingWeaponDuration"); + this.freezingWeaponDuration = properties.getInteger("freezingWeaponDuration"); + this.hasSpiritWolf = properties.getBoolean("hasSpiritWolf"); + this.hasSpiritHorse = properties.getBoolean("hasSpiritHorse"); + this.transportX = properties.getInteger("x"); + this.transportY = properties.getInteger("y"); + this.transportZ = properties.getInteger("z"); + this.transportDimension = properties.getInteger("dimension"); + this.clairvoyanceX = properties.getInteger("x2"); + this.clairvoyanceY = properties.getInteger("y2"); + this.clairvoyanceZ = properties.getInteger("z2"); + this.clairvoyanceDimension = properties.getInteger("dimension2"); + this.tpTimer = properties.getInteger("tpTimer"); + + this.allies = new HashSet(); + NBTTagList tagList = properties.getTagList("allies", NBT.TAG_STRING); + for(int i=0; i(); + NBTTagList tagList2 = properties.getTagList("allyNames", NBT.TAG_STRING); + for(int i=0; i(); + NBTTagList tagList3 = properties.getTagList("soulboundCreatures", NBT.TAG_STRING); + for(int i=0; i(); + for(int id : properties.getIntArray("discoveredSpells")){ + spellsDiscovered.add(Spell.get(id)); + } + } + } + + @Override + public void init(Entity entity, World world) { + // For reference, apparently there is a strange error that causes 'this' to be null here. + } + +} diff --git a/src/main/java/electroblob/wizardry/IElementalDamage.java b/src/main/java/electroblob/wizardry/IElementalDamage.java new file mode 100644 index 00000000..62d45c43 --- /dev/null +++ b/src/main/java/electroblob/wizardry/IElementalDamage.java @@ -0,0 +1,16 @@ +package electroblob.wizardry; + +import electroblob.wizardry.MagicDamage.DamageType; +import net.minecraft.entity.Entity; +import scala.actors.threadpool.Arrays; + +/** This interface allows {@link MagicDamage} and {@link IndirectMagicDamage} to both be treated as instances of a + * single type so that the damage type field can be accessed, rather than having to deal with each of them separately, + * which would be inefficient and cumbersome (the latter of those classes cannot extend the former because they both + * need to extend different subclasses of {@link net.minecraft.util.DamageSource DamageSource}). + * @since Wizardry 1.1 */ +public interface IElementalDamage { + + DamageType getType(); + +} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/util/IndirectMagicDamage.java b/src/main/java/electroblob/wizardry/IndirectMagicDamage.java similarity index 58% rename from src/main/java/electroblob/wizardry/util/IndirectMagicDamage.java rename to src/main/java/electroblob/wizardry/IndirectMagicDamage.java index f116f3e1..227c948b 100644 --- a/src/main/java/electroblob/wizardry/util/IndirectMagicDamage.java +++ b/src/main/java/electroblob/wizardry/IndirectMagicDamage.java @@ -1,18 +1,16 @@ -package electroblob.wizardry.util; +package electroblob.wizardry; -import electroblob.wizardry.util.MagicDamage.DamageType; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.Entity; import net.minecraft.util.EntityDamageSourceIndirect; public class IndirectMagicDamage extends EntityDamageSourceIndirect implements IElementalDamage { private final DamageType type; - private final boolean isRetaliatory; - public IndirectMagicDamage(String name, Entity magic, Entity caster, DamageType type, boolean isRetaliatory){ + public IndirectMagicDamage(String name, Entity magic, Entity caster, DamageType type) { super(name, magic, caster); this.type = type; - this.isRetaliatory = isRetaliatory; } @Override @@ -20,9 +18,4 @@ public class IndirectMagicDamage extends EntityDamageSourceIndirect implements I return type; } - @Override - public boolean isRetaliatory(){ - return isRetaliatory; - } - } diff --git a/src/main/java/electroblob/wizardry/util/MagicDamage.java b/src/main/java/electroblob/wizardry/MagicDamage.java similarity index 69% rename from src/main/java/electroblob/wizardry/util/MagicDamage.java rename to src/main/java/electroblob/wizardry/MagicDamage.java index ce2a5c2f..6f253ad5 100644 --- a/src/main/java/electroblob/wizardry/util/MagicDamage.java +++ b/src/main/java/electroblob/wizardry/MagicDamage.java @@ -1,4 +1,4 @@ -package electroblob.wizardry.util; +package electroblob.wizardry; import java.util.Arrays; import java.util.HashMap; @@ -16,6 +16,7 @@ import electroblob.wizardry.entity.living.EntitySpiderMinion; import electroblob.wizardry.entity.living.EntityStormElemental; import electroblob.wizardry.entity.living.EntityZombieMinion; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.boss.EntityDragon; import net.minecraft.entity.boss.EntityWither; import net.minecraft.entity.monster.EntityBlaze; @@ -27,7 +28,6 @@ import net.minecraft.entity.monster.EntitySkeleton; import net.minecraft.entity.monster.EntitySnowman; import net.minecraft.entity.monster.EntitySpider; import net.minecraft.entity.monster.EntityZombie; -import net.minecraft.entity.monster.SkeletonType; import net.minecraft.util.DamageSource; import net.minecraft.util.EntityDamageSource; @@ -38,11 +38,11 @@ import net.minecraft.util.EntityDamageSource; // The vanilla approach to damage types is inconsistent, to say the least. Poison is simply 'magic', and relies on // EntityLivingBase.isPotionApplicable to determine whether an entity is affected or not. Wither, on the other hand, is -// its own damage type, but again relies on the potion to determine what is immune (which in vanilla is nothing). Fire +// its own damage type, but again relies on the potion to determine what is immune (which in this case is nothing). Fire // has a proper implementation of course, with both block-based and projectile-based types, and any other damagesource // can also be designated as fire damage with setFireDamage(). Likewise, projectile and explosion damage can also be -// applied to any damagesource, but these aren't considered types in their own right; rather, they seem to be damage -// type 'attributes'. This is my attempt to collect all of these into a reasonably coherent system. +// applied to any damagesource, but these aren't condsidered types in their own right; rather, they seem to be damage +// type 'attributes'. /** As of wizardry 1.1, this class has replaced the damagesource-related methods in WizardryUtilities, allowing a * {@link DamageType} to be specified with the damage. The main reason for this is so that damage sources can fit with the @@ -57,19 +57,19 @@ import net.minecraft.util.EntityDamageSource; * * @see IndirectMagicDamage * @see IElementalDamage - * @since Wizardry 1.1 - * @author Electroblob */ + * @since Wizardry 1.1 */ public class MagicDamage extends EntityDamageSource implements IElementalDamage { - /** The name of the damagesource for direct magic damage from the wizardry mod. */ + /** The name of the damagesource for direct magic damage from the wizardry mod. Defined here so that any + * references get changed automatically. */ public static final String DIRECT_MAGIC_DAMAGE = "wizardryMagic"; - /** The name of the damagesource for indirect magic damage from the wizardry mod. */ + /** The name of the damagesource for indirect magic damage from the wizardry mod. Defined here so that any + * references get changed automatically. */ public static final String INDIRECT_MAGIC_DAMAGE = "indirectWizardryMagic"; // Technically, I don't need to specify that the classes in this map must extend entity, but it's good practice to. private static final Map, DamageType[]> immunityMapping = new HashMap, DamageType[]>(); private final DamageType type; - private final boolean isRetaliatory; /** A simple set of constants for the types of damage. The names are deliberately different to those in EnumElement * to avoid confusion. All types are classified as magic damage in the vanilla system, so witches are resistant to them. */ @@ -87,11 +87,11 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage WITHER, /** Poison damage from the wizardry mod. Spiders, cave spiders and undead mobs are immune. */ POISON, - /** [NYI] Force damage from the wizardry mod. Insubstantial creatures (ghast, shadow wraith, etc.) are immune. */ + /** Force damage from the wizardry mod. Insubstantial creatures (ghast, shadow wraith, etc.) are immune. */ FORCE, /** Blast damage from the wizardry mod. Affected by the blast protection enchantment. */ BLAST, - /** [NYI] Radiant damage from the wizardry mod. */ + /** Radiant damage from the wizardry mod. */ RADIANT; } @@ -122,10 +122,9 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage setEntityImmunities(EntitySkeletonMinion.class, DamageType.POISON); } - public MagicDamage(String name, Entity caster, DamageType type, boolean isRetaliatory){ + public MagicDamage(String name, Entity caster, DamageType type) { super(name, caster); this.type = type; - this.isRetaliatory = isRetaliatory; this.setMagicDamage(); if(type == DamageType.FIRE) this.setFireDamage(); if(type == DamageType.BLAST) this.setExplosion(); @@ -141,9 +140,9 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage // Because Mojang, in their infinite wisdom, did not make wither skeletons their own separate class (despite the // fact that cave spiders are), I have to test for this manually. Realistically, no mod author would be stupid // enough to put two entities in one class, so this should be the only time I ever have to do this. - if(type == DamageType.WITHER && entity instanceof EntitySkeleton - // Don't need to check EntitySkeletonMinion separately any more because it now extends EntitySkeleton. - && ((EntitySkeleton)entity).getSkeletonType() == SkeletonType.WITHER){ + if(type == DamageType.WITHER && ( + (entity instanceof EntitySkeleton && ((EntitySkeleton)entity).getSkeletonType() == 1) + || (entity instanceof EntitySkeletonMinion && ((EntitySkeletonMinion)entity).getSkeletonType() == 1))){ return true; } @@ -154,12 +153,13 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage return immunities != null && Arrays.asList(immunities).contains(type); } + // I found a use for varargs! /** Registers the given type of entity as immune to all of the passed in damage types. */ public static void setEntityImmunities(Class entityType, DamageType... immunities){ immunityMapping.put(entityType, immunities); } - /** Adds the passed in damage type to the list of damage types to which the given entity is immune. */ + /** Registers the given type of entity as immune to all of the passed in damage types. */ public static void addEntityImmunity(Class entityType, DamageType immunity){ List immunities = Arrays.asList(immunityMapping.get(entityType)); immunities.add(immunity); @@ -172,61 +172,19 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage * types to allow things to distinguish between magic and regular melee/swords. Unlike DamageSource.magic, it does * not bypass armour and has a player as the source (rather than nothing). It is still classed as magic damage (for * the record, all this does in vanilla is make witches 85% resistant to it - but that seems kinda right anyway). - * isRetaliatory defaults to false. *

* Now that this is its own class, this static method is largely redundant, but it's not worth refactoring the entire * mod just to get rid of this method and use the constructor instead. * @param caster The player or other living entity causing the damage * @param type The type that this damage belongs to; used for resistances and wand perks. Use - * {@link DamageType#MAGIC} for regular, non-elemental magic damage (sometimes you might not want an element + * {@link EnumElement#MAGIC} for regular, non-elemental magic damage (sometimes you might not want an element * even though the spell has one - for example, not all necromancy spells are 'withery', so some of them might * reasonably affect creatures that are ususally immune to wither effects). * @return A damagesource object of type EntityDamageSource */ - public static DamageSource causeDirectMagicDamage(Entity caster, DamageType type){ - return causeDirectMagicDamage(caster, type, false); - } - - /** - * Returns a DamageSource called "wizardryMagic" with the given entity as the caster. Use in preference to vanilla - * types to allow things to distinguish between magic and regular melee/swords. Unlike DamageSource.magic, it does - * not bypass armour and has a player as the source (rather than nothing). It is still classed as magic damage (for - * the record, all this does in vanilla is make witches 85% resistant to it - but that seems kinda right anyway). - *

- * Now that this is its own class, this static method is largely redundant, but it's not worth refactoring the entire - * mod just to get rid of this method and use the constructor instead. - * @param caster The player or other living entity causing the damage - * @param type The type that this damage belongs to; used for resistances and wand perks. Use - * {@link DamageType#MAGIC} for regular, non-elemental magic damage (sometimes you might not want an element - * even though the spell has one - for example, not all necromancy spells are 'withery', so some of them might - * reasonably affect creatures that are ususally immune to wither effects). - * @param isRetaliatory whether this damage source came from a retaliatory attack; prevents infinite loops - * occurring when two entities damage each other with retaliatory effects. - * @return A damagesource object of type EntityDamageSource - */ - public static DamageSource causeDirectMagicDamage(Entity caster, DamageType type, boolean isRetaliatory){ - return new MagicDamage(DIRECT_MAGIC_DAMAGE, caster, type, isRetaliatory); - } - - /** - * Returns a DamageSource called "indirectWizardryMagic" with the player as the caster. Use in preference to vanilla - * types to allow things to distinguish between magic and regular arrows/throwables. Unlike - * DamageSource.causeIndirectMagicDamage, it does not bypass armour. It is still classed as magic damage (for the - * record, all this does in vanilla is make witches 85% resistant to it - but that seems kinda right anyway). - * isRetaliatory defaults to false. - *

- * Now that this is its own class, this static method is largely redundant, but it's not worth refactoring the entire - * mod just to get rid of this method and use the constructor instead. - * @param magic The entity that actually caused the damage - * @param caster The player or other living entity that cast the spell originally - * @param type The type that this damage belongs to; used for resistances and wand perks. Use - * {@link DamageType#MAGIC} for regular, non-elemental magic damage (sometimes you might not want an element - * even though the spell has one - for example, not all necromancy spells are 'withery', so some of them might - * reasonably affect creatures that are ususally immune to wither effects). - * @return A damagesource object of type EntityDamageSourceIndirect - */ - public static DamageSource causeIndirectMagicDamage(Entity magic, Entity caster, DamageType type){ - return causeIndirectMagicDamage(magic, caster, type, false); + public static DamageSource causeDirectMagicDamage(EntityLivingBase caster, DamageType type) + { + return new MagicDamage(DIRECT_MAGIC_DAMAGE, caster, type); } /** @@ -240,15 +198,14 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage * @param magic The entity that actually caused the damage * @param caster The player or other living entity that cast the spell originally * @param type The type that this damage belongs to; used for resistances and wand perks. Use - * {@link DamageType#MAGIC} for regular, non-elemental magic damage (sometimes you might not want an element + * {@link EnumElement#MAGIC} for regular, non-elemental magic damage (sometimes you might not want an element * even though the spell has one - for example, not all necromancy spells are 'withery', so some of them might * reasonably affect creatures that are ususally immune to wither effects). - * @param isRetaliatory whether this damage source came from a retaliatory attack; prevents infinite loops - * occurring when two entities damage each other with retaliatory effects. * @return A damagesource object of type EntityDamageSourceIndirect */ - public static DamageSource causeIndirectMagicDamage(Entity magic, Entity caster, DamageType type, boolean isRetaliatory){ - return new IndirectMagicDamage(INDIRECT_MAGIC_DAMAGE, magic, caster, type, isRetaliatory); + public static DamageSource causeIndirectEntityMagicDamage(Entity magic, EntityLivingBase caster, DamageType type) + { + return new IndirectMagicDamage(INDIRECT_MAGIC_DAMAGE, magic, caster, type); } @Override @@ -256,9 +213,4 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage return type; } - @Override - public boolean isRetaliatory(){ - return isRetaliatory; - } - } diff --git a/src/main/java/electroblob/wizardry/Settings.java b/src/main/java/electroblob/wizardry/Settings.java deleted file mode 100644 index 8d56dce6..00000000 --- a/src/main/java/electroblob/wizardry/Settings.java +++ /dev/null @@ -1,507 +0,0 @@ -package electroblob.wizardry; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -import electroblob.wizardry.packet.PacketSyncSettings; -import electroblob.wizardry.packet.WizardryPacketHandler; -import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import net.minecraft.entity.EntityList; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.util.text.translation.I18n; -import net.minecraftforge.common.config.ConfigCategory; -import net.minecraftforge.common.config.Configuration; -import net.minecraftforge.common.config.Property; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; - -/** Singleton class which deals with everything related to wizardry's config file. To access individual settings, use - * {@link Wizardry#settings}. Also stores a few string constants for easy access. - *

- * As part of the 1.2 update and code overhaul, the way the config settings work in multiplayer has been tightened up. - * Importantly, there are three different types of config options: - *

- *

  • Server-only settings. These only affect server-side code and hence are not synced. Changing these locally only - * has an effect if the local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world. Examples - * include worldgen, mob drops and commands. - *
  • Synchronised settings. These settings affect both client-side AND server-side code, and are synchronised with - * each client on login via {@link Settings#sync(EntityPlayerMP)}. Changing these locally - * only has an effect if the local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world. - * Examples include discovery mode and crafting recipes. Note that as far as users are concerned, - * there is no difference in behaviour between server-only and synchronised settings. - *
  • Client-only settings. These settings only affect client-side code and hence are not synced. Each client obeys - * its own values for these, and changing them on a dedicated server will have no effect. These are usually only display - * and controls settings.
  • - *

    - * Each of the settings fields in this class is marked with one of the above categories to indicate which it belongs - * to. This in turn dictates which logical side it should be called from: client, server or both. Do not access a - * config setting from the wrong side, because it may cause unexpected or strange behaviour. - * @since Wizardry 1.2 - * @author Electroblob */ -// NOTE: We could convert over to the @Config system IF it is sufficiently complete in this Forge version for my purposes. -// (For one, I know that the LangKey annotation is not applicable to type declarations in 1.10.2, unlike in 1.11.2) -//@Config(modid = Wizardry.MODID) -@SuppressWarnings("deprecation") // Used server I18n deliberately; we want to write the comments in english. -public final class Settings { - - // Category names - /** The unlocalised name of the spells config category. */ - public static final String SPELLS_CATEGORY = "spells"; - /** The unlocalised name of the resistances config category. */ - public static final String RESISTANCES_CATEGORY = "resistances"; - /** The unlocalised name of the client config category. */ - public static final String CLIENT_CATEGORY = "client"; - /** The unlocalised name of the commands config category. */ - public static final String COMMANDS_CATEGORY = "commands"; - /** The unlocalised name of the worldgen config category. */ - public static final String WORLDGEN_CATEGORY = "worldgen"; - /** The unlocalised name of the global config category. */ - public static final String GLOBAL_CATEGORY = "global"; - - /** The wizardry config file. */ - private Configuration config; - - // Server-only settings. These only affect server-side code and hence are not synced. Changing these locally only - // has an effect if the local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world. - - // Worldgen - /** [Server-only] The rarity of wizard towers, used by the world generator. Larger numbers are rarer. */ - public int towerRarity = 8; - /** [Server-only] List of dimension ids in which to generate crystal ore. */ - public int[] oreDimensions = {0}; - /** [Server-only] List of dimension ids in which to generate crystal ore. */ - public int[] flowerDimensions = {0}; - /** [Server-only] List of dimension ids in which to generate crystal ore. */ - public int[] towerDimensions = {0}; - /** [Server-only] Whether or not wizardry loot should generate in dungeon chests. Note that this does not - * affect the generation of loot in wizard towers. */ - public boolean generateLoot = true; - - // Entities' drops, targeting, damage, etc. - /** [Server-only] Chance (out of 200) for mobs to drop spell books. */ - public int spellBookDropChance = 3; - /** [Server-only] Whether or not players can teleport through unbreakable blocks (e.g. bedrock) using the phase step spell. */ - public boolean teleportThroughUnbreakableBlocks = false; - /** [Server-only] Whether to allow players to damage their designated allies using magic. */ - public boolean friendlyFire = true; - /** [Server-only] Whether to allow players to disarm other players using the telekinesis spell. */ - public boolean telekineticDisarmament = true; - /** [Server-only] Whether summoned creatures can revenge attack their caster if their caster attacks them. */ - public boolean minionRevengeTargeting = true; - /** [Server-only] List of names of entities which summoned creatures are allowed to attack, in addition to the defaults. */ - public String[] summonedCreatureTargetsWhitelist = {}; - /** [Server-only] List of names of entities which summoned creatures are specifically not allowed to attack, overriding the defaults and the whitelist. */ - public String[] summonedCreatureTargetsBlacklist = {"creeper"}; - /** [Server-only] Global damage scaling factor for all player magic damage. */ - public double playerDamageScale = 1.0f; - /** [Server-only] Global damage scaling factor for all npc magic damage. */ - public double npcDamageScale = 1.0f; - - // Commands (these don't need synchronising since typing a command always queries the server). - /** [Server-only] The maximum allowed multiplier for the /cast command. This limit is here to stop people from accidentally - * breaking their worlds! */ - public double maxSpellCommandMultiplier = 20d; - /** [Server-only] The name of the /cast command. */ - public String castCommandName = "cast"; - /** [Server-only] The name of the /discoverspell command. */ - public String discoverspellCommandName = "discoverspell"; - /** [Server-only] The name of the /ally command. */ - public String allyCommandName = "ally"; - /** [Server-only] The name of the /allies command. */ - public String alliesCommandName = "allies"; - - // Synchronised settings. These settings affect both client-side AND server-side code. Changing these locally - // only has an effect if the local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world. - - // Recipes (only need syncing for display in the wizard's handbook) - /** [Synchronised] Whether or not firebombs should be craftable. */ - public boolean firebombIsCraftable = true; - /** [Synchronised] Whether or not poison bombs should be craftable. */ - public boolean poisonBombIsCraftable = true; - /** [Synchronised] Whether or not poison bombs should be craftable. */ - public boolean smokeBombIsCraftable = true; - /** [Synchronised] Whether to require a magic crystal in the blank scroll crafting recipe (in case it conflicts with another mod). */ - public boolean useAlternateScrollRecipe = false; - - // Gamemodes - /** [Synchronised] When set to true, spells a player hasn't cast yet will be unreadable until they are cast (on a per-world basis). Has no effect when in creative mode. Spells of - * identification will be unobtainable in survival mode if this is false. */ - public boolean discoveryMode = true; - - // Client-only settings. These settings only affect client-side code and hence are not synced. Each client obeys - // its own values for these, and changing them on a dedicated server will have no effect. - - // Controls - /** [Client-only] Whether the player can switch between spells on a wand by scrolling with the mouse wheel while - * sneaking. */ - public boolean enableShiftScrolling = true; - - // Display - /** [Client-only] Whether to show summoned creatures' names and owners above their heads. */ - public boolean showSummonedCreatureNames = true; - /** [Client-only] The position of the spell HUD. */ - public GuiPosition spellHUDPosition = GuiPosition.BOTTOM_LEFT; - - /** Set of constants for each of the four positions that the spell HUD can be in. */ - public enum GuiPosition { - - BOTTOM_LEFT("Bottom left"), - TOP_LEFT("Top left"), - TOP_RIGHT("Top right"), - BOTTOM_RIGHT("Bottom right"); - - /** Constant array storing the names of each of the constants, in the order they are declared. */ - public static final String[] names; - - static { - names = new String[values().length]; - for(GuiPosition position : values()){ - names[position.ordinal()] = position.name; - } - } - - /** The readable name for this GUI position that will be displayed on the button in the config GUI. */ - public final String name; - - GuiPosition(String name){ - this.name = name; - } - - /** Gets a GUI position from its string name (ignoring case), or BOTTOM_LEFT if the given name is not a valid position. */ - public static GuiPosition fromName(String name){ - - for(GuiPosition position : values()){ - if(position.name.equalsIgnoreCase(name)) return position; - } - - Wizardry.logger.info("Invalid string for the spell HUD position. Using default (bottom left) instead."); - return BOTTOM_LEFT; - } - - } - - // As of Wizardry 1.1, all keys used in the config file itself are now hardcoded, not localised. The localisations - // are done in the config GUI. The config file has to be written in one language or it will end up with multiple - // options for different languages. - - // These methods are package-protected to stop anyone else from calling them. - - /** Called from preInit to initialise the config file. The first part of the config file has to be done here (as is - * conventional) so that the various registries can change what they do accordingly. The spell part of the config - * has to be done in the init method.*/ - void initConfig(FMLPreInitializationEvent event){ - - config = new Configuration(event.getSuggestedConfigurationFile()); - config.load(); - - Wizardry.logger.info("Setting up main config"); - - setupGeneralConfig(); - - config.save(); - } - - /** Called from init to initialise the parts of the config file that depend on other mods. For example, the spell - * config is done here and not in preInit because all spells must be registered before it is added, including - * those in other mods. */ - void initConfigExtras(){ - - Wizardry.logger.info("Setting up spells config for " + Spell.getTotalSpellCount() + " spells"); - - setupSpellsConfig(); - - config.save(); - } - - /** Called to save changes to the config file after it has been edited in game from the menus. */ - void saveConfigChanges(){ - - Wizardry.logger.info("Saving in-game config changes"); - - setupGeneralConfig(); - setupSpellsConfig(); - - config.save(); - } - - /** Sends a packet to the specified player's client containing all the synchronised settings. */ - public void sync(EntityPlayerMP player){ - Wizardry.logger.info("Synchronising config settings for " + player.getName()); - IMessage message = new PacketSyncSettings.Message(this); - WizardryPacketHandler.net.sendTo(message, player); - } - - public ConfigCategory getConfigCategory(String name){ - return config.getCategory(name); - } - - private void setupSpellsConfig(){ - - config.addCustomCategoryComment(SPELLS_CATEGORY, "Set a spell to false to disable it. Disabled spells will still have their associated spell book (mainly so the spell books don't all change) and can still be bound to wands, but cannot be cast in game, will not appear in any subsequently generated chests or wizard trades and will not drop from mobs. Disable a spell if it is causing problems, conflicts with another mod or creates an unintended exploit."); - - Property property; - - for(Spell spell : Spell.getSpells(Spell.allSpells)){ - property = config.get(SPELLS_CATEGORY, spell.getRegistryName().toString(), true, - I18n.translateToLocal("spell." + spell.getUnlocalisedName() + ".desc")); - // Uses the same config key as the spell name, because - well, that's what it's called! - property.setLanguageKey("spell." + spell.getUnlocalisedName()); - spell.setEnabled(property.getBoolean()); - } - - } - - private void setupGeneralConfig(){ - - // This trick is borrowed from forge; it sorts the config options into the order you want them. - List propOrder = new ArrayList(); - - Property property; - - config.addCustomCategoryComment(Configuration.CATEGORY_GENERAL, "Please note that changing some of these settings may make the mod very difficult to play."); - - property = config.get(Configuration.CATEGORY_GENERAL, "towerRarity", 8, "Rarity of wizard towers. Higher numbers are rarer. Set to 0 to disable wizard towers completely.", 0, 50); - property.setLanguageKey("config.wizardry.tower_rarity"); - property.setRequiresWorldRestart(true); - Wizardry.proxy.setToNumberSliderEntry(property); - towerRarity = property.getInt(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "spellBookDropChance", 3, "The chance for mobs to drop a spell book when killed. The greater this number, the more often they will drop. Set to 0 to disable spell book drops. Set to 200 for guaranteed drops.", 0, 200); - property.setLanguageKey("config.wizardry.spell_book_drop_chance"); - Wizardry.proxy.setToNumberSliderEntry(property); - spellBookDropChance = property.getInt(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "oreDimensions", new int[]{0}, "List of dimension ids in which crystal ore will generate. Note that removing the overworld (id 0) from this list will make the mod VERY difficult to play!"); - property.setLanguageKey("config.wizardry.ore_dimensions"); - property.setRequiresWorldRestart(true); - oreDimensions = property.getIntList(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "flowerDimensions", new int[]{0}, "List of dimension ids in which crystal flowers will generate."); - property.setLanguageKey("config.wizardry.flower_dimensions"); - property.setRequiresWorldRestart(true); - flowerDimensions = property.getIntList(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "towerDimensions", new int[]{0}, "List of dimension ids in which wizard towers will generate."); - property.setLanguageKey("config.wizardry.tower_dimensions"); - property.setRequiresWorldRestart(true); - towerDimensions = property.getIntList(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "generateLoot", true, "Whether to generate wizardry loot in dungeon chests."); - property.setLanguageKey("config.wizardry.generate_loot"); - property.setRequiresWorldRestart(true); - generateLoot = property.getBoolean(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "firebombIsCraftable", true, "Whether firebombs can be crafted or not."); - property.setLanguageKey("config.wizardry.firebomb_is_craftable"); - property.setRequiresMcRestart(true); - firebombIsCraftable = property.getBoolean(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "poisonBombIsCraftable", true, "Whether poison bombs can be crafted or not."); - property.setLanguageKey("config.wizardry.poison_bomb_is_craftable"); - property.setRequiresMcRestart(true); - poisonBombIsCraftable = property.getBoolean(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "smokeBombIsCraftable", true, "Whether smoke bombs can be crafted or not."); - property.setLanguageKey("config.wizardry.smoke_bomb_is_craftable"); - property.setRequiresMcRestart(true); - smokeBombIsCraftable = property.getBoolean(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "useAlternateScrollRecipe", false, "Whether to require a magic crystal in the shapeless crafting recipe for blank scrolls. Set to true if another mod adds a conflicting recipe."); - property.setLanguageKey("config.wizardry.use_alternate_scroll_recipe"); - property.setRequiresMcRestart(true); - useAlternateScrollRecipe = property.getBoolean(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "teleportThroughUnbreakableBlocks", false, "Whether players are allowed to teleport through unbreakable blocks (e.g. bedrock) using the phase step spell."); - property.setLanguageKey("config.wizardry.teleport_through_unbreakable_blocks"); - teleportThroughUnbreakableBlocks = property.getBoolean(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "showSummonedCreatureNames", true, "Whether to show summoned creatures' names and owners above their heads."); - property.setLanguageKey("config.wizardry.show_summoned_creature_names"); - showSummonedCreatureNames = property.getBoolean(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "friendlyFire", true, "Whether to allow players to damage their designated allies using magic."); - property.setLanguageKey("config.wizardry.friendly_fire"); - friendlyFire = property.getBoolean(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "telekineticDisarmament", true, "Whether to allow players to disarm other players using the telekinesis spell. Set to false to prevent stealing of items."); - property.setLanguageKey("config.wizardry.telekinetic_disarmament"); - telekineticDisarmament = property.getBoolean(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "discoveryMode", true, "For those who like a sense of mystery! When set to true, spells you haven't cast yet will be unreadable until you cast them (on a per-world basis). Has no effect when in creative mode. Spells of identification will be unobtainable in survival mode if this is false."); - property.setLanguageKey("config.wizardry.discovery_mode"); - property.setRequiresWorldRestart(true); - discoveryMode = property.getBoolean(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "enableShiftScrolling", true, "Whether you can switch between spells on a wand by scrolling with the mouse wheel while sneaking. Note that this will only affect you; other players connected to the same server obey their own settings."); - property.setLanguageKey("config.wizardry.enable_shift_scrolling"); - property.setRequiresWorldRestart(false); - enableShiftScrolling = property.getBoolean(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "minionRevengeTargeting", true, "Whether summoned creatures can revenge attack their owner if their owner attacks them."); - property.setLanguageKey("config.wizardry.minion_revenge_targeting"); - property.setRequiresWorldRestart(false); - minionRevengeTargeting = property.getBoolean(); - propOrder.add(property.getName()); - - // These two aren't sliders because using a slider makes it difficult to fine-tune the numbers; the nature of a - // scaling factor means that 0.5 is as big a change as 2.0, so whilst a slider is fine for increasing the damage, - // it doesn't give fine enough control for values less than 1. - property = config.get(Configuration.CATEGORY_GENERAL, "playerDamageScaling", 1.0, "Global damage scaling factor for the damage dealt by players casting spells, relative to 1.", 0, 20); - property.setLanguageKey("config.wizardry.player_damage_scaling"); - playerDamageScale = property.getDouble(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "npcDamageScaling", 1.0, "Global damage scaling factor for the damage dealt by NPCs casting spells, relative to 1.", 0, 20); - property.setLanguageKey("config.wizardry.npc_damage_scaling"); - npcDamageScale = property.getDouble(); - propOrder.add(property.getName()); - - // This one isn't a slider either because people are likely to want exact values ("it must be at most 50.3" is a bit strange!). - property = config.get(Configuration.CATEGORY_GENERAL, "castCommandMultiplierLimit", 20.0, "Upper limit for the multipliers passed into the /cast command. This is here to stop players from accidentally breaking a world/server. Large blast mutipliers can cause extreme lag - you have been warned!", 1, 255); - property.setLanguageKey("config.wizardry.cast_command_multiplier_limit"); - maxSpellCommandMultiplier = property.getDouble(); - propOrder.add(property.getName()); - - property = config.get(Configuration.CATEGORY_GENERAL, "summonedCreatureTargetsWhitelist", new String[0], "List of names of entities which summoned creatures and wizards are allowed to attack, in addition to the defaults. Add mod creatures to this list if you want summoned creatures to attack them and they aren't already doing so. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard)."); - property.setLanguageKey("config.wizardry.summoned_creature_targets_whitelist"); - property.setRequiresWorldRestart(true); - //Wizardry.proxy.setToEntityNameEntry(property); - summonedCreatureTargetsWhitelist = property.getStringList(); - // Converts all strings in the list to lower case, to ignore case sensitivity, and trims them. - for(int i=0; i propOrder1 = new ArrayList(); - - config.addCustomCategoryComment(RESISTANCES_CATEGORY, "Settings which allow entities to be made immune to certain types of magic. In multiplayer, the server/LAN host settings will apply."); - - property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToFire", new String[]{}, "List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard)."); - property.setLanguageKey("config.wizardry.mobs_immune_to_fire"); - property.setRequiresMcRestart(true); - //Wizardry.proxy.setToEntityNameEntry(property); - // Converts all strings in the list to lower case, to ignore case sensitivity, and trims them. - for(int i=0; i randomNames = new HashMap(Spell.getTotalSpellCount()); public Map randomDescriptions = new HashMap(Spell.getTotalSpellCount()); @@ -113,8 +109,6 @@ public class SpellGlyphData extends WorldSavedData { PacketGlyphData.Message msg = new PacketGlyphData.Message(names, descriptions); WizardryPacketHandler.net.sendTo(msg, player); - - Wizardry.logger.info("Synchronising spell glyph data for " + player.getName()); } @@ -146,7 +140,7 @@ public class SpellGlyphData extends WorldSavedData { } @Override - public NBTTagCompound writeToNBT(NBTTagCompound nbt){ + public void writeToNBT(NBTTagCompound nbt){ NBTTagList tagList = new NBTTagList(); @@ -161,16 +155,5 @@ public class SpellGlyphData extends WorldSavedData { } nbt.setTag("spellGlyphData", tagList); - - return nbt; - } - - @SubscribeEvent - public static void onWorldLoadEvent(WorldEvent.Load event){ - if(!event.getWorld().isRemote && event.getWorld().provider.getDimension() == 0){ - // Called to initialise the spell glyph data when a world loads, if it isn't already. - // NOTE: Do we actually need this, or can we just let it initialise the first time it is needed? (see below) - SpellGlyphData.get(event.getWorld()); - } } } \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/util/WandHelper.java b/src/main/java/electroblob/wizardry/WandHelper.java similarity index 71% rename from src/main/java/electroblob/wizardry/util/WandHelper.java rename to src/main/java/electroblob/wizardry/WandHelper.java index 15c0466b..a36202cc 100644 --- a/src/main/java/electroblob/wizardry/util/WandHelper.java +++ b/src/main/java/electroblob/wizardry/WandHelper.java @@ -1,11 +1,8 @@ -package electroblob.wizardry.util; +package electroblob.wizardry; -import java.util.Collections; import java.util.HashMap; import java.util.Set; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.registry.WizardryItems; import electroblob.wizardry.spell.Spell; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -23,18 +20,15 @@ import net.minecraft.nbt.NBTTagCompound; * unlikely case that this is necessary. *

    * Also note that none of the methods in this class actually check that the given ItemStack contains an ItemWand; you - * can, for example, pass in a stack of snowballs without causing problems, but that is of course pointless! However, - * if you have your own spell casting item (which doesn't extend ItemWand), this setup means you can still use this class - * to manage its NBT structure. + * can, for example, pass in a stack of snowballs without causing problems, but that is of course pointless! *

    - * All get methods in this class return some kind of default if the passed-in wand stack has no nbt data. - * See individual method descriptions for more details.
    + * All get methods in this class return some kind of default if the passed-in wand stack has no nbt data.
    * All set methods in this class create a new nbt data for the passed-in wand if it has none, before doing * whatever else they do. * @see electroblob.wizardry.item.ItemWand ItemWand * @see electroblob.wizardry.packet.PacketControlInput PacketControlInput * @since Wizardry 1.1 */ -public final class WandHelper { +public class WandHelper { // NBT tag keys public static final String SPELL_ARRAY_KEY = "spells"; @@ -45,14 +39,14 @@ public final class WandHelper { private static final HashMap upgradeMap = new HashMap(); static { - upgradeMap.put(WizardryItems.condenser_upgrade, "condenser"); - upgradeMap.put(WizardryItems.storage_upgrade, "storage"); - upgradeMap.put(WizardryItems.siphon_upgrade, "siphon"); - upgradeMap.put(WizardryItems.range_upgrade, "range"); - upgradeMap.put(WizardryItems.duration_upgrade, "duration"); - upgradeMap.put(WizardryItems.cooldown_upgrade, "cooldown"); - upgradeMap.put(WizardryItems.blast_upgrade, "blast"); - upgradeMap.put(WizardryItems.attunement_upgrade, "attunement"); + upgradeMap.put(Wizardry.condenserUpgrade, "condenser"); + upgradeMap.put(Wizardry.storageUpgrade, "storage"); + upgradeMap.put(Wizardry.siphonUpgrade, "siphon"); + upgradeMap.put(Wizardry.rangeUpgrade, "range"); + upgradeMap.put(Wizardry.durationUpgrade, "duration"); + upgradeMap.put(Wizardry.cooldownUpgrade, "cooldown"); + upgradeMap.put(Wizardry.blastUpgrade, "blast"); + upgradeMap.put(Wizardry.attunementUpgrade, "attunement"); } /** Returns an array containing the spells currently bound to the given wand. As of Wizardry 1.1, this array is not @@ -62,9 +56,9 @@ public final class WandHelper { Spell[] spells = new Spell[0]; - if(wand.getTagCompound() != null){ + if(wand.stackTagCompound != null){ - int[] spellIDs = wand.getTagCompound().getIntArray(SPELL_ARRAY_KEY); + int[] spellIDs = wand.stackTagCompound.getIntArray(SPELL_ARRAY_KEY); spells = new Spell[spellIDs.length]; @@ -79,15 +73,15 @@ public final class WandHelper { /** Binds the given array of spells to the given wand. The array can be anywhere between 5 and 8 (inclusive) in length. */ public static void setSpells(ItemStack wand, Spell[] spells){ - if(wand.getTagCompound() == null) wand.setTagCompound((new NBTTagCompound())); + if(wand.stackTagCompound == null) wand.stackTagCompound = new NBTTagCompound(); int[] spellIDs = new int[spells.length]; for(int i=0; inot
    account for the individual or total upgrade stack limits. */ public static void applyUpgrade(ItemStack wand, Item upgrade){ - if(wand.getTagCompound() == null) wand.setTagCompound((new NBTTagCompound())); + if(wand.stackTagCompound == null) wand.stackTagCompound = new NBTTagCompound(); - if(!wand.getTagCompound().hasKey(UPGRADES_KEY)) wand.getTagCompound().setTag(UPGRADES_KEY, new NBTTagCompound()); + if(!wand.stackTagCompound.hasKey(UPGRADES_KEY)) wand.stackTagCompound.setTag(UPGRADES_KEY, new NBTTagCompound()); - NBTTagCompound upgrades = wand.getTagCompound().getCompoundTag(UPGRADES_KEY); + NBTTagCompound upgrades = wand.stackTagCompound.getCompoundTag(UPGRADES_KEY); String key = upgradeMap.get(upgrade); if(key != null) upgrades.setInteger(key, upgrades.getInteger(key) + 1); - wand.getTagCompound().setTag(UPGRADES_KEY, upgrades); + wand.stackTagCompound.setTag(UPGRADES_KEY, upgrades); } /** Returns true if the given item is a valid special wand upgrade. */ @@ -264,18 +258,9 @@ public final class WandHelper { return upgradeMap.containsKey(upgrade); } - /** Returns an unmodifiable set of all the items which are valid special wand upgrades. */ + /** Returns a set of all the items which are valid special wand upgrades. */ public static Set getSpecialUpgrades(){ - return Collections.unmodifiableSet(WandHelper.upgradeMap.keySet()); - } - - /** Package-protected getter for the identifier that corresponds to the given item, used only in the - * {@link SpellModifiers} class. Internal to Wizardry. - * @throws IllegalArgumentException if the given item is not a registered special wand upgrade.*/ - static String getIdentifier(Item upgrade){ - if(!isWandUpgrade(upgrade)) throw new IllegalArgumentException("Tried to get a wand upgrade key for an item" - + "that is not a registered special wand upgrade."); - return upgradeMap.get(upgrade); + return WandHelper.upgradeMap.keySet(); } /** Registers a special upgrade with wizardry. Not used in the base mod, but I've put it here to make it easy diff --git a/src/main/java/electroblob/wizardry/WeightedRandomSpellBook.java b/src/main/java/electroblob/wizardry/WeightedRandomSpellBook.java new file mode 100644 index 00000000..3dacabd8 --- /dev/null +++ b/src/main/java/electroblob/wizardry/WeightedRandomSpellBook.java @@ -0,0 +1,64 @@ +package electroblob.wizardry; + +import java.util.Random; + +import electroblob.wizardry.item.ItemScroll; +import electroblob.wizardry.item.ItemSpellBook; +import electroblob.wizardry.item.ItemWand; +import electroblob.wizardry.item.ItemWizardArmour; +import electroblob.wizardry.spell.Spell; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemStack; +import net.minecraft.util.WeightedRandomChestContent; +import net.minecraftforge.common.ChestGenHooks; + +public class WeightedRandomSpellBook extends WeightedRandomChestContent{ + + public WeightedRandomSpellBook(ItemStack par1ItemStack, int par2, int par3, + int par4) { + super(par1ItemStack, par2, par3, par4); + } + + /* A brief comment about dungeon loot: + * Tiers are weighted as per usual. Elements all have equal chance, INCLUDING simple stuff. The main reason for + * this is that dungeon loot is not that common anyway, so making elemental gear even rarer would be too much. + */ + + protected ItemStack[] generateChestContent(Random random, IInventory newInventory){ + + if(theItemId.getItem() instanceof ItemSpellBook){ + + theItemId = new ItemStack(theItemId.getItem(), 1, WizardryUtilities.getStandardWeightedRandomSpellId(random)); + + }else if(theItemId.getItem() instanceof ItemWand){ + + theItemId = new ItemStack(WizardryUtilities.getWand(EnumTier.BASIC, EnumElement.values()[random.nextInt(EnumElement.values().length)])); + + }else if(theItemId.getItem() instanceof ItemWizardArmour){ + + theItemId = new ItemStack(WizardryUtilities.getArmour(EnumElement.values()[random.nextInt(EnumElement.values().length)], random.nextInt(3))); + + }else if(theItemId.getItem() instanceof ItemScroll){ + + int spellId = WizardryUtilities.getStandardWeightedRandomSpellId(random, true); + theItemId = new ItemStack(theItemId.getItem(), 1, spellId); + + }else if(theItemId.getItem() == Wizardry.condenserUpgrade){ + + switch(random.nextInt(8)){ + case 0: theItemId = new ItemStack(Wizardry.condenserUpgrade); break; + case 1: theItemId = new ItemStack(Wizardry.siphonUpgrade); break; + case 2: theItemId = new ItemStack(Wizardry.rangeUpgrade); break; + case 3: theItemId = new ItemStack(Wizardry.cooldownUpgrade); break; + case 4: theItemId = new ItemStack(Wizardry.durationUpgrade); break; + case 5: theItemId = new ItemStack(Wizardry.storageUpgrade); break; + case 6: theItemId = new ItemStack(Wizardry.blastUpgrade); break; + case 7: theItemId = new ItemStack(Wizardry.attunementUpgrade); break; + } + + } + + return ChestGenHooks.generateStacks(random, theItemId, theMinimumChanceToGenerateItem, theMaximumChanceToGenerateItem); + } + +} diff --git a/src/main/java/electroblob/wizardry/WizardData.java b/src/main/java/electroblob/wizardry/WizardData.java deleted file mode 100644 index c8cc4aca..00000000 --- a/src/main/java/electroblob/wizardry/WizardData.java +++ /dev/null @@ -1,660 +0,0 @@ -package electroblob.wizardry; - -import java.lang.ref.WeakReference; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.UUID; - -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.enchantment.Imbuement; -import electroblob.wizardry.entity.EntityShield; -import electroblob.wizardry.entity.living.ISummonedCreature; -import electroblob.wizardry.event.SpellCastEvent; -import electroblob.wizardry.event.SpellCastEvent.Source; -import electroblob.wizardry.packet.PacketCastContinuousSpell; -import electroblob.wizardry.packet.PacketPlayerSync; -import electroblob.wizardry.packet.PacketTransportation; -import electroblob.wizardry.packet.WizardryPacketHandler; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.registry.WizardryAchievements; -import electroblob.wizardry.spell.None; -import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.MobEffects; -import net.minecraft.init.SoundEvents; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagInt; -import net.minecraft.nbt.NBTTagString; -import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.BlockPos; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.capabilities.CapabilityInject; -import net.minecraftforge.common.capabilities.ICapabilitySerializable; -import net.minecraftforge.common.util.Constants.NBT; -import net.minecraftforge.event.AttachCapabilitiesEvent; -import net.minecraftforge.event.entity.EntityJoinWorldEvent; -import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.common.util.INBTSerializable; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; - -/** Capability-based replacement for the old ExtendedPlayer class from 1.7.10. This has been reworked to leave - * minimum external changes (for my own sanity, mainly!). Turns out the only major difference between an internal - * capability and an IEEP is a couple of redundant classes and a different way of registering it. - *

    - * Forge seems to have separate classes to hold the Capability<...> instance ('key') and - * methods for getting the capability, but in my opinion there are already too many classes to deal with, so I'm not - * adding any more than are necessary, meaning those constants and values are kept here instead. - * @since Wizardry 1.2 - * @author Electroblob */ -// On the plus side, having to rethink this class allowed me to clean it up a lot. -@Mod.EventBusSubscriber -public class WizardData implements INBTSerializable { - - /** Static instance of what I like to refer to as the capability key. Private because, well, it's internal! */ - // This annotation does some crazy Forge magic behind the scenes and assigns this field a value. - @CapabilityInject(WizardData.class) - private static final Capability WIZARD_DATA_CAPABILITY = null; - - /** The player this WizardData instance belongs to. */ - private final EntityPlayer player; - - // This one is still necessary, because I can't override the equip animation for items that aren't from Wizardry. - private Map imbuementDurations; - - public boolean hasSpiritWolf; - public boolean hasSpiritHorse; - - /** Whether this player is currently casting a continuous spell via commands. Not saved over world reload - * and reset on player death. */ - private Spell currentlyCasting; - /** The time for which this player has been casting a continuous spell via commands. Increments by 1 each tick. - * Not saved over world reload and reset on player death. */ - private int castingTick; - /** SpellModifiers object for the current continuous spell cast via commands. Not saved over world reload and - * reset on player death. */ - private SpellModifiers spellModifiers; - /** Coordinates for the saved transportation stone circle location. Will be null if no location is saved. */ - private BlockPos stoneCircleLocation; - /** Dimension id which the saved stone circle is in. */ - private int stoneCircleDimension; - /** Time left until the player teleports under the effect of transportation */ - private int tpCountdown; - - /** Coordinates for the saved clairvoyance location. Will be null if no location is saved. */ - private BlockPos clairvoyanceLocation; - /** Dimension id which the saved clairvoyance point is in. */ - private int clairvoyanceDimension; - - public EntityShield shield; - - public WeakReference selectedMinion; - - /** Set of this player's discovered spells. Do not write to this list directly, use - * {@link WizardData#discoverSpell(Spell)} instead. */ - public Set spellsDiscovered; - - private Set allies; - /** List of usernames of this player's allies. May not be accurate 100% of the time. This is here so that a player - * can view the usernames of their allies even when those allies are not online. - * Do not use this for any other purpose than displaying the names! */ - public Set allyNames; - - private Set soulboundCreatures; - - public WizardData(EntityPlayer player){ - this.player = player; - this.imbuementDurations = new HashMap(); - this.spellsDiscovered = new HashSet(); - // All players can recognise magic missile. This is not done using discoverSpell because that seems to cause - // a crash on load occasionally (probably something to do with achievements being initalised) - this.spellsDiscovered.add(Spells.magic_missile); - this.hasSpiritWolf = false; - this.hasSpiritHorse = false; - this.currentlyCasting = Spells.none; - this.spellModifiers = new SpellModifiers(); - this.castingTick = 0; - this.stoneCircleDimension = 0; - this.clairvoyanceDimension = 0; - this.setTpCountdown(0); - this.allies = new HashSet(); - this.allyNames = new HashSet(); - this.soulboundCreatures = new HashSet(); - } - - public boolean hasSpellBeenDiscovered(Spell spell){ - return spellsDiscovered.contains(spell) || spell instanceof None; - } - - /** - * Adds the given spell to the list of discovered spells for this player. Automatically takes into account - * whether the spell has been discovered. Use this method rather than adding directly to the list because it - * handles achievements. - * @param spell The spell to be discovered - * @return True if the spell had not already been discovered; false otherwise. - */ - public boolean discoverSpell(Spell spell){ - - if(spellsDiscovered == null){ - spellsDiscovered = new HashSet(); - } - // The 'none' spell cannot be discovered - if(spell instanceof None) return false; - // Tries to add the spell to the list of discovered spells, and returns false if it was already present - if(!spellsDiscovered.add(spell)) return false; - // If the spell had not already been discovered, achievements can be triggered and the method returns true - if(spellsDiscovered.containsAll(Spell.getSpells(Spell::isEnabled))){ - this.player.addStat(WizardryAchievements.all_spells); - } - - for(Element element : Element.values()){ - if(element != Element.MAGIC && spellsDiscovered.containsAll(Spell.getSpells(new Spell.TierElementFilter(null, element)))){ - this.player.addStat(WizardryAchievements.element_master); - } - } - - return true; - } - - /** Sets the player's saved transportation stone location and dimension. */ - public void setStoneCircleLocation(BlockPos pos, int dimensionID){ - this.stoneCircleLocation = pos; - this.stoneCircleDimension = dimensionID; - } - - /** Returns the coordinates of the associated player's saved transportation stone circle. */ - public BlockPos getStoneCircleLocation(){ return stoneCircleLocation; } - /** Returns the dimension ID of the associated player's saved transportation stone circle. */ - public int getStoneCircleDimension(){ return stoneCircleDimension; } - - public int getTpCountdown() { return tpCountdown; } - - public void setTpCountdown(int tpCountdown) { this.tpCountdown = tpCountdown; } - - /** Sets the player's saved clairvoyance location. */ - public void setClairvoyancePoint(BlockPos pos, int dimensionID){ - this.clairvoyanceLocation = pos; - this.clairvoyanceDimension = dimensionID; - } - - /** Returns the coordinates for the saved clairvoyance location. Will be null if no location is saved. */ - public BlockPos getClairvoyanceLocation(){ return clairvoyanceLocation; } - - /** Returns the dimension ID for the saved clairvoyance location. Will be null if no location is saved. */ - public int getClairvoyanceDimension(){ return clairvoyanceDimension; } - - /** Overwrites the imbuement duration associated with the given imubement for this player, or creates it if there - * was none previously. - * @throws IllegalArgumentException if the given {@link Enchantment} is not an {@link Imbuement}. */ - public void setImbuementDuration(Enchantment enchantment, int duration){ - // It is best to throw an exception here, because otherwise the error would either go unnoticed (if non-imbuements - // were ignored) or cause a ClassCastException later (if non-imbuements were allowed to be added). - if(enchantment instanceof Imbuement){ - this.imbuementDurations.put((Imbuement) enchantment, duration); - }else{ - throw new IllegalArgumentException("Attempted to set an imbuement duration for something that isn't an Imbuement! (This exception has been thrown now to prevent a ClassCastException from occurring later.)"); - } - } - - /** Returns the imbuement duration associated with the given imbuement for this player, or 0 if it does not exist. */ - @SuppressWarnings("unlikely-arg-type") - public int getImbuementDuration(Enchantment enchantment){ - // Need to check that i is not null, otherwise it throws an NPE when Java auto-unboxes it. - // What's nice here is that the map simply accepts objects as keys, so there's no need to cast or throw exceptions. - Integer i = this.imbuementDurations.get(enchantment); - // If i is null, returns 0; otherwise returns i, auto-unboxed to an int. - return i == null ? 0 : i; - } - - /** Decrements the duration for each conjured item by 1, and removes from the map any that are 0 or less or that - * the player no longer has. Also deletes the item from the player's inventory if it runs out of time. */ - private void updateImbuedItems(){ - - Set activeImbuements = new HashSet(); - - // For each item in the player's inventory - for(ItemStack stack : player.inventory.mainInventory){ - if(stack != null && stack.isItemEnchanted()){ - - Map enchantments = EnchantmentHelper.getEnchantments(stack); - - Iterator> iterator = enchantments.entrySet().iterator(); - // For each of the item's enchantments - while(iterator.hasNext()){ - Enchantment enchantment = iterator.next().getKey(); - // Ignores the enchantment unless it is an imbuement - if(enchantment instanceof Imbuement){ - int duration = this.getImbuementDuration(enchantment); - // If the imbuement is still active: - if(duration > 0){ - // Decrements the timer - this.imbuementDurations.put((Imbuement)enchantment, duration-1); - // Adds this imbuement to the set of imbuements that need to be kept - activeImbuements.add((Imbuement)enchantment); - // Otherwise: - }else{ - // Removes the enchantment from the enchantment map - iterator.remove(); - // Applies the new enchantment map to the item - EnchantmentHelper.setEnchantments(enchantments, stack); - } - } - } - } - } - // Removes all imbuements from the map that are no longer active - this.imbuementDurations.keySet().retainAll(activeImbuements); - } - - /** Adds the given player to the list of allies belonging to the associated player, or removes the player if - * they are already in the list of allies. Returns true if the player was added, false if they were removed. */ - public boolean toggleAlly(EntityPlayer player){ - if(this.isPlayerAlly(player)){ - this.allies.remove(player.getUniqueID()); - // The remove method uses .equals() rather than == so this will work fine. - this.allyNames.remove(player.getName()); - return false; - }else{ - this.allies.add(player.getUniqueID()); - this.allyNames.add(player.getName()); - return true; - } - } - - /** Returns whether the given player is in this player's list of allies, or is on the same team as this player. */ - public boolean isPlayerAlly(EntityPlayer player){ - return this.allies.contains(player.getUniqueID()) || this.player.isOnSameTeam(player); - } - - /** Adds the given entity to this player's list of soulbound creatures, and returns whether it succeeded. */ - public boolean soulbind(EntityLivingBase target){ - return this.soulboundCreatures.add(target.getUniqueID()); - } - - /** Returns whether the given entity has been soulbound to this player. */ - public boolean isCreatureSoulbound(EntityPlayer target){ - return this.soulboundCreatures.contains(target.getUniqueID()); - } - - /** Damages all creatures soulbound to this player by the given amount, and removes from the list any that no - * longer exist. */ - public void damageAllSoulboundCreatures(float damage){ - - for(Iterator iterator = this.soulboundCreatures.iterator(); iterator.hasNext();){ - - Entity entity = WizardryUtilities.getEntityByUUID(this.player.worldObj, iterator.next()); - - if(entity == null) iterator.remove(); - - if(entity instanceof EntityLivingBase){ - // Retaliatory effect - if(entity.attackEntityFrom(MagicDamage.causeDirectMagicDamage(this.player, DamageType.MAGIC, true), damage)){ - // Sound only plays if the damage succeeds - player.playSound(SoundEvents.ENTITY_WITHER_HURT, 1.0F, player.worldObj.rand.nextFloat() * 0.2F + 1.0F); - } - } - } - } - - /** Starts casting the given spell with the given modifiers. */ - public void startCastingContinuousSpell(Spell spell, SpellModifiers modifiers){ - - this.currentlyCasting = spell; - this.spellModifiers = modifiers; - - if(!this.player.worldObj.isRemote){ - PacketCastContinuousSpell.Message message = new PacketCastContinuousSpell.Message(this.player.getEntityId(), - spell.id(), this.spellModifiers); - WizardryPacketHandler.net.sendToDimension(message, this.player.worldObj.provider.getDimension()); - } - } - - /** Stops casting the current spell. */ - public void stopCastingContinuousSpell(){ - - this.currentlyCasting = Spells.none; - this.castingTick = 0; - this.spellModifiers.reset(); - - if(!this.player.worldObj.isRemote){ - PacketCastContinuousSpell.Message message = new PacketCastContinuousSpell.Message(this.player.getEntityId(), - Spells.none.id(), this.spellModifiers); - WizardryPacketHandler.net.sendToDimension(message, this.player.worldObj.provider.getDimension()); - } - } - - /** Casts the current continuous spell, fires relevant events and updates the castingTick field. */ - public void updateContinuousSpellCasting(){ - - if(this.currentlyCasting != null && this.currentlyCasting.isContinuous){ - - if(MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Tick(player, currentlyCasting, spellModifiers, Source.COMMAND, castingTick))){ - this.stopCastingContinuousSpell(); - return; - } - - if(this.currentlyCasting.cast(player.worldObj, player, EnumHand.MAIN_HAND, castingTick, this.spellModifiers) - && this.castingTick == 0){ - // On the first tick casting a continuous spell via commands, SpellCastEvent.Post is fired. - MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(player, currentlyCasting, spellModifiers, Source.COMMAND)); - } - - castingTick++; - - }else{ - // Why is this here? Surely castingTick will always be 0 if currentlyCasting is null? - this.castingTick = 0; - } - } - - /** Returns whether this player is currently casting a continuous spell via commands. */ - public boolean isCasting(){ - return this.currentlyCasting != null && this.currentlyCasting != Spells.none; - } - - /** Returns the continuous spell this player is currently casting via commands, or the 'none' spell if they aren't - * casting anything. */ - public Spell currentlyCasting(){ - return currentlyCasting; - } - - /** Called each time the associated player is updated. */ - private void update(){ - - if(this.selectedMinion != null && this.selectedMinion.get() == null) this.selectedMinion = null; - - // This new system removes a lot of repetitive event handler code and inflexible variables which had duplicate - // functions, just for different enchantments. - updateImbuedItems(); - - if(!player.worldObj.isRemote){ - if(getTpCountdown() == 1){ - player.setPositionAndUpdate(this.stoneCircleLocation.getX() + 0.5, this.stoneCircleLocation.getY(), - this.stoneCircleLocation.getZ() + 0.5); - player.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, 50, 0)); - IMessage msg = new PacketTransportation.Message(player.getEntityId()); - WizardryPacketHandler.net.sendToDimension(msg, player.worldObj.provider.getDimension()); - } - - if(getTpCountdown() > 0){ - setTpCountdown(getTpCountdown() - 1); - } - } - - updateContinuousSpellCasting(); - } - - /** - * Returns the WizardData instance for the specified player. - */ - public static final WizardData get(EntityPlayer player){ - return player.getCapability(WIZARD_DATA_CAPABILITY, null); - } - - /** Called from the event handler each time the associated player entity is cloned, i.e. on respawn or when - * travelling to a different dimension. Used to copy over any variables that should persist over player death. - * This is the inverse of the old onPlayerDeath method, which reset the variables that shouldn't persist. - * @param data The old WizardData whose variables are to be copied over. - * @param respawn True if the player died and is respawning, false if they are just travelling between dimensions. */ - public void copyFrom(WizardData data, boolean respawn){ - // TODO: What happens with spirit wolf and spirit horse? - this.hasSpiritHorse = data.hasSpiritHorse; - this.hasSpiritWolf = data.hasSpiritWolf; - this.allies = data.allies; - this.allyNames = data.allyNames; - this.clairvoyanceDimension = data.clairvoyanceDimension; - this.clairvoyanceLocation = data.clairvoyanceLocation; - this.selectedMinion = data.selectedMinion; - // Curse of soulbinding is lifted when the caster dies, but not when they switch dimensions. - if(!respawn) this.soulboundCreatures = data.soulboundCreatures; - this.spellsDiscovered = data.spellsDiscovered; - this.stoneCircleDimension = data.stoneCircleDimension; - this.stoneCircleLocation = data.stoneCircleLocation; - - // Imbuements are lost on death so their durations do not persist. - // Command spell casting is reset on death so the associated variables do not persist. - // tpCountdown is reset both when the player dies and when they switch dimensions. - - } - - /** Sends a packet to this player's client to synchronise necessary information. Only called server side. */ - public void sync(){ - if(this.player instanceof EntityPlayerMP){ - int id = -1; - if(this.selectedMinion != null && this.selectedMinion.get() instanceof Entity) id = ((Entity)this.selectedMinion.get()).getEntityId(); - IMessage msg = new PacketPlayerSync.Message(this.spellsDiscovered, id); - WizardryPacketHandler.net.sendTo(msg, (EntityPlayerMP)this.player); - } - } - - @Override - public NBTTagCompound serializeNBT() { - - NBTTagCompound properties = new NBTTagCompound(); - - // ...so Java 8 allows you to do stuff like this: - properties.setTag("imbuements", WizardryUtilities.mapToNBT(this.imbuementDurations, - imbuement -> new NBTTagInt(Enchantment.getEnchantmentID((Enchantment)imbuement)), NBTTagInt::new)); - - properties.setBoolean("hasSpiritWolf", this.hasSpiritWolf); - properties.setBoolean("hasSpiritHorse", this.hasSpiritHorse); - - if(this.stoneCircleLocation != null) properties.setLong("stoneCircleLocation", this.stoneCircleLocation.toLong()); - properties.setInteger("stoneCircleDimension", this.stoneCircleDimension); - properties.setInteger("tpCountdown", this.tpCountdown); - - if(this.clairvoyanceLocation != null) properties.setLong("clairvoyanceLocation", this.clairvoyanceLocation.toLong()); - properties.setInteger("clairvoyanceDimension", this.getClairvoyanceDimension()); - - // THIS is why I wrote the list/map <-> NBT methods. Look how neat this is! - properties.setTag("allies", WizardryUtilities.listToNBT(this.allies, WizardryUtilities::UUIDtoTagCompound)); - properties.setTag("allyNames", WizardryUtilities.listToNBT(this.allyNames, NBTTagString::new)); - properties.setTag("soulboundCreatures", WizardryUtilities.listToNBT(this.soulboundCreatures, WizardryUtilities::UUIDtoTagCompound)); - - // Might be worth converting this over to WizardryUtilities.listToNBT. - int[] spells = new int[this.spellsDiscovered.size()]; - int i=0; - for(Spell spell : this.spellsDiscovered){ - spells[i] = spell.id(); - i++; - } - properties.setIntArray("discoveredSpells", spells); - - return properties; - } - - @Override - public void deserializeNBT(NBTTagCompound nbt) { - - if(nbt != null){ - - this.imbuementDurations = WizardryUtilities.NBTToMap(nbt.getTagList("imbuements", NBT.TAG_COMPOUND), - (NBTTagInt tag) -> (Imbuement)Enchantment.getEnchantmentByID(tag.getInt()), NBTTagInt::getInt); - - this.hasSpiritWolf = nbt.getBoolean("hasSpiritWolf"); - this.hasSpiritHorse = nbt.getBoolean("hasSpiritHorse"); - - this.stoneCircleLocation = BlockPos.fromLong(nbt.getLong("stoneCircleLocation")); - this.stoneCircleDimension = nbt.getInteger("stoneCircleDimension"); - this.tpCountdown = nbt.getInteger("tpCountdown"); - - this.clairvoyanceLocation = BlockPos.fromLong(nbt.getLong("clairvoyanceLocation")); - this.clairvoyanceDimension = nbt.getInteger("clairvoyanceDimension"); - - this.allies = new HashSet(WizardryUtilities.NBTToList(nbt.getTagList("allies", NBT.TAG_COMPOUND), - WizardryUtilities::tagCompoundToUUID)); - - this.allyNames = new HashSet(WizardryUtilities.NBTToList(nbt.getTagList("allyNames", NBT.TAG_STRING), - NBTTagString::getString)); - - this.soulboundCreatures = new HashSet(WizardryUtilities.NBTToList(nbt.getTagList("soulboundCreatures", NBT.TAG_COMPOUND), - WizardryUtilities::tagCompoundToUUID)); - - this.spellsDiscovered = new HashSet(); - for(int id : nbt.getIntArray("discoveredSpells")){ - spellsDiscovered.add(Spell.get(id)); - } - } - } - - // Event handlers - - @SubscribeEvent - // The type parameter here has to be Entity, not EntityPlayer, or the event won't get fired. - public static void onCapabilityLoad(AttachCapabilitiesEvent event){ - - if(event.getObject() instanceof EntityPlayer) - event.addCapability(new ResourceLocation(Wizardry.MODID, "WizardData"), new WizardData.Provider((EntityPlayer)event.getObject())); - - // This demonstrates why capabilities are badly structured: The following code compiles, but what it does is put - // a player into a CapabilityDispatcher, which is in turn stored in that very same player, which makes no sense - // at all! - //event.addCapability(new ResourceLocation(Wizardry.MODID, "WizardData"), event.getObject()); - } - - @SubscribeEvent - public static void onPlayerCloneEvent(PlayerEvent.Clone event){ - - WizardData newData = WizardData.get(event.getEntityPlayer()); - WizardData oldData = WizardData.get(event.getOriginal()); - - newData.copyFrom(oldData, event.isWasDeath()); - } - - @SubscribeEvent - public static void onEntityJoinWorld(EntityJoinWorldEvent event){ - if(!event.getEntity().worldObj.isRemote && event.getEntity() instanceof EntityPlayerMP){ - // Synchronises wizard data after loading. - WizardData data = WizardData.get((EntityPlayer)event.getEntity()); - if(data != null) data.sync(); - } - } - - @SubscribeEvent - public static void onLivingUpdateEvent(LivingUpdateEvent event){ - - if(event.getEntityLiving() instanceof EntityPlayer){ - - EntityPlayer player = (EntityPlayer)event.getEntityLiving(); - - if(WizardData.get(player) != null){ - WizardData.get(player).update(); - } - } - } - - /** This is a nested class for a few reasons: firstly, it makes sense because instances of this and WizardData go - * hand-in-hand; secondly, it's too short to be worth a separate file; and thirdly (and most importantly) it allows - * me to access WIZARD_DATA_CAPABILITY while keeping it private. */ - public static class Provider implements ICapabilitySerializable { - - private final WizardData data; - - public Provider(EntityPlayer player){ - data = new WizardData(player); - } - - @Override - public boolean hasCapability(Capability capability, EnumFacing facing) { - return capability == WIZARD_DATA_CAPABILITY; - } - - @Override - public T getCapability(Capability capability, EnumFacing facing) { - - if(capability == WIZARD_DATA_CAPABILITY){ - return WIZARD_DATA_CAPABILITY.cast(data); - } - - return null; - } - - @Override - public NBTTagCompound serializeNBT() { - return data.serializeNBT(); - } - - @Override - public void deserializeNBT(NBTTagCompound nbt) { - data.deserializeNBT(nbt); - } - - } - - // Ended up deleting IWizardData because it was unnecessary. This is the comment that was at the start of it: - - /* I'm not going to lie, I will never find the capabilities system even remotely intuitive so this is a bare-minimum - * approach just to get things working (four classes where one would have done?!) At one point I considered simply - * wrapping my old IEEP inside a single-field capability, but I eventually decided I would at least *try* to do it - * properly. - * - * "...without having to directly implement many interfaces." - Forge Docs. I still can't see what's wrong with - * implementing many interfaces; surely that's what Java interfaces are designed for? - * - * Other things I find annoying: - * - IStorage. It's completely redundant in the majority of cases, and I don't understand why we need yet another - * separate class. - * - Making an interface, only to implement it once and once only. This completely defeats the point of interfaces. - * - The EnumFacing parameter, which is again redundant for everything that isn't a tile entity. So much for a clean, - * neat system. - * - * What Forge has effectively done is conflated two different functions: attaching data to stuff and cross-mod - * integration/soft dependencies. I think this is bad design; it would have been better to keep the two features separate. - * - * Here's my current understanding of how the capability system works: - * - You make an interface which defines the things your capability can do (this class). I will call this the TEMPLATE. - * - You implement that interface with your default implementation (WizardData). This is the closest analog to your old - * IEEP implementation class. THIS CLASS STORES ALL THE VARIABLES, and hence has one instance for each instance of whatever - * it is attached to. I will call this the DATA. - * - The DATA class implements INBTSerializable (assuming you want it to be saved, which is nearly always the case) - * - Despite its name, Capability does NOT represent a capability itself. Instead, it acts as a sort of identifier/key, - * the idea being that you can access a particular instance of your DATA given the key (which tells forge that you want a - * capability of type TEMPLATE) and the object you want the DATA for. This is what Entity.getCapability(...) does. - * - * To really understand what's going on though, you need to sift through Forge's verbose data structures and find where - * capabilities are actually hooked into vanilla: - * - Anything that implements ICapabilityProvider will have a private CapabilityDispatcher field. This holds other - * ICapabilityProviders. (I know. This inheritance pattern DOES NOT MAKE SENSE, because these could, in theory, be OTHER - * ENTITIES!) - * - This field is assigned a value through Forge's event factory, which, as we are all familiar with, calls all the - * methods marked with @SubscribeEvent. These methods add individual ICapabilityProviders to a Map stored in the event, - * which the event factory then wraps in a CapabilityDispatcher (which is itself an ICapabilityProvider) for the object - * that called it. - * - In your event handler, you return a custom ICapabilityProvider which is effectively bolted on to the player, and - * duplicates the ICapabilityProvider methods so you can hook into them and return an instance of your DATA class. - * - Where before there was a simple collection of IEEPs stored in the player, there is now a tree of ICapabilityProviders: - * - * - Entity/TileEntity/ItemStack - * - Vanilla ICapabilityProviders, mostly IItemHandlers, stored as fields. - * - CapabilityDispatcher, stored as a field. - * - Custom ICapabilityProviders - * - Custom CapabilityDispatchers - * - ... - * - * Most importantly, EACH PLAYER HOLDS THEIR OWN INSTANCE OF THIS TREE. - * - * When a capability is retrieved, the following process happens: - * 1. For the Entity/TileEntity/ItemStack instance, ICapabilityProvider.getCapability(...) is called. - * 2. The request propogates through the tree and finds the requested capability. */ - -} diff --git a/src/main/java/electroblob/wizardry/Wizardry.java b/src/main/java/electroblob/wizardry/Wizardry.java index 69f955fe..98e9bd8b 100644 --- a/src/main/java/electroblob/wizardry/Wizardry.java +++ b/src/main/java/electroblob/wizardry/Wizardry.java @@ -1,173 +1,665 @@ package electroblob.wizardry; -import org.apache.logging.log4j.Logger; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Locale; +import com.google.common.base.Function; +import com.google.common.collect.Ordering; + +import cpw.mods.fml.client.event.ConfigChangedEvent; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.Mod.EventHandler; +import cpw.mods.fml.common.Mod.Instance; +import cpw.mods.fml.common.SidedProxy; +import cpw.mods.fml.common.event.FMLInitializationEvent; +import cpw.mods.fml.common.event.FMLPostInitializationEvent; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import cpw.mods.fml.common.event.FMLServerStartingEvent; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.network.NetworkRegistry; +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.MagicDamage.DamageType; +import electroblob.wizardry.block.BlockArcaneWorkbench; +import electroblob.wizardry.block.BlockCrystal; +import electroblob.wizardry.block.BlockCrystalFlower; +import electroblob.wizardry.block.BlockCrystalOre; +import electroblob.wizardry.block.BlockMagicLight; +import electroblob.wizardry.block.BlockSnare; +import electroblob.wizardry.block.BlockSpectral; +import electroblob.wizardry.block.BlockStatue; +import electroblob.wizardry.block.BlockTransportationStone; +import electroblob.wizardry.block.BlockVanishingCobweb; import electroblob.wizardry.command.CommandCastSpell; import electroblob.wizardry.command.CommandDiscoverSpell; import electroblob.wizardry.command.CommandSetAlly; import electroblob.wizardry.command.CommandViewAllies; +import electroblob.wizardry.enchantment.EnchantmentMagicSword; +import electroblob.wizardry.enchantment.EnchantmentTimed; +import electroblob.wizardry.item.ItemArcaneTome; +import electroblob.wizardry.item.ItemArmourUpgrade; +import electroblob.wizardry.item.ItemFirebomb; +import electroblob.wizardry.item.ItemFlamingAxe; +import electroblob.wizardry.item.ItemFrostAxe; +import electroblob.wizardry.item.ItemIdentificationScroll; +import electroblob.wizardry.item.ItemPoisonBomb; +import electroblob.wizardry.item.ItemScroll; +import electroblob.wizardry.item.ItemSmokeBomb; +import electroblob.wizardry.item.ItemSpawnWizard; +import electroblob.wizardry.item.ItemSpectralArmour; +import electroblob.wizardry.item.ItemSpectralBow; +import electroblob.wizardry.item.ItemSpectralPickaxe; +import electroblob.wizardry.item.ItemSpectralSword; +import electroblob.wizardry.item.ItemSpellBook; +import electroblob.wizardry.item.ItemWand; +import electroblob.wizardry.item.ItemWizardArmour; +import electroblob.wizardry.item.ItemWizardHandbook; import electroblob.wizardry.packet.WizardryPacketHandler; -import electroblob.wizardry.registry.WizardryAchievements; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryRegistry; -import electroblob.wizardry.registry.WizardryTabs; +import electroblob.wizardry.potion.PotionDecay; +import electroblob.wizardry.potion.PotionFrost; +import electroblob.wizardry.potion.PotionMagicEffect; +import electroblob.wizardry.spell.Spell; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; import net.minecraft.item.Item; -import net.minecraft.nbt.NBTBase; -import net.minecraft.util.EnumFacing; +import net.minecraft.item.Item.ToolMaterial; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemStack; +import net.minecraft.potion.Potion; +import net.minecraft.stats.Achievement; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; import net.minecraftforge.common.AchievementPage; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.capabilities.Capability.IStorage; -import net.minecraftforge.common.capabilities.CapabilityManager; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.Mod.EventHandler; -import net.minecraftforge.fml.common.Mod.Instance; -import net.minecraftforge.fml.common.SidedProxy; -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.common.event.FMLMissingMappingsEvent; -import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; -import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import net.minecraftforge.fml.common.event.FMLServerStartingEvent; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.network.NetworkRegistry; -import net.minecraftforge.fml.common.registry.GameRegistry; -import net.minecraftforge.fml.common.registry.GameRegistry.Type; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.common.config.Property; +import net.minecraftforge.common.util.EnumHelper; @Mod(modid = Wizardry.MODID, name = Wizardry.NAME, version = Wizardry.VERSION, guiFactory = "electroblob." + Wizardry.MODID + ".WizardryGuiFactory") public class Wizardry { - /** Wizardry's mod ID. */ public static final String MODID = "wizardry"; - /** Wizardry's mod name, in readable form. */ public static final String NAME = "Electroblob's Wizardry"; - /** The version number for this version of wizardry. The following system is used for version numbers: - *

    [major Minecraft version].[major mod version].[minor mod version/patch]

    - * The major mod version is consistent across Minecraft versions, i.e. Wizardry 1.1 has the same features as - * Wizardry 2.1, but they are for different versions of Minecraft and have separate minor versioning. 1.x.x - * represents Minecraft 1.7.x versions, 2.x.x represents Minecraft 1.10.x versions, 3.x.x represents Minecraft - * 1.11.x versions, and so on. */ - public static final String VERSION = "2.1.2"; - - // IDEA: Improve the algorithm that finds a place to summon creatures to take walls into account. - // IDEA: Replace all uses of Math.cos and Math.sin with MathHelper versions - // IDEA: API feature that automatically injects custom wand upgrades into wizardry's loot tables - // IDEA: Support for the @e selector in the /cast command (the methods already exist, just plug them in) - // IDEA: Dispensers shooting spells from scrolls! Imagine the possibilities! - // == Rendering overhaul! == - // IDEA: Make spirit animals fade away when dispelled - // IDEA: Use your newfound knowledge of OpenGL to render animated boxes around entities being buffed, similar to creeper charge - // IDEA: Redo RenderArc so it looks like lightning (it's literally a load of translucent boxes inside each other) - // IDEA: The arcane workbench could use a few particles - // IDEA: Add a box to the wizard armour model so that the robes bend when the wearer is sneaking - // IDEA: Flash particle (I think it exists in vanilla somewhere) on spell impact - // IDEA: Dust particles spray out from projectiles as they move - // IDEA: Colour fading for particles - // IDEA: Make lightning and other effects particles. There's no reason why you can't pass in a player argument and have the particles move with them! - - /* Minor bugs that need fixing at some point: - * - Player skin hat layer shows through wizard hats - * - Wizard armour breaks rather than just running out of mana (I can't seem to replicate this bug, but I have had - * it happen to me before...) - * - Shift-clicking a stack of special upgrades when in the arcane workbench causes the whole stack to be - * transferred when it should be just one (this is a bug with vanilla as well - try putting a stack of bottles into - * a brewing stand). I have at least made it so only one gets used now, so it has no impact on the game. - * - When a spell is on cooldown, you can't break blocks when holding a wand. */ - - // TODO: So somehow I have managed to overlook the fact that health is actually a float. What this means is that - // I can make the healing spells use damage multipliers - hurrah! + public static final String VERSION = "1.1.5"; - // TODO: Switch from IInventory to IItemHandler (Or don't. It's only useful for automation really.) - // TODO: Triggering of inbuilt Forge events in relevant places? - // TODO: Implement custom events - // TODO: Rearrange the config gui and file + // Constants + /** The amount of mana each magic crystal is worth */ + public static final int MANA_PER_CRYSTAL = 100; + /** The amount of mana each mana flask can hold */ + public static final int MANA_PER_FLASK = 700; + /** The maximum number of one type of wand upgrade which can be applied to a wand. */ + public static final int UPGRADE_STACK_LIMIT = 3; + /** The fraction by which cooldowns are reduced for each level of cooldown upgrade. */ + public static final float COOLDOWN_REDUCTION_PER_LEVEL = 0.15f; + /** The fraction by which maximum charge is increased for each level of storage upgrade. */ + public static final float STORAGE_INCREASE_PER_LEVEL = 0.15f; + /** The fraction by which damage is increased for each tier of matching wand. */ + public static final float DAMAGE_INCREASE_PER_TIER = 0.15f; + /** The fraction by which costs are reduced for each piece of matching armour. Note that changing this value will not + * affect continuous spells, since they are handled differently. */ + public static final float COST_REDUCTION_PER_ARMOUR = 0.2f; + /** The fraction by which spell duration is increased for each level of duration upgrade. */ + public static final float DURATION_INCREASE_PER_LEVEL = 0.25f; + /** The fraction by which spell range is increased for each level of range upgrade. */ + public static final float RANGE_INCREASE_PER_LEVEL = 0.25f; + /** The fraction by which spell blast radius is increased for each level of range upgrade. */ + public static final float BLAST_RADIUS_INCREASE_PER_LEVEL = 0.25f; + /** The fraction by which movement speed is reduced per level of frost effect. */ + public static final double FROST_SLOWNESS_PER_LEVEL = 0.5; + /** The fraction by which movement speed is reduced per level of decay effect. */ + public static final double DECAY_SLOWNESS_PER_LEVEL = 0.2; + /** The fraction by which dig speed is reduced per level of frost effect. */ + public static final float FROST_FATIGUE_PER_LEVEL = 0.45f; + /** The number of ticks between each mana increase for wands with the condenser upgrade. */ + public static final int CONDENSER_TICK_INTERVAL = 50; + /** The amount of mana given for a kill for each level of siphon upgrade. A random amount from 0 to this number - 1 + * is also added. See {@link WizardryEventHandler#onLivingDeathEvent} for more details. */ + public static final int SIPHON_MANA_PER_LEVEL = 3; + /** The number of ticks between the spawning of patches of decay when an entity has the decay effect. + * Note that decay won't spawn again if something is already standing in it. */ + public static final int DECAY_SPREAD_INTERVAL = 8; - // TODO: Have particles obey Minecraft's particle setting where appropriate - // (see https://github.com/RootsTeam/Embers/blob/master/src/main/java/teamroots/embers/particle/ParticleUtil.java) + // Category names + /** The unlocalised name of the spells config category. */ + public static final String SPELLS_CATEGORY = "spells"; + /** The unlocalised name of the ids config category. */ + public static final String IDS_CATEGORY = "ids"; + /** The unlocalised name of the ids config category. */ + public static final String RESISTANCES_CATEGORY = "resistances"; + + // Chest loot + /** The frequency with which spell books will be generated in dungeon chests. Higher numbers are more common. */ + public static final int SPELL_BOOK_FREQUENCY = 20; + /** The frequency with which (basic) wands will be generated in dungeon chests. Higher numbers are more common. */ + public static final int WAND_FREQUENCY = 3; + /** The frequency with which wizard armour will be generated in dungeon chests. Higher numbers are more common. */ + public static final int ARMOUR_FREQUENCY = 6; + /** The frequency with which spell books will be generated in dungeon chests. Higher numbers are more common. */ + public static final int SCROLL_FREQUENCY = 10; + /** The frequency with which armour upgrades will be generated in dungeon chests. Higher numbers are more common. */ + public static final int WAND_UPGRADE_FREQUENCY = 2; + /** The frequency with which spell books will be generated in dungeon chests. Higher numbers are more common. */ + public static final int CRYSTAL_FREQUENCY = 5; + /** The frequency with which apprentice tomes of arcana will be generated in dungeon chests. Higher numbers are more common. */ + public static final int APPRENTICE_TOME_FREQUENCY = 3; + /** The frequency with which advanced tomes of arcana will be generated in dungeon chests. Higher numbers are more common. */ + public static final int ADVANCED_TOME_FREQUENCY = 2; + /** The frequency with which master tomes of arcana will be generated in dungeon chests. Higher numbers are more common. */ + public static final int MASTER_TOME_FREQUENCY = 1; + /** The frequency with which armour upgrades will be generated in dungeon chests. Higher numbers are more common. */ + public static final int ARMOUR_UPGRADE_FREQUENCY = 1; + /** The frequency with which firebombs will be generated in dungeon chests. Higher numbers are more common. */ + public static final int FIREBOMB_FREQUENCY = 4; + /** The frequency with which poison bombs will be generated in dungeon chests. Higher numbers are more common. */ + public static final int POISON_BOMB_FREQUENCY = 4; + /** The frequency with which smoke bombs will be generated in dungeon chests. Higher numbers are more common. */ + public static final int SMOKE_BOMB_FREQUENCY = 4; + /** The frequency with which scrolls of identification will be generated in dungeon chests. Higher numbers are more common. */ + public static final int IDENTIFICATION_SCROLL_FREQUENCY = 3; - // NOTE: Add melee upgrades to loot tables when they are added. + // Global options + /** The rarity of wizard towers, used by the world generator. Larger numbers are rarer. */ + public static int towerRarity = 8; + /** List of dimension ids in which to generate crystal ore. */ + public static int[] oreDimensions = {0}; + /** List of dimension ids in which to generate crystal ore. */ + public static int[] flowerDimensions = {0}; + /** List of dimension ids in which to generate crystal ore. */ + public static int[] towerDimensions = {0}; + /** Chance (out of 200) for mobs to drop spell books. */ + public static int spellBookDropChance = 3; + /** Whether or not wizardry loot should generate in dungeon chests. */ + public static boolean generateLoot = true; + /** Whether or not firebombs should be craftable. */ + public static boolean firebombIsCraftable = true; + /** Whether or not poison bombs should be craftable. */ + public static boolean poisonBombIsCraftable = true; + /** Whether or not poison bombs should be craftable. */ + public static boolean smokeBombIsCraftable = true; + /** Whether to require a magic crystal in the blank scroll crafting recipe (in case it conflicts with another mod). */ + public static boolean useAlternateScrollRecipe = false; + /** Whether or not players can teleport through unbreakable blocks (e.g. bedrock) using the phase step spell. */ + public static boolean teleportThroughUnbreakableBlocks = false; + /** Whether to show summoned creatures' names and owners above their heads. */ + public static boolean showSummonedCreatureNames = true; + /** Whether to allow players to damage their designated allies using magic. */ + public static boolean friendlyFire = true; + /** Whether to allow players to disarm other players using the telekinesis spell. */ + public static boolean telekineticDisarmament = true; + /** When set to true, spells a player hasn't cast yet will be unreadable until they are cast (on a per-world basis). Has no effect when in creative mode. Spells of + * identification will be unobtainable in survival mode if this is false. */ + public static boolean discoveryMode = true; + /** Whether the player can switch between spells on a wand by scrolling with the mouse wheel while sneaking. Note that different players connected to the same server each have their own setting for this. */ + public static boolean enableShiftScrolling = true; + /** Whether summoned creatures can revenge attack their caster if their caster attacks them. */ + public static boolean minionRevengeTargeting = true; + /** Global damage scaling factor for all player magic damage. */ + public static double playerDamageScale = 1.0f; + /** Global damage scaling factor for all npc magic damage. */ + public static double npcDamageScale = 1.0f; + /** The maximum allowed multiplier for the /cast command. This limit is here to stop people from accidentally + * breaking their worlds! */ + public static double maxSpellCommandMultiplier = 20d; + /** List of names of entities which summoned creatures are allowed to attack, in addition to the defaults. */ + public static String[] summonedCreatureTargetsWhitelist = {}; + /** List of names of entities which summoned creatures are specifically not allowed to attack, overriding the defaults and the whitelist. */ + public static String[] summonedCreatureTargetsBlacklist = {"creeper"}; + /** The position of the spell HUD. */ + public static String spellHUDPosition = "Bottom left"; + /** The name of the /cast command. */ + public static String castCommandName = "cast"; + /** The name of the /discoverspell command. */ + public static String discoverspellCommandName = "discoverspell"; + /** The name of the /ally command. */ + public static String allyCommandName = "ally"; + /** The name of the /allies command. */ + public static String alliesCommandName = "allies"; - /** Static instance of the {@link Settings} object for Wizardry. */ - public static final Settings settings = new Settings(); - - /** Static instance of the {@link Logger} object for Wizardry. */ - public static Logger logger; - + // Config ids + /** The id of the frost potion effect. */ + private static int frostPotionID = 31; + /** The id of the fireskin potion effect. */ + private static int transiencePotionID = 32; + /** The id of the fireskin potion effect. */ + private static int fireskinPotionID = 33; + /** The id of the ice shroud potion effect. */ + private static int iceShroudPotionID = 34; + /** The id of the static aura potion effect. */ + private static int staticAuraPotionID = 35; + /** The id of the decay potion effect. */ + private static int decayPotionID = 36; + /** The id of the sixth sense potion effect. */ + private static int sixthSensePotionID = 37; + /** The id of the arcane jammer potion effect. */ + private static int arcaneJammerPotionID = 38; + /** The id of the mind trick potion effect. */ + private static int mindTrickPotionID = 39; + /** The id of the mind control potion effect. */ + private static int mindControlPotionID = 40; + /** The id of the font of mana potion effect. */ + private static int fontOfManaPotionID = 41; + /** The id of the fear potion effect. */ + private static int fearPotionID = 42; + /** The id of the magic sword enchantment. */ + private static int magicSwordEnchantmentID = 100; + /** The id of the magic bow enchantment. */ + private static int magicBowEnchantmentID = 101; + /** The id of the flaming weapon enchantment. */ + private static int flamingWeaponEnchantmentID = 102; + /** The id of the flaming weapon enchantment. */ + private static int freezingWeaponEnchantmentID = 103; + + private static Comparator itemSorter; + private static Comparator spellItemSorter; //private static Pattern entityNamePattern; - - // EventManager - WizardryWorldGenerator generator = new WizardryWorldGenerator(); - // The instance of wizardry that Forge uses. - @Instance(Wizardry.MODID) + // Creative Tabs + public static CreativeTabs tabWizardry = new CreativeTabs("wizardry"){ + @Override + @SideOnly(Side.CLIENT) + public Item getTabIconItem() { + return wizardHandbook; + } + + @Override + @SideOnly(Side.CLIENT) + public void displayAllReleventItems(List items) { + // items is a list of itemstacks, not items! + super.displayAllReleventItems(items); + Collections.sort(items, itemSorter); + } + }; + + public static CreativeTabs tabSpells = new CreativeTabs("wizardryspells"){ + @Override + @SideOnly(Side.CLIENT) + public Item getTabIconItem() { + return spellBook; + } + + @Override + @SideOnly(Side.CLIENT) + public void displayAllReleventItems(List items) { + // items is a list of itemstacks, not items! + super.displayAllReleventItems(items); + Collections.sort(items, spellItemSorter); + } + }; + + /** The wizardry config file */ + public static Configuration config; + + // Anything set to use the material 'air' will not render, even with a TESR! + + // Blocks + public final static Block arcaneWorkbench = new BlockArcaneWorkbench().setHardness(1.0F).setBlockName("arcaneWorkbench").setCreativeTab(tabWizardry); + public final static Block crystalOre = new BlockCrystalOre(Material.rock).setHardness(3.0F).setBlockName("crystalOre").setCreativeTab(tabWizardry).setBlockTextureName("wizardry:crystal_ore"); + public final static Block petrifiedStone = new BlockStatue(Material.rock).setHardness(1.5F).setResistance(10.0F).setBlockName("petrifiedStone").setBlockTextureName("minecraft:stone"); + public final static Block iceStatue = new BlockStatue(Material.ice).setHardness(0.5F).setLightOpacity(3).setStepSound(Block.soundTypeGlass).setBlockName("iceStatue").setBlockTextureName("minecraft:ice"); + public final static Block magicLight = new BlockMagicLight(Material.circuits).setBlockName("magicLight").setBlockTextureName("minecraft:beacon"); + public final static Block crystalFlower = new BlockCrystalFlower(Material.plants).setHardness(0.0F).setBlockName("crystalFlower").setStepSound(Block.soundTypeGrass).setBlockTextureName("wizardry:crystal_flower").setCreativeTab(tabWizardry); + public final static Block snare = new BlockSnare(Material.plants).setHardness(0.0F).setBlockName("snare").setStepSound(Block.soundTypeGrass).setBlockTextureName("wizardry:snare"); + public final static Block transportationStone = new BlockTransportationStone(Material.rock).setHardness(0.0F).setLightLevel(0.5f).setLightOpacity(0).setBlockName("transportationStone").setCreativeTab(tabWizardry).setBlockTextureName("wizardry:transportation_stone"); + public final static Block spectralBlock = new BlockSpectral(Material.glass).setBlockName("spectralBlock").setStepSound(Block.soundTypeGlass).setBlockTextureName("wizardry:spectral_block").setLightLevel(0.7f).setLightOpacity(0).setBlockUnbreakable().setResistance(6000000.0F); + public final static Block crystalBlock = new BlockCrystal(Material.iron).setHardness(5.0F).setResistance(10.0F).setBlockName("crystalBlock").setBlockTextureName("wizardry:crystal_block").setCreativeTab(tabWizardry); + public final static Block meteor = new Block(Material.rock){}.setBlockTextureName("wizardry:meteor").setLightLevel(1); + public final static Block vanishingCobweb = new BlockVanishingCobweb(Material.web).setBlockName("vanishingCobweb").setBlockTextureName("minecraft:web").setLightOpacity(1).setHardness(4.0F); + + // Items + public final static Item magicCrystal = new Item().setTextureName("wizardry:magic_crystal").setUnlocalizedName("magicCrystal").setCreativeTab(tabWizardry); + + public final static Item magicWand = new ItemWand(EnumTier.BASIC, null).setTextureName("wizardry:wand_basic").setUnlocalizedName("magicWand"); + public final static Item apprenticeWand = new ItemWand(EnumTier.APPRENTICE, null).setTextureName("wizardry:wand_apprentice").setUnlocalizedName("apprenticeWand"); + public final static Item advancedWand = new ItemWand(EnumTier.ADVANCED, null).setTextureName("wizardry:wand_advanced").setUnlocalizedName("advancedWand"); + public final static Item masterWand = new ItemWand(EnumTier.MASTER, null).setTextureName("wizardry:wand_master").setUnlocalizedName("masterWand"); + + public final static Item arcaneTome = new ItemArcaneTome(); + public final static Item wizardHandbook = new ItemWizardHandbook(); + public final static Item spellBook = new ItemSpellBook(); + + public final static Item basicFireWand = new ItemWand(EnumTier.BASIC, EnumElement.FIRE).setTextureName("wizardry:wand_basic_fire").setUnlocalizedName("basicFireWand"); + public final static Item basicIceWand = new ItemWand(EnumTier.BASIC, EnumElement.ICE).setTextureName("wizardry:wand_basic_ice").setUnlocalizedName("basicIceWand"); + public final static Item basicLightningWand = new ItemWand(EnumTier.BASIC, EnumElement.LIGHTNING).setTextureName("wizardry:wand_basic_lightning").setUnlocalizedName("basicLightningWand"); + public final static Item basicNecromancyWand = new ItemWand(EnumTier.BASIC, EnumElement.NECROMANCY).setTextureName("wizardry:wand_basic_necromancy").setUnlocalizedName("basicNecromancyWand"); + public final static Item basicEarthWand = new ItemWand(EnumTier.BASIC, EnumElement.EARTH).setTextureName("wizardry:wand_basic_earth").setUnlocalizedName("basicEarthWand"); + public final static Item basicSorceryWand = new ItemWand(EnumTier.BASIC, EnumElement.SORCERY).setTextureName("wizardry:wand_basic_sorcery").setUnlocalizedName("basicSorceryWand"); + public final static Item basicHealingWand = new ItemWand(EnumTier.BASIC, EnumElement.HEALING).setTextureName("wizardry:wand_basic_healing").setUnlocalizedName("basicHealingWand"); + + public final static Item apprenticeFireWand = new ItemWand(EnumTier.APPRENTICE, EnumElement.FIRE).setTextureName("wizardry:wand_apprentice_fire").setUnlocalizedName("apprenticeFireWand"); + public final static Item apprenticeIceWand = new ItemWand(EnumTier.APPRENTICE, EnumElement.ICE).setTextureName("wizardry:wand_apprentice_ice").setUnlocalizedName("apprenticeIceWand"); + public final static Item apprenticeLightningWand = new ItemWand(EnumTier.APPRENTICE, EnumElement.LIGHTNING).setTextureName("wizardry:wand_apprentice_lightning").setUnlocalizedName("apprenticeLightningWand"); + public final static Item apprenticeNecromancyWand = new ItemWand(EnumTier.APPRENTICE, EnumElement.NECROMANCY).setTextureName("wizardry:wand_apprentice_necromancy").setUnlocalizedName("apprenticeNecromancyWand"); + public final static Item apprenticeEarthWand = new ItemWand(EnumTier.APPRENTICE, EnumElement.EARTH).setTextureName("wizardry:wand_apprentice_earth").setUnlocalizedName("apprenticeEarthWand"); + public final static Item apprenticeSorceryWand = new ItemWand(EnumTier.APPRENTICE, EnumElement.SORCERY).setTextureName("wizardry:wand_apprentice_sorcery").setUnlocalizedName("apprenticeSorceryWand"); + public final static Item apprenticeHealingWand = new ItemWand(EnumTier.APPRENTICE, EnumElement.HEALING).setTextureName("wizardry:wand_apprentice_healing").setUnlocalizedName("apprenticeHealingWand"); + + public final static Item advancedFireWand = new ItemWand(EnumTier.ADVANCED, EnumElement.FIRE).setTextureName("wizardry:wand_advanced_fire").setUnlocalizedName("advancedFireWand"); + public final static Item advancedIceWand = new ItemWand(EnumTier.ADVANCED, EnumElement.ICE).setTextureName("wizardry:wand_advanced_ice").setUnlocalizedName("advancedIceWand"); + public final static Item advancedLightningWand = new ItemWand(EnumTier.ADVANCED, EnumElement.LIGHTNING).setTextureName("wizardry:wand_advanced_lightning").setUnlocalizedName("advancedLightningWand"); + public final static Item advancedNecromancyWand = new ItemWand(EnumTier.ADVANCED, EnumElement.NECROMANCY).setTextureName("wizardry:wand_advanced_necromancy").setUnlocalizedName("advancedNecromancyWand"); + public final static Item advancedEarthWand = new ItemWand(EnumTier.ADVANCED, EnumElement.EARTH).setTextureName("wizardry:wand_advanced_earth").setUnlocalizedName("advancedEarthWand"); + public final static Item advancedSorceryWand = new ItemWand(EnumTier.ADVANCED, EnumElement.SORCERY).setTextureName("wizardry:wand_advanced_sorcery").setUnlocalizedName("advancedSorceryWand"); + public final static Item advancedHealingWand = new ItemWand(EnumTier.ADVANCED, EnumElement.HEALING).setTextureName("wizardry:wand_advanced_healing").setUnlocalizedName("advancedHealingWand"); + + public final static Item masterFireWand = new ItemWand(EnumTier.MASTER, EnumElement.FIRE).setTextureName("wizardry:wand_master_fire").setUnlocalizedName("masterFireWand"); + public final static Item masterIceWand = new ItemWand(EnumTier.MASTER, EnumElement.ICE).setTextureName("wizardry:wand_master_ice").setUnlocalizedName("masterIceWand"); + public final static Item masterLightningWand = new ItemWand(EnumTier.MASTER, EnumElement.LIGHTNING).setTextureName("wizardry:wand_master_lightning").setUnlocalizedName("masterLightningWand"); + public final static Item masterNecromancyWand = new ItemWand(EnumTier.MASTER, EnumElement.NECROMANCY).setTextureName("wizardry:wand_master_necromancy").setUnlocalizedName("masterNecromancyWand"); + public final static Item masterEarthWand = new ItemWand(EnumTier.MASTER, EnumElement.EARTH).setTextureName("wizardry:wand_master_earth").setUnlocalizedName("masterEarthWand"); + public final static Item masterSorceryWand = new ItemWand(EnumTier.MASTER, EnumElement.SORCERY).setTextureName("wizardry:wand_master_sorcery").setUnlocalizedName("masterSorceryWand"); + public final static Item masterHealingWand = new ItemWand(EnumTier.MASTER, EnumElement.HEALING).setTextureName("wizardry:wand_master_healing").setUnlocalizedName("masterHealingWand"); + + public final static Item spectralSword = new ItemSpectralSword(ToolMaterial.IRON).setTextureName("wizardry:spectral_sword").setUnlocalizedName("spectralSword"); + public final static Item spectralPickaxe = new ItemSpectralPickaxe(ToolMaterial.IRON).setTextureName("wizardry:spectral_pickaxe").setUnlocalizedName("spectralPickaxe"); + public final static Item spectralBow = new ItemSpectralBow().setUnlocalizedName("spectralBow"); + + public final static Item manaFlask = new Item(){ + @Override + public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer entityplayer){ + entityplayer.triggerAchievement(Wizardry.craftFlask); + } + }.setTextureName("wizardry:mana_flask").setUnlocalizedName("manaFlask").setCreativeTab(tabWizardry); + + public final static Item storageUpgrade = new Item().setTextureName("wizardry:upgrade_storage").setUnlocalizedName("storageUpgrade").setCreativeTab(tabWizardry); + public final static Item siphonUpgrade = new Item().setTextureName("wizardry:upgrade_siphon").setUnlocalizedName("siphonUpgrade").setCreativeTab(tabWizardry); + public final static Item condenserUpgrade = new Item().setTextureName("wizardry:upgrade_condenser").setUnlocalizedName("condenserUpgrade").setCreativeTab(tabWizardry); + public final static Item rangeUpgrade = new Item().setTextureName("wizardry:upgrade_range").setUnlocalizedName("rangeUpgrade").setCreativeTab(tabWizardry); + public final static Item durationUpgrade = new Item().setTextureName("wizardry:upgrade_duration").setUnlocalizedName("durationUpgrade").setCreativeTab(tabWizardry); + public final static Item cooldownUpgrade = new Item().setTextureName("wizardry:upgrade_cooldown").setUnlocalizedName("cooldownUpgrade").setCreativeTab(tabWizardry); + public final static Item blastUpgrade = new Item().setTextureName("wizardry:upgrade_blast").setUnlocalizedName("blastUpgrade").setCreativeTab(tabWizardry); + public final static Item attunementUpgrade = new Item().setTextureName("wizardry:upgrade_attunement").setUnlocalizedName("attunementUpgrade").setCreativeTab(tabWizardry); + + public final static Item magicSilk = new Item().setTextureName("wizardry:magic_silk").setUnlocalizedName("magicSilk").setCreativeTab(tabWizardry); + + public final static Item.ToolMaterial MAGICAL = EnumHelper.addToolMaterial("MAGICAL", 3, 1000, 8.0f, 4.0f, 0); + + public final static Item flamingAxe = new ItemFlamingAxe(Wizardry.MAGICAL).setTextureName("wizardry:flaming_axe").setUnlocalizedName("flamingAxe"); + public final static Item frostAxe = new ItemFrostAxe(Wizardry.MAGICAL).setTextureName("wizardry:frost_axe").setUnlocalizedName("frostAxe"); + + public final static Item firebomb = new ItemFirebomb().setTextureName("wizardry:firebomb").setUnlocalizedName("firebomb"); + public final static Item poisonBomb = new ItemPoisonBomb().setTextureName("wizardry:poison_bomb").setUnlocalizedName("poisonBomb"); + + public final static Item blankScroll = new Item().setTextureName("wizardry:scroll").setUnlocalizedName("blankScroll").setCreativeTab(tabWizardry); + public final static Item scroll = new ItemScroll().setTextureName("wizardry:scroll").setUnlocalizedName("scroll").setCreativeTab(tabSpells); + + // The only way to get these is in dungeon chests (They are legendary, after all. Wizards don't just have them. + // Also if they were sold you could buy four from the same wizard - and that's no fun at all!) + public final static Item armourUpgrade = new ItemArmourUpgrade().setTextureName("wizardry:armour_upgrade").setUnlocalizedName("armourUpgrade"); + + public final static ItemArmor.ArmorMaterial SILK = EnumHelper.addArmorMaterial("SILK", 15, new int[]{2, 5, 4, 2}, 0); + + // Saw a post somewhere that said you have to put these in the init methods rather than defining them as constants. + // I *think* that's because the post was for a newer Minecraft version, where custom armour has its own renderer or + // something, meaning it would be done a lot like the entity rendering registry in ClientProxy. This is all working + // fine it seems, so I'm not going to fiddle with it, but it might be useful to know if I update versions again. + public final static Item wizardHat = new ItemWizardArmour(Wizardry.SILK, 1, 0, null); + public final static Item wizardRobe = new ItemWizardArmour(Wizardry.SILK, 1, 1, null); + public final static Item wizardLeggings = new ItemWizardArmour(Wizardry.SILK, 1, 2, null); + public final static Item wizardBoots = new ItemWizardArmour(Wizardry.SILK, 1, 3, null); + + public final static Item wizardHatFire = new ItemWizardArmour(Wizardry.SILK, 1, 0, EnumElement.FIRE); + public final static Item wizardRobeFire = new ItemWizardArmour(Wizardry.SILK, 1, 1, EnumElement.FIRE); + public final static Item wizardLeggingsFire = new ItemWizardArmour(Wizardry.SILK, 1, 2, EnumElement.FIRE); + public final static Item wizardBootsFire = new ItemWizardArmour(Wizardry.SILK, 1, 3, EnumElement.FIRE); + + public final static Item wizardHatIce = new ItemWizardArmour(Wizardry.SILK, 1, 0, EnumElement.ICE); + public final static Item wizardRobeIce = new ItemWizardArmour(Wizardry.SILK, 1, 1, EnumElement.ICE); + public final static Item wizardLeggingsIce = new ItemWizardArmour(Wizardry.SILK, 1, 2, EnumElement.ICE); + public final static Item wizardBootsIce = new ItemWizardArmour(Wizardry.SILK, 1, 3, EnumElement.ICE); + + public final static Item wizardHatLightning = new ItemWizardArmour(Wizardry.SILK, 1, 0, EnumElement.LIGHTNING); + public final static Item wizardRobeLightning = new ItemWizardArmour(Wizardry.SILK, 1, 1, EnumElement.LIGHTNING); + public final static Item wizardLeggingsLightning = new ItemWizardArmour(Wizardry.SILK, 1, 2, EnumElement.LIGHTNING); + public final static Item wizardBootsLightning = new ItemWizardArmour(Wizardry.SILK, 1, 3, EnumElement.LIGHTNING); + + public final static Item wizardHatNecromancy = new ItemWizardArmour(Wizardry.SILK, 1, 0, EnumElement.NECROMANCY); + public final static Item wizardRobeNecromancy = new ItemWizardArmour(Wizardry.SILK, 1, 1, EnumElement.NECROMANCY); + public final static Item wizardLeggingsNecromancy = new ItemWizardArmour(Wizardry.SILK, 1, 2, EnumElement.NECROMANCY); + public final static Item wizardBootsNecromancy = new ItemWizardArmour(Wizardry.SILK, 1, 3, EnumElement.NECROMANCY); + + public final static Item wizardHatEarth = new ItemWizardArmour(Wizardry.SILK, 1, 0, EnumElement.EARTH); + public final static Item wizardRobeEarth = new ItemWizardArmour(Wizardry.SILK, 1, 1, EnumElement.EARTH); + public final static Item wizardLeggingsEarth = new ItemWizardArmour(Wizardry.SILK, 1, 2, EnumElement.EARTH); + public final static Item wizardBootsEarth = new ItemWizardArmour(Wizardry.SILK, 1, 3, EnumElement.EARTH); + + public final static Item wizardHatSorcery = new ItemWizardArmour(Wizardry.SILK, 1, 0, EnumElement.SORCERY); + public final static Item wizardRobeSorcery = new ItemWizardArmour(Wizardry.SILK, 1, 1, EnumElement.SORCERY); + public final static Item wizardLeggingsSorcery = new ItemWizardArmour(Wizardry.SILK, 1, 2, EnumElement.SORCERY); + public final static Item wizardBootsSorcery = new ItemWizardArmour(Wizardry.SILK, 1, 3, EnumElement.SORCERY); + + public final static Item wizardHatHealing = new ItemWizardArmour(Wizardry.SILK, 1, 0, EnumElement.HEALING); + public final static Item wizardRobeHealing = new ItemWizardArmour(Wizardry.SILK, 1, 1, EnumElement.HEALING); + public final static Item wizardLeggingsHealing = new ItemWizardArmour(Wizardry.SILK, 1, 2, EnumElement.HEALING); + public final static Item wizardBootsHealing = new ItemWizardArmour(Wizardry.SILK, 1, 3, EnumElement.HEALING); + + public final static Item spawnWizard = new ItemSpawnWizard().setUnlocalizedName("spawn_wizard"); + + public final static Item spectralHelmet = new ItemSpectralArmour(ItemArmor.ArmorMaterial.IRON, 1, 0).setTextureName("wizardry:spectral_helmet").setUnlocalizedName("spectral_helmet"); + public final static Item spectralChestplate = new ItemSpectralArmour(ItemArmor.ArmorMaterial.IRON, 1, 1).setTextureName("wizardry:spectral_chestplate").setUnlocalizedName("spectral_chestplate"); + public final static Item spectralLeggings = new ItemSpectralArmour(ItemArmor.ArmorMaterial.IRON, 1, 2).setTextureName("wizardry:spectral_leggings").setUnlocalizedName("spectral_leggings"); + public final static Item spectralBoots = new ItemSpectralArmour(ItemArmor.ArmorMaterial.IRON, 1, 3).setTextureName("wizardry:spectral_boots").setUnlocalizedName("spectral_boots"); + + public final static Item smokeBomb = new ItemSmokeBomb().setTextureName("wizardry:smoke_bomb").setUnlocalizedName("smoke_bomb"); + + public final static Item identificationScroll = new ItemIdentificationScroll(); + + // Potion Effects + public static Potion frost; + public static Potion transience; + public static Potion fireskin; + public static Potion iceShroud; + public static Potion staticAura; + public static Potion decay; + public static Potion sixthSense; + public static Potion arcaneJammer; + public static Potion mindTrick; + public static Potion mindControl; + public static Potion fontOfMana; + public static Potion fear; + + // Enchantments + public static Enchantment magicSword; + public static Enchantment magicBow; + public static Enchantment flamingWeapon; + public static Enchantment freezingWeapon; + + // Achievements + public static final Achievement crystal = new Achievement("crystal", "Crystal", -1, -1, magicCrystal, null).registerStat(); + public static final Achievement arcaneInitiate = new Achievement("arcaneInitiate", "ArcaneInitiate", 2, -1, magicWand, crystal).registerStat(); + public static final Achievement apprentice = new Achievement("apprentice", "Apprentice", 2, 3, apprenticeWand, arcaneInitiate).registerStat(); + public static final Achievement master = new Achievement("master", "Master", 3, 6, masterWand, apprentice).registerStat(); + public static final Achievement allSpells = new Achievement("allSpells", "AllSpells", 5, 7, wizardHandbook, master).registerStat().setSpecial(); + public static final Achievement wizardTrade = new Achievement("wizardTrade", "WizardTrade", 2, -5, Items.emerald, arcaneInitiate).registerStat(); + public static final Achievement buyMasterSpell = new Achievement("buyMasterSpell", "BuyMasterSpell", 5, -5, spellBook, wizardTrade).registerStat().setSpecial(); + public static final Achievement freezeBlaze = new Achievement("freezeBlaze", "FreezeBlaze", -1, 3, Blocks.ice, apprentice).registerStat(); + public static final Achievement chargeCreeper = new Achievement("chargeCreeper", "ChargeCreeper", -1, 1, Items.gunpowder, arcaneInitiate).registerStat(); + public static final Achievement frankenstein = new Achievement("frankenstein", "Frankenstein", -3, 1, advancedLightningWand, chargeCreeper).registerStat().setSpecial(); + public static final Achievement specialUpgrade = new Achievement("specialUpgrade", "SpecialUpgrade", 4, 1, condenserUpgrade, arcaneInitiate).registerStat(); + public static final Achievement craftFlask = new Achievement("craftFlask", "CraftFlask", 4, -2, manaFlask, arcaneInitiate).registerStat(); + public static final Achievement elemental = new Achievement("elemental", "Elemental", 6, -1, basicFireWand, arcaneInitiate).registerStat(); + public static final Achievement armourSet = new Achievement("armourSet", "ArmourSet", 0, -4, wizardHat, arcaneInitiate).registerStat(); + public static final Achievement legendary = new Achievement("legendary", "Legendary", -2, -5, armourUpgrade, armourSet).registerStat().setSpecial(); + public static final Achievement selfDestruct = new Achievement("selfDestruct", "SelfDestruct", 1, 0, Blocks.pumpkin, arcaneInitiate).registerStat(); + public static final Achievement pigTornado = new Achievement("pigTornado", "PigTornado", 6, 3, Items.saddle, apprentice).registerStat().setSpecial(); + public static final Achievement jamWizard = new Achievement("jamWizard", "JamWizard", 4, 4, Blocks.web, apprentice).registerStat(); + public static final Achievement slimeSkeleton = new Achievement("slimeSkeleton", "SlimeSkeleton", 1, 5, Items.slime_ball, apprentice).registerStat(); + public static final Achievement angerWizard = new Achievement("angerWizard", "AngerWizard", 1, -7, Items.iron_sword, wizardTrade).registerStat(); + public static final Achievement defeatEvilWizard = new Achievement("defeatEvilWizard", "DefeatEvilWizard", 4, -7, wizardBootsNecromancy, wizardTrade).registerStat(); + public static final Achievement maxOutWand = new Achievement("maxOutWand", "MaxOutWand", 7, 1, arcaneTome, specialUpgrade).registerStat().setSpecial(); + public static final Achievement elementMaster = new Achievement("elementMaster", "ElementMaster", 7, -3, masterIceWand, elemental).registerStat().setSpecial(); + public static final Achievement identifySpell = new Achievement("identifySpell", "IdentifySpell", -2, -3, identificationScroll, arcaneInitiate).registerStat(); + + private static final Achievement[] achievementsList = {crystal, arcaneInitiate, apprentice, master, allSpells, wizardTrade, buyMasterSpell, freezeBlaze, chargeCreeper, + frankenstein, specialUpgrade, craftFlask, elemental, armourSet, legendary, selfDestruct, pigTornado, jamWizard, slimeSkeleton, angerWizard, defeatEvilWizard, + maxOutWand, elementMaster, identifySpell}; + public static final AchievementPage wizardryAchievementTab = new AchievementPage("Wizardry", achievementsList); + + // EventManager + WizardryWorldGenerator oreManager = new WizardryWorldGenerator(); + + // The instance of your mod that Forge uses. + @Instance(value = Wizardry.MODID) public static Wizardry instance; - // Location of the proxy code, used by Forge. + // Says where the client and server 'proxy' code is loaded. @SidedProxy(clientSide="electroblob.wizardry.client.ClientProxy", serverSide="electroblob.wizardry.CommonProxy") public static CommonProxy proxy; @EventHandler public void preInit(FMLPreInitializationEvent event){ - logger = event.getModLog(); - - // The array in question no longer exists, so I'm pretty sure this isn't necessary any more. - // expandPotionTypesArray(); + expandPotionTypesArray(); - settings.initConfig(event); - - // Yes - by the looks of it, having an interface is completely unnecessary in this case. - CapabilityManager.INSTANCE.register(WizardData.class, new IStorage(){ - // These methods are only called by Capability.writeNBT() or Capability.readNBT(), which in turn are - // NEVER CALLED. Unless I'm missing some reflective invocation, that means this entire class serves only - // to allow capabilities to be saved and loaded manually. What that would be useful for I don't know. - // (If an API forces most users to write redundant code for no reason, it's not user friendly, is it?) - // ... well, that's my rant for today! - @Override public NBTBase writeNBT(Capability capability, WizardData instance, EnumFacing side){ return null; } - @Override public void readNBT(Capability capability, WizardData instance, EnumFacing side, NBTBase nbt){} - }, WizardData.class); + // Config file + + /* The first part of the config file has to be done here (as is conventional) so that the various registries + * can change what they do accordingly. The spell part of the config has to be done in the init method. */ + + config = new Configuration(event.getSuggestedConfigurationFile()); + + config.load(); + + setupGeneralConfig(); + + config.save(); + + WizardryRegistry.registerBlocks(); + + WizardryRegistry.registerItems(); WizardryRegistry.registerTileEntities(); WizardryRegistry.registerEntities(this); + + WizardryRegistry.registerSpells(); // The check for the generateLoot setting is now done within this method. WizardryRegistry.registerLoot(); + + // Potion effects + frost = new PotionFrost(frostPotionID, true, 0x38ddec); + transience = new PotionMagicEffect(transiencePotionID, false, 0xffe89b, 0).setPotionName("potion.transience"); + fireskin = new PotionMagicEffect(fireskinPotionID, false, 0xff2f02, 1).setPotionName("potion.fireskin"); + iceShroud = new PotionMagicEffect(iceShroudPotionID, false, 0x52f1ff, 2).setPotionName("potion.ice_shroud"); + staticAura = new PotionMagicEffect(staticAuraPotionID, false, 0x0070ff, 3).setPotionName("potion.static_aura"); + decay = new PotionDecay(decayPotionID, true, 0x3c006c); + sixthSense = new PotionMagicEffect(sixthSensePotionID, false, 0xc6ff01, 4).setPotionName("potion.sixth_sense"); + arcaneJammer = new PotionMagicEffect(arcaneJammerPotionID, false, 0xcf4aa2, 5).setPotionName("potion.arcane_jammer"); + mindTrick = new PotionMagicEffect(mindTrickPotionID, true, 0x601683, 6).setPotionName("potion.mind_trick"); + mindControl = new PotionMagicEffect(mindControlPotionID, true, 0x320b44, 7).setPotionName("potion.mind_control"); + fontOfMana = new PotionMagicEffect(fontOfManaPotionID, false, 0xffe5bb, 8).setPotionName("potion.font_of_mana"); + fear = new PotionMagicEffect(fearPotionID, true, 0xbd0100, 9).setPotionName("potion.fear"); + + // Enchantments + magicSword = new EnchantmentMagicSword(magicSwordEnchantmentID); + magicBow = new EnchantmentTimed(magicBowEnchantmentID).setName("magic_bow"); + flamingWeapon = new EnchantmentTimed(flamingWeaponEnchantmentID).setName("flaming_weapon"); + freezingWeapon = new EnchantmentTimed(freezingWeaponEnchantmentID).setName("freezing_weapon"); - // NOTE: Will need to be moved to init for 1.12, as will anything that needs to be after the registry events. - WizardryTabs.sort(); + // Creative tab sorter + + List orderedItemList = Arrays.asList( + + Item.getItemFromBlock(arcaneWorkbench), + Item.getItemFromBlock(crystalOre), + Item.getItemFromBlock(crystalBlock), + Item.getItemFromBlock(crystalFlower), + Item.getItemFromBlock(transportationStone), + magicCrystal, magicWand, apprenticeWand, advancedWand, masterWand, arcaneTome, wizardHandbook, spawnWizard, + basicFireWand, basicIceWand, basicLightningWand, basicNecromancyWand, basicEarthWand, basicSorceryWand, basicHealingWand, + smokeBomb, firebomb, poisonBomb, blankScroll, identificationScroll, manaFlask, storageUpgrade, siphonUpgrade, + condenserUpgrade, rangeUpgrade, durationUpgrade, cooldownUpgrade, blastUpgrade, attunementUpgrade, magicSilk, armourUpgrade, + wizardHat, wizardRobe, wizardLeggings, wizardBoots, + wizardHatFire, wizardRobeFire, wizardLeggingsFire, wizardBootsFire, + wizardHatIce, wizardRobeIce, wizardLeggingsIce, wizardBootsIce, + wizardHatLightning, wizardRobeLightning, wizardLeggingsLightning, wizardBootsLightning, + wizardHatNecromancy, wizardRobeNecromancy, wizardLeggingsNecromancy, wizardBootsNecromancy, + wizardHatEarth, wizardRobeEarth, wizardLeggingsEarth, wizardBootsEarth, + wizardHatSorcery, wizardRobeSorcery, wizardLeggingsSorcery, wizardBootsSorcery, + wizardHatHealing, wizardRobeHealing, wizardLeggingsHealing, wizardBootsHealing + + ); + + itemSorter = Ordering.explicit(orderedItemList).onResultOf(new Function() { + @Override + public Item apply(ItemStack input) { + return input.getItem(); + } + }); - // Moved to preInit, because apparently it has to be here now. - proxy.registerRenderers(); - // It seems this also has to be here - proxy.registerKeyBindings(); + spellItemSorter = new Comparator(){ + @Override + public int compare(ItemStack stack1, ItemStack stack2) { + + if((stack1.getItem() instanceof ItemSpellBook && stack2.getItem() instanceof ItemSpellBook) + || (stack1.getItem() instanceof ItemScroll && stack2.getItem() instanceof ItemScroll)){ + + Spell spell1 = Spell.get(stack1.getItemDamage()); + Spell spell2 = Spell.get(stack2.getItemDamage()); + + return spell1.compareTo(spell2); + + }else if(stack1.getItem() instanceof ItemScroll){ + return 1; + }else if(stack2.getItem() instanceof ItemScroll){ + return -1; + } + return 0; + } + }; } @EventHandler public void init(FMLInitializationEvent event){ - settings.initConfigExtras(); + // Spell config (this has to be here and not in preInit because all spells must be registered before it is + // added, including those in other mods.) + + //config.load(); + + setupSpellsConfig(); + + config.save(); + + proxy.registerKeyBindings(); // Event Handlers - GameRegistry.registerWorldGenerator(generator, 0); - MinecraftForge.EVENT_BUS.register(new WizardryKeyHandler()); - MinecraftForge.EVENT_BUS.register(instance); - proxy.registerSpellHUD(); // This can't easily be converted to use the new @Mod.EventBusSubscriber system + GameRegistry.registerWorldGenerator(oreManager, 0); + FMLCommonHandler.instance().bus().register(new WizardryKeyHandler()); + FMLCommonHandler.instance().bus().register(instance); + proxy.registerEventHandlers(); + proxy.registerSpellHUD(); NetworkRegistry.INSTANCE.registerGuiHandler(this, new WizardryGuiHandler()); WizardryPacketHandler.initPackets(); // Achievements - AchievementPage.registerAchievementPage(WizardryAchievements.WIZARDRY_ACHIEVEMENT_PAGE); + AchievementPage.registerAchievementPage(wizardryAchievementTab); - // Recipes WizardryRegistry.registerRecipes(); - - proxy.initMixedFontRenderer(); + + proxy.registerRenderers(); } @EventHandler public void postInit(FMLPostInitializationEvent event){ + // To ensure backwards compatibility, the spell books and scrolls themselves are now sorted in the creative tab, + // and the spells are left in whatever order they were registered. + //Spell.sortSpells(); // This needs to be here or it won't necessarily include all the mods' entities. - // TODO: Re-implement this when the Forge bug is fixed. /* Doesn't seem to be doing anything... String entityNames = ""; for(Object name : EntityList.classToStringMapping.values()){ @@ -179,7 +671,6 @@ public class Wizardry { entityNames = entityNames.substring(0, entityNames.length()-1); entityNamePattern = Pattern.compile(entityNames); */ - proxy.initialiseLayers(); } @EventHandler @@ -191,71 +682,399 @@ public class Wizardry { } @SubscribeEvent - public void onConfigChanged(net.minecraftforge.fml.client.event.ConfigChangedEvent.OnConfigChangedEvent event){ - if(event.getModID().equals(Wizardry.MODID)){ - settings.saveConfigChanges(); - // All of the synchronised settings require a world restart anyway so this doesn't need syncing. - } + public void onConfigChanged(ConfigChangedEvent.OnConfigChangedEvent eventArgs){ + if(eventArgs.modID.equals(Wizardry.MODID)) Wizardry.syncConfig(); } - // 2.1 changed some item ids, so this fixes them for existing worlds - // NOTE: Needs changing to RegistryEvent.MissingMapping in 1.12, or just removing since nobody updates minecraft - // versions when using mods. - @EventHandler - public static void onMissingMappingEvent(FMLMissingMappingsEvent event){ - // Just get, not getAll, since the mod id didn't change! - for(FMLMissingMappingsEvent.MissingMapping mapping : event.get()){ - if(mapping.type == Type.ITEM && mapping.resourceLocation.getResourceDomain().equals(Wizardry.MODID)){ - - Item replacement = null; - - switch(mapping.resourceLocation.getResourcePath()){ - - case "wand_basic": replacement = WizardryItems.magic_wand; break; - case "wand_basic_fire": replacement = WizardryItems.basic_fire_wand; break; - case "wand_basic_ice": replacement = WizardryItems.basic_ice_wand; break; - case "wand_basic_lightning": replacement = WizardryItems.basic_lightning_wand; break; - case "wand_basic_necromancy": replacement = WizardryItems.basic_necromancy_wand; break; - case "wand_basic_earth": replacement = WizardryItems.basic_earth_wand; break; - case "wand_basic_sorcery": replacement = WizardryItems.basic_sorcery_wand; break; - case "wand_basic_healing": replacement = WizardryItems.basic_healing_wand; break; - case "wand_apprentice": replacement = WizardryItems.apprentice_wand; break; - case "wand_apprentice_fire": replacement = WizardryItems.apprentice_fire_wand; break; - case "wand_apprentice_ice": replacement = WizardryItems.apprentice_ice_wand; break; - case "wand_apprentice_lightning": replacement = WizardryItems.apprentice_lightning_wand; break; - case "wand_apprentice_necromancy": replacement = WizardryItems.apprentice_necromancy_wand; break; - case "wand_apprentice_earth": replacement = WizardryItems.apprentice_earth_wand; break; - case "wand_apprentice_sorcery": replacement = WizardryItems.apprentice_sorcery_wand; break; - case "wand_apprentice_healing": replacement = WizardryItems.apprentice_healing_wand; break; - case "wand_advanced": replacement = WizardryItems.advanced_wand; break; - case "wand_advanced_fire": replacement = WizardryItems.advanced_fire_wand; break; - case "wand_advanced_ice": replacement = WizardryItems.advanced_ice_wand; break; - case "wand_advanced_lightning": replacement = WizardryItems.advanced_lightning_wand; break; - case "wand_advanced_necromancy": replacement = WizardryItems.advanced_necromancy_wand; break; - case "wand_advanced_earth": replacement = WizardryItems.advanced_earth_wand; break; - case "wand_advanced_sorcery": replacement = WizardryItems.advanced_sorcery_wand; break; - case "wand_advanced_healing": replacement = WizardryItems.advanced_healing_wand; break; - case "wand_master": replacement = WizardryItems.master_wand; break; - case "wand_master_fire": replacement = WizardryItems.master_fire_wand; break; - case "wand_master_ice": replacement = WizardryItems.master_ice_wand; break; - case "wand_master_lightning": replacement = WizardryItems.master_lightning_wand; break; - case "wand_master_necromancy": replacement = WizardryItems.master_necromancy_wand; break; - case "wand_master_earth": replacement = WizardryItems.master_earth_wand; break; - case "wand_master_sorcery": replacement = WizardryItems.master_sorcery_wand; break; - case "wand_master_healing": replacement = WizardryItems.master_healing_wand; break; - case "upgrade_storage": replacement = WizardryItems.storage_upgrade; break; - case "upgrade_siphon": replacement = WizardryItems.siphon_upgrade; break; - case "upgrade_condenser": replacement = WizardryItems.condenser_upgrade; break; - case "upgrade_range": replacement = WizardryItems.range_upgrade; break; - case "upgrade_duration": replacement = WizardryItems.duration_upgrade; break; - case "upgrade_cooldown": replacement = WizardryItems.cooldown_upgrade; break; - case "upgrade_blast": replacement = WizardryItems.blast_upgrade; break; - case "upgrade_attunement": replacement = WizardryItems.attunement_upgrade; break; - // If it didn't match any of the ones that changed, do nothing. - default: return; + /** Call to sync the config file after it has been edited in game from the menus. */ + public static void syncConfig(){ + + setupGeneralConfig(); + + setupSpellsConfig(); + + config.save(); + + } + + // As of wizardry 1.1, all keys used in the config file itself are now hardcoded, not localised. The localisations + // are done in the config GUI. The config file has to be written in one language or it will end up with multiple + // options for different languages. + + private static void setupSpellsConfig(){ + + config.addCustomCategoryComment(Wizardry.SPELLS_CATEGORY, "Set a spell to false to disable it. Disabled spells will still have their associated spell book (mainly so the spell books don't all change) and can still be bound to wands, but cannot be cast in game, will not appear in any subsequently generated chests or wizard trades and will not drop from mobs. Disable a spell if it is causing problems, conflicts with another mod or creates an unintended exploit."); + + Property property; + + for(Spell spell : Spell.getSpells(Spell.allSpells)){ + property = config.get(Wizardry.SPELLS_CATEGORY, spell.getUnlocalisedName(), true, spell.getDescription()); + property.setLanguageKey("spell." + spell.getUnlocalisedName()); + spell.setEnabled(property.getBoolean()); + } + + } + + private static void setupGeneralConfig(){ + + // This trick is borrowed from forge; it sorts the config options into the order you want them. + List propOrder = new ArrayList(); + + Property property; + + config.addCustomCategoryComment(config.CATEGORY_GENERAL, "Please note that changing some of these settings may make the mod very difficult to play."); + + property = config.get(config.CATEGORY_GENERAL, "towerRarity", 8, "Rarity of wizard towers. Higher numbers are rarer. Set to 0 to disable wizard towers completely.", 0, 50); + property.setLanguageKey("config.tower_rarity"); + property.setRequiresWorldRestart(true); + Wizardry.proxy.setToNumberSliderEntry(property); + towerRarity = property.getInt(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "spellBookDropChance", 3, "The chance for mobs to drop a spell book when killed. The greater this number, the more often they will drop. Set to 0 to disable spell book drops. Set to 200 for guaranteed drops.", 0, 200); + property.setLanguageKey("config.spell_book_drop_chance"); + Wizardry.proxy.setToNumberSliderEntry(property); + spellBookDropChance = property.getInt(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "oreDimensions", oreDimensions, "List of dimension ids in which crystal ore will generate. Note that removing the overworld (id 0) from this list will make the mod VERY difficult to play!"); + property.setLanguageKey("config.ore_dimensions"); + property.setRequiresWorldRestart(true); + oreDimensions = property.getIntList(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "flowerDimensions", flowerDimensions, "List of dimension ids in which crystal flowers will generate."); + property.setLanguageKey("config.flower_dimensions"); + property.setRequiresWorldRestart(true); + flowerDimensions = property.getIntList(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "towerDimensions", towerDimensions, "List of dimension ids in which wizard towers will generate."); + property.setLanguageKey("config.tower_dimensions"); + property.setRequiresWorldRestart(true); + towerDimensions = property.getIntList(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "generateLoot", true, "Whether to generate wizardry loot in dungeon chests."); + property.setLanguageKey("config.generate_loot"); + property.setRequiresWorldRestart(true); + generateLoot = property.getBoolean(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "firebombIsCraftable", true, "Whether firebombs can be crafted or not."); + property.setLanguageKey("config.firebomb_is_craftable"); + property.setRequiresMcRestart(true); + firebombIsCraftable = property.getBoolean(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "poisonBombIsCraftable", true, "Whether poison bombs can be crafted or not."); + property.setLanguageKey("config.poison_bomb_is_craftable"); + property.setRequiresMcRestart(true); + poisonBombIsCraftable = property.getBoolean(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "smokeBombIsCraftable", true, "Whether smoke bombs can be crafted or not."); + property.setLanguageKey("config.smoke_bomb_is_craftable"); + property.setRequiresMcRestart(true); + smokeBombIsCraftable = property.getBoolean(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "useAlternateScrollRecipe", false, "Whether to require a magic crystal in the shapeless crafting recipe for blank scrolls. Set to true if another mod adds a conflicting recipe."); + property.setLanguageKey("config.use_alternate_scroll_recipe"); + property.setRequiresMcRestart(true); + useAlternateScrollRecipe = property.getBoolean(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "teleportThroughUnbreakableBlocks", false, "Whether players are allowed to teleport through unbreakable blocks (e.g. bedrock) using the phase step spell."); + property.setLanguageKey("config.teleport_through_unbreakable_blocks"); + teleportThroughUnbreakableBlocks = property.getBoolean(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "showSummonedCreatureNames", true, "Whether to show summoned creatures' names and owners above their heads."); + property.setLanguageKey("config.show_summoned_creature_names"); + showSummonedCreatureNames = property.getBoolean(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "friendlyFire", true, "Whether to allow players to damage their designated allies using magic."); + property.setLanguageKey("config.friendly_fire"); + friendlyFire = property.getBoolean(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "telekineticDisarmament", true, "Whether to allow players to disarm other players using the telekinesis spell. Set to false to prevent stealing of items."); + property.setLanguageKey("config.telekinetic_disarmament"); + telekineticDisarmament = property.getBoolean(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "discoveryMode", true, "For those who like a sense of mystery! When set to true, spells you haven't cast yet will be unreadable until you cast them (on a per-world basis). Has no effect when in creative mode. Spells of identification will be unobtainable in survival mode if this is false."); + property.setLanguageKey("config.discovery_mode"); + property.setRequiresWorldRestart(true); + discoveryMode = property.getBoolean(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "enableShiftScrolling", true, "Whether you can switch between spells on a wand by scrolling with the mouse wheel while sneaking. Note that this will only affect you; other players connected to the same server obey their own settings."); + property.setLanguageKey("config.enable_shift_scrolling"); + property.setRequiresWorldRestart(false); + enableShiftScrolling = property.getBoolean(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "minionRevengeTargeting", true, "Whether summoned creatures can revenge attack their owner if their owner attacks them."); + property.setLanguageKey("config.minion_revenge_targeting"); + property.setRequiresWorldRestart(false); + minionRevengeTargeting = property.getBoolean(); + propOrder.add(property.getName()); + + // These two aren't sliders because using a slider makes it difficult to fine-tune the numbers; the nature of a + // scaling factor means that 0.5 is as big a change as 2.0, so whilst a slider is fine for increasing the damage, + // it doesn't give fine enough control for values less than 1. + property = config.get(config.CATEGORY_GENERAL, "playerDamageScaling", 1.0, "Global damage scaling factor for the damage dealt by players casting spells, relative to 1.", 0, 20); + property.setLanguageKey("config.player_damage_scaling"); + playerDamageScale = property.getDouble(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "npcDamageScaling", 1.0, "Global damage scaling factor for the damage dealt by NPCs casting spells, relative to 1.", 0, 20); + property.setLanguageKey("config.npc_damage_scaling"); + npcDamageScale = property.getDouble(); + propOrder.add(property.getName()); + + // This one isn't a slider either because people are likely to want exact values ("it must be at most 50.3" is a bit strange!). + property = config.get(config.CATEGORY_GENERAL, "castCommandMultiplierLimit", 20.0, "Upper limit for the multipliers passed into the /cast command. This is here to stop players from accidentally breaking a world/server. Large blast mutipliers can cause extreme lag - you have been warned!", 1, 255); + property.setLanguageKey("config.cast_command_multiplier_limit"); + maxSpellCommandMultiplier = property.getDouble(); + propOrder.add(property.getName()); + + property = config.get(config.CATEGORY_GENERAL, "summonedCreatureTargetsWhitelist", summonedCreatureTargetsWhitelist, "List of names of entities which summoned creatures and wizards are allowed to attack, in addition to the defaults. Add mod creatures to this list if you want summoned creatures to attack them and they aren't already doing so. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard)."); + property.setLanguageKey("config.summoned_creature_targets_whitelist"); + property.setRequiresWorldRestart(true); + summonedCreatureTargetsWhitelist = property.getStringList(); + // Converts all strings in the list to lower case, to ignore case sensitivity, and trims them. + for(int i=0; i propOrder1 = new ArrayList(); + + config.addCustomCategoryComment(Wizardry.RESISTANCES_CATEGORY, "These options allow entities to be made immune to certain types of magic."); + + property = config.get(Wizardry.RESISTANCES_CATEGORY, "mobsImmuneToFire", new String[]{}, "List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard)."); + property.setLanguageKey("config.mobs_immune_to_fire"); + property.setRequiresMcRestart(true); + // Converts all strings in the list to lower case, to ignore case sensitivity, and trims them. + for(int i=0; i)EntityList.stringToClassMapping.get(property.getStringList()[i]), DamageType.FIRE); + } + propOrder1.add(property.getName()); + + property = config.get(Wizardry.RESISTANCES_CATEGORY, "mobsImmuneToIce", new String[]{}, "List of names of entities that are immune to ice, in addition to the defaults. Add mod creatures to this list if you want them to be immune to ice magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard)."); + property.setLanguageKey("config.mobs_immune_to_ice"); + property.setRequiresMcRestart(true); + // Converts all strings in the list to lower case, to ignore case sensitivity, and trims them. + for(int i=0; i)EntityList.stringToClassMapping.get(property.getStringList()[i]), DamageType.FROST); + } + propOrder1.add(property.getName()); + + property = config.get(Wizardry.RESISTANCES_CATEGORY, "mobsImmuneToLightning", new String[]{}, "List of names of entities that are immune to lightning, in addition to the defaults. Add mod creatures to this list if you want them to be immune to lightning magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard)."); + property.setLanguageKey("config.mobs_immune_to_lightning"); + property.setRequiresMcRestart(true); + // Converts all strings in the list to lower case, to ignore case sensitivity, and trims them. + for(int i=0; i)EntityList.stringToClassMapping.get(property.getStringList()[i]), DamageType.SHOCK); + } + propOrder1.add(property.getName()); + + property = config.get(Wizardry.RESISTANCES_CATEGORY, "mobsImmuneToWither", new String[]{}, "List of names of entities that are immune to wither effects, in addition to the defaults. Add mod creatures to this list if you want them to be immune to withering magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard)."); + property.setLanguageKey("config.mobs_immune_to_wither"); + property.setRequiresMcRestart(true); + // Converts all strings in the list to lower case, to ignore case sensitivity, and trims them. + for(int i=0; i)EntityList.stringToClassMapping.get(property.getStringList()[i]), DamageType.WITHER); + } + propOrder1.add(property.getName()); + + property = config.get(Wizardry.RESISTANCES_CATEGORY, "mobsImmuneToPoison", new String[]{}, "List of names of entities that are immune to poison, in addition to the defaults. Add mod creatures to this list if you want them to be immune to poison magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard)."); + property.setLanguageKey("config.mobs_immune_to_poison"); + property.setRequiresMcRestart(true); + // Converts all strings in the list to lower case, to ignore case sensitivity, and trims them. + for(int i=0; i)EntityList.stringToClassMapping.get(property.getStringList()[i]), DamageType.POISON); + } + propOrder1.add(property.getName()); + + config.setCategoryPropertyOrder(Wizardry.RESISTANCES_CATEGORY, propOrder1); + + // IDs + + List propOrder2 = new ArrayList(); + + config.addCustomCategoryComment(Wizardry.IDS_CATEGORY, "Change these IDs if they conflict with another mod."); + + property = config.get(Wizardry.IDS_CATEGORY, "frostPotionID", 31, "The ID of the frost potion effect. Change if this conflicts with another mod.", 24, 255); + property.setLanguageKey("config.frost_potion_id"); + property.setRequiresMcRestart(true); + frostPotionID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "transiencePotionID", 32, "The ID of the transience potion effect. Change if this conflicts with another mod.", 24, 255); + property.setLanguageKey("config.transience_potion_id"); + property.setRequiresMcRestart(true); + transiencePotionID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "fireskinPotionID", 33, "The ID of the fireskin potion effect. Change if this conflicts with another mod.", 24, 255); + property.setLanguageKey("config.fireskin_potion_id"); + property.setRequiresMcRestart(true); + fireskinPotionID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "iceShroudPotionID", 34, "The ID of the ice shroud potion effect. Change if this conflicts with another mod.", 24, 255); + property.setLanguageKey("config.ice_shroud_potion_id"); + property.setRequiresMcRestart(true); + iceShroudPotionID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "staticAuraPotionID", 35, "The ID of the static aura potion effect. Change if this conflicts with another mod.", 24, 255); + property.setLanguageKey("config.static_aura_potion_id"); + property.setRequiresMcRestart(true); + staticAuraPotionID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "decayPotionID", 36, "The ID of the decay potion effect. Change if this conflicts with another mod.", 24, 255); + property.setLanguageKey("config.decay_potion_id"); + property.setRequiresMcRestart(true); + decayPotionID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "sixthSensePotionID", 37, "The ID of the sixth sense potion effect. Change if this conflicts with another mod.", 24, 255); + property.setLanguageKey("config.sixth_sense_potion_id"); + property.setRequiresMcRestart(true); + sixthSensePotionID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "arcaneJammerPotionID", 38, "The ID of the arcane jammer potion effect. Change if this conflicts with another mod.", 24, 255); + property.setLanguageKey("config.arcane_jammer_potion_id"); + property.setRequiresMcRestart(true); + arcaneJammerPotionID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "mindTrickPotionID", 39, "The ID of the mind trick potion effect. Change if this conflicts with another mod.", 24, 255); + property.setLanguageKey("config.mind_trick_potion_id"); + property.setRequiresMcRestart(true); + mindTrickPotionID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "mindControlPotionID", 40, "The ID of the mind control potion effect. Change if this conflicts with another mod.", 24, 255); + property.setLanguageKey("config.mind_control_potion_id"); + property.setRequiresMcRestart(true); + mindControlPotionID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "fontOfManaPotionID", 41, "The ID of the font of mana potion effect. Change if this conflicts with another mod.", 24, 255); + property.setLanguageKey("config.font_of_mana_potion_id"); + property.setRequiresMcRestart(true); + fontOfManaPotionID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "fearPotionID", 42, "The ID of the fear potion effect. Change if this conflicts with another mod.", 24, 255); + property.setLanguageKey("config.fear_potion_id"); + property.setRequiresMcRestart(true); + fearPotionID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "magicSwordEnchantmentID", 100, "The ID of the magic sword enchantment. Change if this conflicts with another mod.", 63, 255); + property.setLanguageKey("config.magic_sword_enchantment_id"); + property.setRequiresMcRestart(true); + magicSwordEnchantmentID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "magicBowEnchantmentID", 101, "The ID of the magic bow enchantment. Change if this conflicts with another mod.", 63, 255); + property.setLanguageKey("config.magic_bow_enchantment_id"); + property.setRequiresMcRestart(true); + magicBowEnchantmentID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "flamingWeaponEnchantmentID", 102, "The ID of the flaming weapon enchantment. Change if this conflicts with another mod.", 63, 255); + property.setLanguageKey("config.flaming_weapon_enchantment_id"); + property.setRequiresMcRestart(true); + flamingWeaponEnchantmentID = property.getInt(); + propOrder2.add(property.getName()); + + property = config.get(Wizardry.IDS_CATEGORY, "freezingWeaponEnchantmentID", 103, "The ID of the freezing weapon enchantment. Change if this conflicts with another mod.", 63, 255); + property.setLanguageKey("config.freezing_weapon_enchantment_id"); + property.setRequiresMcRestart(true); + freezingWeaponEnchantmentID = property.getInt(); + propOrder2.add(property.getName()); + + config.setCategoryPropertyOrder(Wizardry.IDS_CATEGORY, propOrder2); + + } + + private static void expandPotionTypesArray(){ + + Potion[] potionTypes = null; + + for(Field f : Potion.class.getDeclaredFields()){ + f.setAccessible(true); + // Notice that this already takes the obfuscation into account. + try{ + if(f.getName().equals("potionTypes") || f.getName().equals("field_76425_a")) { + Field modfield = Field.class.getDeclaredField("modifiers"); + modfield.setAccessible(true); + modfield.setInt(f, f.getModifiers() & ~Modifier.FINAL); + + potionTypes = (Potion[])f.get(null); + final Potion[] newPotionTypes = new Potion[256]; + System.arraycopy(potionTypes, 0, newPotionTypes, 0, potionTypes.length); + f.set(null, newPotionTypes); } - // No need to log, Forge does that. - mapping.remap(replacement); + } + catch (Exception e) { + System.err.println("Something went very wrong! Error while expanding potion types array:"); + e.printStackTrace(); } } } diff --git a/src/main/java/electroblob/wizardry/WizardryEventHandler.java b/src/main/java/electroblob/wizardry/WizardryEventHandler.java index a91acd2b..f5e530cc 100644 --- a/src/main/java/electroblob/wizardry/WizardryEventHandler.java +++ b/src/main/java/electroblob/wizardry/WizardryEventHandler.java @@ -1,171 +1,86 @@ package electroblob.wizardry; -import electroblob.wizardry.constants.Constants; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.entity.EntityArc; +import electroblob.wizardry.entity.construct.EntityBubble; +import electroblob.wizardry.entity.construct.EntityDecay; import electroblob.wizardry.entity.living.EntityEvilWizard; -import electroblob.wizardry.entity.living.ISpellCaster; -import electroblob.wizardry.entity.living.ISummonedCreature; -import electroblob.wizardry.event.DiscoverSpellEvent; -import electroblob.wizardry.event.SpellCastEvent; +import electroblob.wizardry.entity.living.EntitySilverfishMinion; +import electroblob.wizardry.entity.living.EntityWizard; +import electroblob.wizardry.item.ItemFlamingAxe; +import electroblob.wizardry.item.ItemFrostAxe; +import electroblob.wizardry.item.ItemSpectralArmour; +import electroblob.wizardry.item.ItemSpectralBow; +import electroblob.wizardry.item.ItemSpectralPickaxe; +import electroblob.wizardry.item.ItemSpectralSword; import electroblob.wizardry.item.ItemWand; import electroblob.wizardry.item.ItemWizardArmour; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.registry.WizardryAchievements; -import electroblob.wizardry.registry.WizardryEnchantments; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; +import electroblob.wizardry.spell.Clairvoyance; import electroblob.wizardry.spell.FreezingWeapon; +import electroblob.wizardry.spell.MindControl; +import electroblob.wizardry.spell.ShadowWard; import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.IElementalDamage; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WandHelper; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.spell.Intimidate; import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.monster.IMob; +import net.minecraft.entity.monster.EntityCreeper; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.passive.EntityPig; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.projectile.EntityArrow; -import net.minecraft.init.SoundEvents; +import net.minecraft.init.Blocks; import net.minecraft.inventory.ContainerPlayer; import net.minecraft.inventory.ContainerWorkbench; import net.minecraft.inventory.IInventory; +import net.minecraft.item.ItemBow; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.DamageSource; import net.minecraft.world.World; -import net.minecraft.world.storage.loot.LootEntry; -import net.minecraft.world.storage.loot.LootEntryTable; -import net.minecraft.world.storage.loot.LootPool; -import net.minecraft.world.storage.loot.RandomValueRange; -import net.minecraft.world.storage.loot.conditions.LootCondition; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.LootTableLoadEvent; +import net.minecraftforge.common.util.FakePlayer; +import net.minecraftforge.event.entity.EntityEvent.EntityConstructing; +import net.minecraftforge.event.entity.EntityJoinWorldEvent; +import net.minecraftforge.event.entity.EntityStruckByLightningEvent; +import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.entity.living.LivingAttackEvent; import net.minecraftforge.event.entity.living.LivingDeathEvent; import net.minecraftforge.event.entity.living.LivingDropsEvent; import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; import net.minecraftforge.event.entity.living.LivingHurtEvent; +import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent; +import net.minecraftforge.event.entity.player.BonemealEvent; import net.minecraftforge.event.entity.player.EntityItemPickupEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent; - -// Better ways of organising event handling: -// - Split it into several separate handlers, each with a logical area to deal with (see Astral Sorcery) -// - Remove most of the stuff, and have individual spell, item, block, entity, etc. classes handle their own events -// (see Botania) -// - Keep all the methods, but delegate near-repeated behaviours to their individual spell/potion/whatever classes -// (TGG does this, apparently) -// Incidentally, Twilight Forest still has one big event handler class - and a comment about how it's so long...! - -// In the end, I decided the most pragmatic solution was to either use the second option or keep things how they were, -// whichever will result in more readable/easily maintainable code in each case. To keep in line with the modularity -// of the spell system, the goal is to have nothing in here which relates to a specific spell (mostly done, but a few -// things remain). - -/** - * As of Wizardry 2.1, most of the code in this class has been relocated somewhere sensible, leaving only a few - * miscellaneous things that don't make much sense anywhere else, or that are better kept together. Previously, this was - * a gigantic class with about half of the entire mod's logic in it! - * @author Electroblob - * @since Wizardry 1.0 - */ -@Mod.EventBusSubscriber -public final class WizardryEventHandler { - - // IDEA: Config option allowing users to specify loot locations - private static final String[] LOOT_INJECTION_LOCATIONS = { - "minecraft:chests/simple_dungeon", - "minecraft:chests/abandoned_mineshaft", - "minecraft:chests/desert_pyramid", - "minecraft:chests/jungle_temple", - "minecraft:chests/stronghold_corridor", - "minecraft:chests/stronghold_crossing", - "minecraft:chests/stronghold_library", - "minecraft:chests/igloo_chest" - }; +import net.minecraftforge.event.entity.player.PlayerEvent.BreakSpeed; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.event.world.BlockEvent; +import net.minecraftforge.event.world.WorldEvent; +public class WizardryEventHandler { + @SubscribeEvent - public static void onLootTableLoadEvent(LootTableLoadEvent event){ - if(Wizardry.settings.generateLoot){ - for(String location : LOOT_INJECTION_LOCATIONS){ - if(event.getName().toString().matches(location)){ - event.getTable().addPool(getAdditive("wizardry:chests/dungeon_additions")); - } - } - } - } - - private static LootPool getAdditive(String entryName){ - return new LootPool(new LootEntry[] { getAdditiveEntry(entryName, 1) }, new LootCondition[0], new RandomValueRange(1), new RandomValueRange(0, 1), Wizardry.MODID + "_additive_pool"); - } - - private static LootEntryTable getAdditiveEntry(String name, int weight){ - return new LootEntryTable(new ResourceLocation(name), weight, 0, new LootCondition[0], Wizardry.MODID + "_additive_entry"); - } - - @SubscribeEvent - public static void onPlayerLoggedInEvent(PlayerLoggedInEvent event){ - // When a player logs in, they are sent the glyph data and the server's settings. - if(event.player instanceof EntityPlayerMP){ - SpellGlyphData.get(event.player.worldObj).sync((EntityPlayerMP)event.player); - Wizardry.settings.sync((EntityPlayerMP)event.player); + public void onEntityConstructingEvent(EntityConstructing event){ + if(event.entity instanceof EntityPlayer && ExtendedPlayer.get((EntityPlayer)event.entity) == null){ + ExtendedPlayer.register((EntityPlayer) event.entity); } } @SubscribeEvent - public static void onSpellCastPreEvent(SpellCastEvent.Pre event){ - // If a spell is disabled in the config, it will not work. - if(!event.getSpell().isEnabled()){ - if(!event.getEntityLiving().worldObj.isRemote) - event.getEntity().addChatMessage(new TextComponentTranslation("spell.disabled", event.getSpell().getNameForTranslationFormatted())); - event.setCanceled(true); - } - } - - @SubscribeEvent - public static void onSpellCastPostEvent(SpellCastEvent.Post event){ - - // Spell discovery (only players can discover spells, obviously) - if(event.getEntity() instanceof EntityPlayer){ - - EntityPlayer player = (EntityPlayer)event.getEntity(); - - WizardData data = WizardData.get(player); - - if(data != null){ - // Data is updated on both sides (This line was added client-side to fix a bug back in 1.1.3, so now - // it's in common code, which is nice!) - // Short-circuiting AND means that discoverSpell is only called if the event isn't cancelled. - if(!MinecraftForge.EVENT_BUS.post(new DiscoverSpellEvent(player, event.getSpell(), - DiscoverSpellEvent.Source.CASTING)) && data.discoverSpell(event.getSpell())){ - - // If the spell wasn't already discovered, other stuff happens: - if(event.getSource() == SpellCastEvent.Source.COMMAND){ - // If the spell didn't send a packet itself, the extended player needs to be synced so the - // spell discovery updates on the client. - if(!event.getSpell().doesSpellRequirePacket()) data.sync(); - - }else if(!event.getEntity().worldObj.isRemote && !player.capabilities.isCreativeMode - && Wizardry.settings.discoveryMode){ - // Sound and text only happen server-side, in survival, with discovery mode on, and only when - // the spell wasn't cast using commands. - WizardryUtilities.playSoundAtPlayer(player, SoundEvents.ENTITY_PLAYER_LEVELUP, 1.25f, 1); - player.addChatMessage(new TextComponentTranslation("spell.discover", event.getSpell().getNameForTranslationFormatted())); - } - } - } + public void onWorldLoadEvent(WorldEvent.Load event){ + if(!event.world.isRemote && event.world.provider.dimensionId == 0){ + SpellGlyphData.get(event.world); } } @@ -192,229 +107,496 @@ public final class WizardryEventHandler { * conventions for what sort of things take what priority...? */ @SubscribeEvent - public static void onLivingAttackEvent(LivingAttackEvent event){ + public void onLivingAttackEvent(LivingAttackEvent event){ // Prevents any damage to allies from magic if friendly fire is enabled - if(!Wizardry.settings.friendlyFire && event.getSource() != null && event.getSource().getEntity() instanceof EntityPlayer - && event.getEntity() instanceof EntityPlayer && event.getSource() instanceof IElementalDamage){ - if(WizardryUtilities.isPlayerAlly((EntityPlayer)event.getSource().getEntity(), (EntityPlayer)event.getEntity())){ + if(!Wizardry.friendlyFire && event.source != null && event.source.getEntity() instanceof EntityPlayer + && event.entity instanceof EntityPlayer && event.source instanceof IElementalDamage){ + if(WizardryUtilities.isPlayerAlly((EntityPlayer)event.source.getEntity(), (EntityPlayer)event.entity)){ event.setCanceled(true); - // This needs to be here, since if the event is cancelled nothing else needs to happen. + // I think this ought to be here, since if the event is cancelled nothing else needs to happen. return; } } + + if(event.source instanceof IElementalDamage){ + if(MagicDamage.isEntityImmune(((IElementalDamage)event.source).getType(), event.entity)){ + event.setCanceled(true); + // I would have liked to have done the 'resist' chat message here, but I overlooked the fact that I + // would need an instance of the spell to get its display name! + return; + } + // One convenient side effect of the new damage type system is that I can get rid of all the places where + // creepers are charged and just put them here under shock damage - this is precisely the sort of + // repetitive code I was trying to get rid of, since errors can (and did!) occur. + if(event.entityLiving instanceof EntityCreeper && !((EntityCreeper)event.entityLiving).getPowered() + && ((IElementalDamage)event.source).getType() == DamageType.SHOCK){ + // Charges creepers when they are hit by shock damage + event.entityLiving.getDataWatcher().updateObject(17, Byte.valueOf((byte)1)); + // Gives the player that caused the shock damage the 'It's Gonna Blow' achievement + if(event.source.getEntity() instanceof EntityPlayer){ + ((EntityPlayer)event.source.getEntity()).triggerAchievement(Wizardry.chargeCreeper); + } + } + } - // Retaliatory effects - // These are better off here because the revenge effects are pretty similar, and I'd rather keep the (lengthy) - // if statement in one place. - if(event.getSource() != null && event.getSource().getEntity() instanceof EntityLivingBase - && !event.getSource().isProjectile() && !(event.getSource() instanceof IElementalDamage && - ((IElementalDamage)event.getSource()).isRetaliatory())){ + // Bursts bubble when the creature inside takes damage + if(event.entityLiving.ridingEntity instanceof EntityBubble && + !((EntityBubble)event.entityLiving.ridingEntity).isDarkOrb){ + event.entityLiving.ridingEntity.worldObj.playSoundAtEntity(event.entityLiving.ridingEntity, "random.pop", 1.5f, 1.0f); + event.entityLiving.ridingEntity.setDead(); + } - EntityLivingBase attacker = (EntityLivingBase)event.getSource().getEntity(); - World world = event.getEntityLiving().worldObj; + // Prevents all unblockable damage while transience is active + if(event.entityLiving.isPotionActive(Wizardry.transience) && event.source != null && !event.source.isUnblockable()){ + event.setCanceled(true); + // Again, I think this ought to be here, since if the event is cancelled nothing else needs to happen. + return; + } - // Fireskin - if(event.getEntityLiving().isPotionActive(WizardryPotions.fireskin) - && !MagicDamage.isEntityImmune(DamageType.FIRE, event.getEntityLiving())) - attacker.setFire(5); + if(event.source != null && event.source.getEntity() instanceof EntityLivingBase){ - // Ice Shroud - if(event.getEntityLiving().isPotionActive(WizardryPotions.ice_shroud) && - !MagicDamage.isEntityImmune(DamageType.FROST, event.getEntityLiving())) - attacker.addPotionEffect(new PotionEffect(WizardryPotions.frost, 100, 0)); + // Cancels the mind trick effect if the creature takes damage + // This has been moved to within the (event.source.getEntity() instanceof EntityLivingBase) check so it doesn't + // crash the game with a ConcurrentModificationException. If you think about it, mind trick only ought to be + // cancelled if something attacks the entity since potions, drowning, cacti etc. don't affect the targeting. + if(event.entityLiving.isPotionActive(Wizardry.mindTrick)){ + event.entityLiving.removePotionEffect(Wizardry.mindTrick.id); + } - // Static Aura - if(event.getEntityLiving().isPotionActive(WizardryPotions.static_aura)){ + // 'Revenge' effects + EntityLivingBase attacker = (EntityLivingBase)event.source.getEntity(); + World world = event.entityLiving.worldObj; + + ItemStack wand = event.entityLiving.getHeldItem(); + + if(event.entityLiving.isPotionActive(Wizardry.fireskin) && !event.source.isProjectile()){ + if(!MagicDamage.isEntityImmune(DamageType.FIRE, event.entityLiving)) attacker.setFire(5); + } + + if(event.entityLiving.isPotionActive(Wizardry.iceShroud) && !event.source.isProjectile()){ + if(!MagicDamage.isEntityImmune(DamageType.FROST, event.entityLiving)) + attacker.addPotionEffect(new PotionEffect(Wizardry.frost.id, 100, 0, true)); + } + + if(event.entityLiving.isPotionActive(Wizardry.staticAura) && !event.source.isProjectile()){ if(!world.isRemote){ EntityArc arc = new EntityArc(world); - arc.setEndpointCoords(event.getEntityLiving().posX, event.getEntityLiving().posY + 1, event.getEntityLiving().posZ, + arc.setEndpointCoords(event.entityLiving.posX, event.entityLiving.posY + 1, event.entityLiving.posZ, attacker.posX, attacker.posY + attacker.height/2, attacker.posZ); world.spawnEntityInWorld(arc); }else{ for(int i=0;i<8;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, attacker.posX + world.rand.nextFloat() - 0.5, attacker.getEntityBoundingBox().minY + attacker.height/2 + world.rand.nextFloat()*2 - 1, attacker.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); - world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, attacker.posX + world.rand.nextFloat() - 0.5, attacker.getEntityBoundingBox().minY + attacker.height/2 + world.rand.nextFloat()*2 - 1, attacker.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, world, attacker.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(attacker) + attacker.height/2 + world.rand.nextFloat()*2 - 1, attacker.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); + world.spawnParticle("largesmoke", attacker.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(attacker) + attacker.height/2 + world.rand.nextFloat()*2 - 1, attacker.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); } } - attacker.attackEntityFrom(MagicDamage.causeDirectMagicDamage(event.getEntityLiving(), DamageType.SHOCK, true), 4.0f); - attacker.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); + attacker.attackEntityFrom(MagicDamage.causeDirectMagicDamage(event.entityLiving, DamageType.SHOCK), 4.0f); + world.playSoundAtEntity(attacker, "wizardry:arc", 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); } - } + // Shadow ward + if(event.entityLiving instanceof EntityPlayer){ + if(((EntityPlayer)event.entityLiving).isUsingItem() && wand != null && wand.getItemDamage() < wand.getMaxDamage() + && wand.getItem() instanceof ItemWand && WandHelper.getCurrentSpell(wand) instanceof ShadowWard + && !event.source.isUnblockable()){ + + event.setCanceled(true); + event.entityLiving.attackEntityFrom(DamageSource.magic, event.ammount/2); + attacker.attackEntityFrom(MagicDamage.causeDirectMagicDamage(event.entityLiving, DamageType.MAGIC), event.ammount/2); + } + } + + if(attacker.isPotionActive(Wizardry.transience)){ + event.setCanceled(true); + } + + // This behaviour has been removed, but is left here in case it is needed in future. + /* + if(attacker.isPotionActive(Wizardry.fireskin) && !event.source.isProjectile()){ + event.entityLiving.setFire(5); + } + + if(attacker.isPotionActive(Wizardry.iceShroud) && !event.source.isProjectile()){ + event.entityLiving.addPotionEffect(new PotionEffect(Wizardry.frost.id, 100, 0, true)); + } + */ + } } @SubscribeEvent - public static void onLivingHurtEvent(LivingHurtEvent event){ - + public void onLivingHurtEvent(LivingHurtEvent event){ + + // Curse of soulbinding + if(!event.entity.worldObj.isRemote && event.entityLiving instanceof EntityPlayer && !event.source.isUnblockable()){ + ExtendedPlayer properties = ExtendedPlayer.get((EntityPlayer)event.entityLiving); + if(properties != null){ + properties.damageAllSoulboundCreatures(event.ammount); + } + } + // Flaming and freezing swords - if(event.getSource().getEntity() instanceof EntityLivingBase){ - - EntityLivingBase attacker = (EntityLivingBase)event.getSource().getEntity(); - - // Players can only ever attack with their main hand, so this is the right method to use here. - if(attacker.getHeldItemMainhand() != null && attacker.getHeldItemMainhand().getItem() instanceof ItemSword){ - - int level = EnchantmentHelper.getEnchantmentLevel(WizardryEnchantments.flaming_weapon, attacker.getHeldItemMainhand()); - - if(level > 0 && !MagicDamage.isEntityImmune(DamageType.FIRE, event.getEntityLiving())) - event.getEntityLiving().setFire(level*4); - - level = EnchantmentHelper.getEnchantmentLevel(WizardryEnchantments.freezing_weapon, attacker.getHeldItemMainhand()); + if(event.source.getEntity() instanceof EntityLivingBase){ + EntityLivingBase attacker = (EntityLivingBase)event.source.getEntity(); + if(attacker.getHeldItem() != null && attacker.getHeldItem().getItem() instanceof ItemSword){ + + int level = EnchantmentHelper.getEnchantmentLevel(Wizardry.flamingWeapon.effectId, attacker.getHeldItem()); + + if(level > 0 && !MagicDamage.isEntityImmune(DamageType.FIRE, event.entityLiving)) + event.entityLiving.setFire(level*4); + + level = EnchantmentHelper.getEnchantmentLevel(Wizardry.freezingWeapon.effectId, attacker.getHeldItem()); // Frost lasts for longer because it doesn't do any actual damage - if(level > 0 && !MagicDamage.isEntityImmune(DamageType.FROST, event.getEntityLiving())) - event.getEntityLiving().addPotionEffect(new PotionEffect(WizardryPotions.frost, level*200, 0)); + if(level > 0 && !MagicDamage.isEntityImmune(DamageType.FROST, event.entityLiving)) + event.entityLiving.addPotionEffect(new PotionEffect(Wizardry.frost.id, level*200, 0, true)); } } - + // Freezing bow - if(event.getSource().getSourceOfDamage() instanceof EntityArrow && event.getSource().getSourceOfDamage().getEntityData() != null){ - - int level = event.getSource().getSourceOfDamage().getEntityData().getInteger(FreezingWeapon.FREEZING_ARROW_NBT_KEY); - - if(level > 0 && !MagicDamage.isEntityImmune(DamageType.FROST, event.getEntityLiving())) - event.getEntityLiving().addPotionEffect(new PotionEffect(WizardryPotions.frost, level*150, 0)); + if(event.source.getSourceOfDamage() instanceof EntityArrow && event.source.getSourceOfDamage().getEntityData() != null){ + + int level = event.source.getSourceOfDamage().getEntityData().getInteger(FreezingWeapon.FREEZING_ARROW_NBT_KEY); + + if(level > 0 && !MagicDamage.isEntityImmune(DamageType.FROST, event.entityLiving)) + event.entityLiving.addPotionEffect(new PotionEffect(Wizardry.frost.id, level*150, 0, true)); } - + // Damage scaling - if(event.getSource() != null && event.getSource() instanceof IElementalDamage){ - - if(event.getSource().getEntity() instanceof EntityPlayer){ - event.setAmount((float)(event.getAmount() * Wizardry.settings.playerDamageScale)); + if(event.source != null && event.source instanceof IElementalDamage){ + + if(event.source.getEntity() instanceof EntityPlayer){ + event.ammount *= Wizardry.playerDamageScale; }else{ - event.setAmount((float)(event.getAmount() * Wizardry.settings.npcDamageScale)); + event.ammount *= Wizardry.npcDamageScale; } } } @SubscribeEvent - public static void onLivingUpdateEvent(LivingUpdateEvent event){ + public void onBlockPlaceEvent(BlockEvent.PlaceEvent event){ - if(event.getEntityLiving() instanceof EntityPlayer){ + if(event.player.isPotionActive(Wizardry.transience)){ + event.setCanceled(true); + return; + } - EntityPlayer player = (EntityPlayer)event.getEntityLiving(); + // Spectral blocks cannot be built on + if(event.placedAgainst == Wizardry.spectralBlock){ + event.setCanceled(true); + return; + } + } - if(player.worldObj.isRemote) hackilyFixContinuousSpellCasting(player); + @SubscribeEvent + public void onBlockBreakEvent(BlockEvent.BreakEvent event){ + + if(event.getPlayer().isPotionActive(Wizardry.transience)){ + event.setCanceled(true); + return; + } - if(player.openContainer instanceof ContainerWorkbench){ - craftingTableTick(player); + // Makes wizards angry if a player breaks a block in their tower + if(!(event.getPlayer() instanceof FakePlayer)){ + + List wizards = WizardryUtilities.getEntitiesWithinRadius(64, event.x, event.y, event.z, event.world, EntityWizard.class); + + if(!wizards.isEmpty()){ + for(EntityWizard wizard : wizards){ + if(wizard.isBlockPartOfTower(event.x, event.y, event.z)){ + wizard.setRevengeTarget(event.getPlayer()); + event.getPlayer().triggerAchievement(Wizardry.angerWizard); + } + } + } + } + } + + @SubscribeEvent + public void onEntityStruckByLightningEvent(EntityStruckByLightningEvent event){ + + if(event.lightning.getEntityData() != null && event.lightning.getEntityData().hasKey("summoningPlayer")){ + + EntityPlayer player = (EntityPlayer)WizardryUtilities.getEntityByUUID(event.lightning.worldObj, UUID.fromString(event.lightning.getEntityData().getString("summoningPlayer"))); + + if(event.entity instanceof EntityCreeper){ + player.triggerAchievement(Wizardry.chargeCreeper); } - if(player.openContainer instanceof ContainerPlayer){ + if(event.entity instanceof EntityPig){ + player.triggerAchievement(Wizardry.frankenstein); + } + } + + } + + @SubscribeEvent + public void onLivingUpdateEvent(LivingUpdateEvent event){ + + if(event.entityLiving instanceof EntityPlayer){ + + EntityPlayer entityplayer = (EntityPlayer)event.entityLiving; + + if(ExtendedPlayer.get(entityplayer) != null){ + ExtendedPlayer.get(entityplayer).update(entityplayer); + } + + if(entityplayer.openContainer instanceof ContainerWorkbench){ + this.craftingTableTick(entityplayer); + } + + if(entityplayer.openContainer instanceof ContainerPlayer){ // Unfortunately I have no choice but to call this method every tick when the player isn't using another // inventory, since the only thing tracking whether the player is looking at their inventory is the GUI // itself, which is client-side only. - playerInventoryTick(player); + this.playerInventoryTick(entityplayer); } - testForArmourSet:{ - for(ItemStack stack : player.getArmorInventoryList()){ - if(stack == null || !(stack.getItem() instanceof ItemWizardArmour)){ - break testForArmourSet; + if(entityplayer.getCurrentArmor(0) != null && entityplayer.getCurrentArmor(0).getItem() instanceof ItemWizardArmour + && entityplayer.getCurrentArmor(1) != null && entityplayer.getCurrentArmor(1).getItem() instanceof ItemWizardArmour + && entityplayer.getCurrentArmor(2) != null && entityplayer.getCurrentArmor(2).getItem() instanceof ItemWizardArmour + && entityplayer.getCurrentArmor(3) != null && entityplayer.getCurrentArmor(3).getItem() instanceof ItemWizardArmour){ + + entityplayer.triggerAchievement(Wizardry.armourSet); + } + + // Tests for magic weapons, decrements the time until the magic wears off, and removes the enchantment if + // it has run out. + + magicWeapons: + if(ExtendedPlayer.get(entityplayer) != null){ + + for(ItemStack stack : entityplayer.inventory.mainInventory){ + + if(stack != null && stack.isItemEnchanted()){ + + Map enchantments = EnchantmentHelper.getEnchantments(stack); + + if(enchantments.containsKey(Wizardry.magicSword.effectId) || enchantments.containsKey(Wizardry.magicBow.effectId)){ + + if(ExtendedPlayer.get(entityplayer).magicWeaponDuration > 0){ + // Decrements the time until the magic wears off + ExtendedPlayer.get(entityplayer).magicWeaponDuration--; + }else{ + // Removes the magic weapon enchantment from the enchantment map + enchantments.remove(Wizardry.magicSword.effectId); + enchantments.remove(Wizardry.magicBow.effectId); + // Applies the new enchantment map to the item + EnchantmentHelper.setEnchantments(enchantments, stack); + } + + // If it found an imbued weapon, it can stop since there should only be one. + // More importantly, doing this skips the reset thing below. Just a bit tidier than a flag. + break magicWeapons; + } } } - player.addStat(WizardryAchievements.armour_set); + + // Resets the magic weapon timer if the player no longer has one. + if(ExtendedPlayer.get(entityplayer).magicWeaponDuration > 0){ + ExtendedPlayer.get(entityplayer).magicWeaponDuration = 0; + } } - } + // Tests for flaming weapons, decrements the time until the magic wears off, and removes the enchantment if + // it has run out. - if(event.getEntityLiving().worldObj.isRemote){ + flamingWeapons: + if(ExtendedPlayer.get(entityplayer) != null){ - // Client-side continuous spell casting for NPCs + for(ItemStack stack : entityplayer.inventory.mainInventory){ - if(event.getEntity() instanceof ISpellCaster && event.getEntity() instanceof EntityLiving){ + if(stack != null && stack.isItemEnchanted()){ - Spell spell = ((ISpellCaster)event.getEntity()).getContinuousSpell(); - SpellModifiers modifiers = ((ISpellCaster)event.getEntity()).getModifiers(); + Map enchantments = EnchantmentHelper.getEnchantments(stack); - if(spell != null && spell != Spells.none){ - - if(!MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Tick(event.getEntityLiving(), spell, modifiers, - SpellCastEvent.Source.NPC, 0))){ - - spell.cast(event.getEntity().worldObj, (EntityLiving)event.getEntity(), EnumHand.MAIN_HAND, 0, - // TODO: This implementation of modifiers relies on them being accessible client-side. - ((EntityLiving)event.getEntity()).getAttackTarget(), modifiers); + if(enchantments.containsKey(Wizardry.flamingWeapon.effectId)){ + + if(ExtendedPlayer.get(entityplayer).flamingWeaponDuration > 0){ + // Decrements the time until the flaming wears off + ExtendedPlayer.get(entityplayer).flamingWeaponDuration--; + }else{ + // Removes the flaming weapon enchantment from the enchantment map + enchantments.remove(Wizardry.flamingWeapon.effectId); + // Applies the new enchantment map to the item + EnchantmentHelper.setEnchantments(enchantments, stack); + } + + // If it found an imbued weapon, it can stop since there should only be one. + // More importantly, doing this skips the reset thing below. Just a bit tidier than a flag. + break flamingWeapons; + } } } - } - } - } - @SubscribeEvent - public static void onLivingDeathEvent(LivingDeathEvent event){ - - if(event.getSource().getEntity() instanceof EntityPlayer){ - - EntityPlayer player = (EntityPlayer)event.getSource().getEntity(); - - for(ItemStack stack : WizardryUtilities.getPrioritisedHotbarAndOffhand(player)){ - - if(stack != null && stack.getItem() instanceof ItemWand && stack.isItemDamaged() && WandHelper.getUpgradeLevel(stack, WizardryItems.siphon_upgrade) > 0){ - int damage = stack.getItemDamage() - Constants.SIPHON_MANA_PER_LEVEL*WandHelper.getUpgradeLevel(stack, WizardryItems.siphon_upgrade) - player.worldObj.rand.nextInt(Constants.SIPHON_MANA_PER_LEVEL); - if(damage < 0) damage = 0; - stack.setItemDamage(damage); - break; + // Resets the flaming weapon timer if the player no longer has one. + if(ExtendedPlayer.get(entityplayer).flamingWeaponDuration > 0){ + ExtendedPlayer.get(entityplayer).flamingWeaponDuration = 0; } } + + // Tests for freezing weapons, decrements the time until the magic wears off, and removes the enchantment if + // it has run out. - if(event.getEntityLiving() == player && event.getSource() instanceof IElementalDamage){ - player.addStat(WizardryAchievements.self_destruct); + freezingWeapons: + if(ExtendedPlayer.get(entityplayer) != null){ + + for(ItemStack stack : entityplayer.inventory.mainInventory){ + + if(stack != null && stack.isItemEnchanted()){ + + Map enchantments = EnchantmentHelper.getEnchantments(stack); + + if(enchantments.containsKey(Wizardry.freezingWeapon.effectId)){ + + if(ExtendedPlayer.get(entityplayer).freezingWeaponDuration > 0){ + // Decrements the time until the freezing wears off + ExtendedPlayer.get(entityplayer).freezingWeaponDuration--; + }else{ + // Removes the freezing weapon enchantment from the enchantment map + enchantments.remove(Wizardry.freezingWeapon.effectId); + // Applies the new enchantment map to the item + EnchantmentHelper.setEnchantments(enchantments, stack); + } + + // If it found an imbued weapon, it can stop since there should only be one. + // More importantly, doing this skips the reset thing below. Just a bit tidier than a flag. + break freezingWeapons; + } + } + } + + // Resets the freezing weapon timer if the player no longer has one. + if(ExtendedPlayer.get(entityplayer).freezingWeaponDuration > 0){ + ExtendedPlayer.get(entityplayer).freezingWeaponDuration = 0; + } + } + + } + + if(event.entityLiving.worldObj.isRemote){ + + if(event.entityLiving.isPotionActive(Wizardry.frost)){ + + double x = event.entityLiving.posX + (event.entityLiving.worldObj.rand.nextDouble() - 0.5)*event.entityLiving.width; + double y = WizardryUtilities.getEntityFeetPos(event.entityLiving) + event.entityLiving.worldObj.rand.nextDouble()*event.entityLiving.height; + double z = event.entityLiving.posZ + (event.entityLiving.worldObj.rand.nextDouble() - 0.5)*event.entityLiving.width; + + Wizardry.proxy.spawnParticle(EnumParticleType.SNOW, event.entityLiving.worldObj, x, y, z, 0, -0.02, 0, 15 + event.entityLiving.worldObj.rand.nextInt(5)); + } + + if(event.entityLiving.isPotionActive(Wizardry.fireskin)){ + + double x = event.entityLiving.posX + (event.entityLiving.worldObj.rand.nextDouble() - 0.5)*event.entityLiving.width; + double y = WizardryUtilities.getEntityFeetPos(event.entityLiving) + event.entityLiving.worldObj.rand.nextDouble()*event.entityLiving.height; + double z = event.entityLiving.posZ + (event.entityLiving.worldObj.rand.nextDouble() - 0.5)*event.entityLiving.width; + + event.entityLiving.worldObj.spawnParticle("flame", x, y, z, 0, 0, 0); + } + + if(event.entityLiving.isPotionActive(Wizardry.iceShroud)){ + + double x = event.entityLiving.posX + (event.entityLiving.worldObj.rand.nextDouble() - 0.5)*event.entityLiving.width; + double y = WizardryUtilities.getEntityFeetPos(event.entityLiving) + event.entityLiving.worldObj.rand.nextDouble()*event.entityLiving.height; + double z = event.entityLiving.posZ + (event.entityLiving.worldObj.rand.nextDouble() - 0.5)*event.entityLiving.width; + + float brightness = 0.5f + (event.entityLiving.worldObj.rand.nextFloat()/2); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, event.entityLiving.worldObj, x, y, z, 0, 0, 0, 48 + event.entityLiving.worldObj.rand.nextInt(12), brightness, brightness + 0.1f, 1.0f, true, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SNOW, event.entityLiving.worldObj, x, y, z, 0, -0.02, 0, 40 + event.entityLiving.worldObj.rand.nextInt(10)); + } + + if(event.entityLiving.isPotionActive(Wizardry.staticAura)){ + + double x = event.entityLiving.posX + (event.entityLiving.worldObj.rand.nextDouble() - 0.5)*event.entityLiving.width; + double y = WizardryUtilities.getEntityFeetPos(event.entityLiving) + event.entityLiving.worldObj.rand.nextDouble()*event.entityLiving.height; + double z = event.entityLiving.posZ + (event.entityLiving.worldObj.rand.nextDouble() - 0.5)*event.entityLiving.width; + + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, event.entityLiving.worldObj, x, y, z, 0, 0, 0, 3); + } + + if(event.entityLiving.isPotionActive(Wizardry.transience)){ + + double x = event.entityLiving.posX + (event.entityLiving.worldObj.rand.nextDouble() - 0.5)*event.entityLiving.width; + double y = WizardryUtilities.getEntityFeetPos(event.entityLiving) + event.entityLiving.worldObj.rand.nextDouble()*event.entityLiving.height; + double z = event.entityLiving.posZ + (event.entityLiving.worldObj.rand.nextDouble() - 0.5)*event.entityLiving.width; + + Wizardry.proxy.spawnParticle(EnumParticleType.DUST, event.entityLiving.worldObj, x, y, z, 0, 0, 0, (int)(16.0D / (Math.random() * 0.8D + 0.2D)), 0.8f, 0.8f, 1.0f); + } + + }else{ + + if(event.entityLiving.isPotionActive(Wizardry.decay) && event.entityLiving.onGround && event.entityLiving.ticksExisted % Wizardry.DECAY_SPREAD_INTERVAL == 0){ + + List list = event.entityLiving.worldObj.getEntitiesWithinAABBExcludingEntity(event.entityLiving, event.entityLiving.boundingBox); + + boolean flag = true; + + for(Object object : list){ + if(object instanceof EntityDecay) flag = false; + } + + if(flag){ + // The victim spreading the decay is the 'caster' here, so that it can actually wear off, otherwise it just gets infected with its own decay and the effect lasts forever. + event.entityLiving.worldObj.spawnEntityInWorld(new EntityDecay(event.entityLiving.worldObj, event.entityLiving.posX, event.entityLiving.posY, event.entityLiving.posZ, event.entityLiving)); + } + } + } + + // Mind trick + if(event.entityLiving.isPotionActive(Wizardry.mindTrick) && event.entityLiving instanceof EntityLiving){ + // Old AI (this can't be done in onLivingSetAttackTargetEvent because that only fires for the new AI). + if(event.entityLiving instanceof EntityCreature) ((EntityCreature)event.entityLiving).setTarget(null); + } + + // Mind control - old AI (this can't be done in onLivingSetAttackTargetEvent because that only fires for the new AI). + mindcontrol: + if(event.entityLiving.isPotionActive(Wizardry.mindControl) && event.entityLiving instanceof EntityLiving){ + + NBTTagCompound entityNBT = event.entityLiving.getEntityData(); + + if(entityNBT != null && entityNBT.hasKey(MindControl.NBT_KEY)){ + + Entity caster = WizardryUtilities.getEntityByUUID(event.entity.worldObj, UUID.fromString(entityNBT.getString(MindControl.NBT_KEY))); + + if(caster instanceof EntityLivingBase){ + + if(MindControl.findMindControlTarget((EntityLiving)event.entityLiving, (EntityLivingBase)caster, event.entity.worldObj)){ + // If it worked, skip setting the target to null. + break mindcontrol; + } + } + } + // If the caster couldn't be found or no valid target was found, this just acts like mind trick. + ((EntityLiving)event.entityLiving).setAttackTarget(null); + } + + // Terror + if(event.entityLiving.isPotionActive(Wizardry.fear) && event.entityLiving instanceof EntityCreature){ + + NBTTagCompound entityNBT = event.entityLiving.getEntityData(); + EntityCreature creature = (EntityCreature)event.entityLiving; + + if(entityNBT != null && entityNBT.hasKey(Intimidate.NBT_KEY)){ + + Entity caster = WizardryUtilities.getEntityByUUID(creature.worldObj, UUID.fromString(entityNBT.getString(Intimidate.NBT_KEY))); + + if(caster instanceof EntityLivingBase){ + Intimidate.runAway(creature, (EntityLivingBase)caster); + } } } } @SubscribeEvent - public static void onLivingDropsEvent(LivingDropsEvent event){ - // TODO: Really, this should be in a loot table (mob_additions), however I can't seem to find a way of - // automatically adding it to all subclasses of IMob. - // Evil wizards drop spell books themselves - if(event.getEntityLiving() instanceof IMob && !(event.getEntityLiving() instanceof EntityEvilWizard) - // TODO: Backport when you backport the new summoned creature system. - && !(event.getEntityLiving() instanceof ISummonedCreature) && event.getSource().getEntity() instanceof EntityPlayer - && Wizardry.settings.spellBookDropChance > 0){ - - // This does exactly what the entity drop method does, but with a different random number so that the - // spell book doesn't always drop with other rare drops. - int rareDropNumber = event.getEntity().worldObj.rand.nextInt(200) - event.getLootingLevel(); - if(rareDropNumber < Wizardry.settings.spellBookDropChance){ - // Drops a spell book - int id = WizardryUtilities.getStandardWeightedRandomSpellId(event.getEntity().worldObj.rand); - - event.getDrops().add(new EntityItem(event.getEntityLiving().worldObj, event.getEntityLiving().posX, event.getEntityLiving().posY, event.getEntityLiving().posZ, - new ItemStack(WizardryItems.spell_book, 1, id))); - } + public void onBreakSpeedEvent(BreakSpeed event){ + if(event.entityPlayer.isPotionActive(Wizardry.frost)){ + // Amplifier + 1 because it starts at 0 + event.newSpeed = event.originalSpeed * (1 - Wizardry.FROST_FATIGUE_PER_LEVEL*(event.entityPlayer.getActivePotionEffect(Wizardry.frost).getAmplifier() + 1)); } } - @SubscribeEvent - public static void onItemPickupEvent(EntityItemPickupEvent event){ - if(event.getItem().getEntityItem().getItem() == WizardryItems.magic_crystal){ - event.getEntityPlayer().addStat(WizardryAchievements.crystal, 1); - } - } - - // Private helper methods - // ================================================================================================================ - - /** - * Detects inconsistencies between player.getActiveItemStack and the actual itemstack and forces them to be equal. - * Fixes issue #25. - * @param player - */ - private static void hackilyFixContinuousSpellCasting(EntityPlayer player){ - if(player.isHandActive() && player.getHeldItem(player.getActiveHand()) != null - && player.getHeldItem(player.getActiveHand()).getItem() instanceof ItemWand - && WandHelper.getCurrentSpell(player.getHeldItem(player.getActiveHand())).isContinuous){ - if(player.getActiveItemStack() != player.getHeldItem(player.getActiveHand())){ - player.setHeldItem(player.getActiveHand(), player.getActiveItemStack()); - } - } - } - - private static void playerInventoryTick(EntityPlayer player){ + private void playerInventoryTick(EntityPlayer player) { // Charges wand using mana flask. It is here rather than in the crafting handler so the result displays // the proper damage before it is actually crafted. @@ -425,11 +607,11 @@ public final class WizardryEventHandler { IInventory craftMatrix = ((ContainerPlayer)player.openContainer).craftMatrix; ItemStack outputItem = ((ContainerPlayer)player.openContainer).craftResult.getStackInSlot(0); - for(int i = 0; i < craftMatrix.getSizeInventory(); i++){ + for (int i = 0; i < craftMatrix.getSizeInventory(); i++){ if(craftMatrix.getStackInSlot(i) != null){ ItemStack itemstack = craftMatrix.getStackInSlot(i); - if(itemstack.getItem() == WizardryItems.mana_flask){ + if(itemstack.getItem() == Wizardry.manaFlask){ flag = true; } @@ -444,27 +626,28 @@ public final class WizardryEventHandler { } if(outputItem != null && outputItem.getItem() instanceof ItemWand && flag && wand != null){ - outputItem.setTagCompound((wand.getTagCompound())); - if(wand.getItemDamage()-Constants.MANA_PER_FLASK < 0){ + outputItem.setTagCompound(wand.getTagCompound()); + if(wand.getItemDamage()-Wizardry.MANA_PER_FLASK < 0){ outputItem.setItemDamage(0); }else{ - outputItem.setItemDamage(wand.getItemDamage()-Constants.MANA_PER_FLASK); + outputItem.setItemDamage(wand.getItemDamage()-Wizardry.MANA_PER_FLASK); } } if(outputItem != null && outputItem.getItem() instanceof ItemWizardArmour && flag && armour != null){ - outputItem.setTagCompound((armour.getTagCompound())); - if(armour.getItemDamage()-Constants.MANA_PER_FLASK < 0){ + outputItem.setTagCompound(armour.getTagCompound()); + if(armour.getItemDamage()-Wizardry.MANA_PER_FLASK < 0){ outputItem.setItemDamage(0); }else{ - outputItem.setItemDamage(wand.getItemDamage()-Constants.MANA_PER_FLASK); + outputItem.setItemDamage(wand.getItemDamage()-Wizardry.MANA_PER_FLASK); } } } - private static void craftingTableTick(EntityPlayer player) { + private void craftingTableTick(EntityPlayer player) { - // Charges wand using mana flask + // Charges wand using mana flask. It is here rather than in the crafting handler so the result displays + // the proper damage before it is actually crafted. boolean flag = false; ItemStack wand = null; @@ -476,7 +659,7 @@ public final class WizardryEventHandler { if(craftMatrix.getStackInSlot(i) != null){ ItemStack itemstack = craftMatrix.getStackInSlot(i); - if(itemstack.getItem() == WizardryItems.mana_flask){ + if(itemstack.getItem() == Wizardry.manaFlask){ flag = true; } @@ -491,22 +674,300 @@ public final class WizardryEventHandler { } if(outputItem != null && outputItem.getItem() instanceof ItemWand && flag && wand != null){ - outputItem.setTagCompound((wand.getTagCompound())); - if(wand.getItemDamage()-Constants.MANA_PER_FLASK < 0){ + outputItem.setTagCompound(wand.getTagCompound()); + if(wand.getItemDamage()-Wizardry.MANA_PER_FLASK < 0){ outputItem.setItemDamage(0); }else{ - outputItem.setItemDamage(wand.getItemDamage()-Constants.MANA_PER_FLASK); + outputItem.setItemDamage(wand.getItemDamage()-Wizardry.MANA_PER_FLASK); } } if(outputItem != null && outputItem.getItem() instanceof ItemWizardArmour && flag && armour != null){ - outputItem.setTagCompound((armour.getTagCompound())); - if(armour.getItemDamage()-Constants.MANA_PER_FLASK < 0){ + outputItem.setTagCompound(armour.getTagCompound()); + if(armour.getItemDamage()-Wizardry.MANA_PER_FLASK < 0){ outputItem.setItemDamage(0); }else{ - outputItem.setItemDamage(wand.getItemDamage()-Constants.MANA_PER_FLASK); + outputItem.setItemDamage(wand.getItemDamage()-Wizardry.MANA_PER_FLASK); } } } + @SubscribeEvent + public void onLivingDeathEvent(LivingDeathEvent event){ + + // Extended player data saving + if (!event.entity.worldObj.isRemote && event.entity instanceof EntityPlayer){ + // This should never be null, but no harm in checking. + if(ExtendedPlayer.get((EntityPlayer)event.entity) != null){ + + ExtendedPlayer.get((EntityPlayer)event.entity).onPlayerDeath(); + + NBTTagCompound playerData = new NBTTagCompound(); + ExtendedPlayer.get((EntityPlayer)event.entity).saveNBTData(playerData); + CommonProxy.storeEntityData(ExtendedPlayer.getSaveKey((EntityPlayer)event.entity), playerData); + } + } + + if(event.source.getEntity() instanceof EntityPlayer){ + + EntityPlayer player = (EntityPlayer)event.source.getEntity(); + + // Mana siphoning. Works for the first wand with a siphon upgrade on the hotbar. + for(int i=0; i<9; i++){ + ItemStack itemstack = player.inventory.getStackInSlot(i); + if(itemstack != null && itemstack.getItem() instanceof ItemWand && itemstack.isItemDamaged() && WandHelper.getUpgradeLevel(itemstack, Wizardry.siphonUpgrade) > 0){ + int damage = itemstack.getItemDamage() - Wizardry.SIPHON_MANA_PER_LEVEL*WandHelper.getUpgradeLevel(itemstack, Wizardry.siphonUpgrade) - player.worldObj.rand.nextInt(Wizardry.SIPHON_MANA_PER_LEVEL); + if(damage < 0) damage = 0; + itemstack.setItemDamage(damage); + break; + } + } + + if(event.entityLiving == player && event.source instanceof IElementalDamage){ + player.triggerAchievement(Wizardry.selfDestruct); + } + } + + if(event.source.getEntity() instanceof EntitySilverfishMinion){ + int lifetime = ((EntitySilverfishMinion)event.source.getEntity()).lifetime; + // Summons 1-4 more silverfish + int alliesToSummon = event.entity.worldObj.rand.nextInt(4) + 1; + + for(int i=0; i 0){ + arrow.setDamage(arrow.getDamage() + (double)level * 0.5D + 0.5D); + } + + if(EnchantmentHelper.getEnchantmentLevel(Wizardry.flamingWeapon.effectId, archer.getHeldItem()) > 0){ + // Again, this is exactly what happens in ItemBow (flame is flame; level does nothing). + arrow.setFire(100); + } + + level = EnchantmentHelper.getEnchantmentLevel(Wizardry.freezingWeapon.effectId, archer.getHeldItem()); + + if(level > 0){ + if(arrow.getEntityData() != null){ + arrow.getEntityData().setInteger(FreezingWeapon.FREEZING_ARROW_NBT_KEY, level); + } + } + } + } + } + + } + + @SubscribeEvent + public void onLivingDropsEvent(LivingDropsEvent event){ + // Evil wizards drop spell books themselves + if(event.entityLiving instanceof EntityMob && !(event.entityLiving instanceof EntityEvilWizard) && event.source.getEntity() instanceof EntityPlayer && Wizardry.spellBookDropChance > 0){ + + // This does exactly what the entity drop method does, but with a different random number so that the + // spell book doesn't always drop with other rare drops. + int rareDropNumber = event.entity.worldObj.rand.nextInt(200) - event.lootingLevel; + if(rareDropNumber < Wizardry.spellBookDropChance){ + // Drops a spell book + int id = WizardryUtilities.getStandardWeightedRandomSpellId(event.entity.worldObj.rand); + + event.drops.add(new EntityItem(event.entityLiving.worldObj, event.entityLiving.posX, event.entityLiving.posY, event.entityLiving.posZ, + new ItemStack(Wizardry.spellBook, 1, id))); + } + } + + for(EntityItem item : event.drops){ + + // Destroys conjured items if their caster dies. + if(item.getEntityItem().getItem() instanceof ItemSpectralSword + || item.getEntityItem().getItem() instanceof ItemSpectralPickaxe + || item.getEntityItem().getItem() instanceof ItemSpectralBow + || item.getEntityItem().getItem() instanceof ItemSpectralArmour + || item.getEntityItem().getItem() instanceof ItemFlamingAxe + || item.getEntityItem().getItem() instanceof ItemFrostAxe){ + + item.setDead(); + } + + // Instantly disenchants an imbued weapon if it is dropped when the player dies. + if(item.getEntityItem().isItemEnchanted()){ + + // No need to check what enchantments the item has, since remove() does nothing if the element does not exist. + Map enchantments = EnchantmentHelper.getEnchantments(item.getEntityItem()); + + // Removes the magic weapon enchantments from the enchantment map + enchantments.remove(Wizardry.magicSword.effectId); + enchantments.remove(Wizardry.magicBow.effectId); + enchantments.remove(Wizardry.flamingWeapon.effectId); + enchantments.remove(Wizardry.freezingWeapon.effectId); + + // Applies the new enchantment map to the item + EnchantmentHelper.setEnchantments(enchantments, item.getEntityItem()); + } + } + } + + @SubscribeEvent + public void onLivingSetAttackTargetEvent(LivingSetAttackTargetEvent event){ + // Mind trick + // If the target is null already, no need to set it to null, or infinite loops will occur. + if((event.entityLiving.isPotionActive(Wizardry.mindTrick) || event.entityLiving.isPotionActive(Wizardry.fear)) && event.entityLiving instanceof EntityLiving && event.target != null){ + // New AI + ((EntityLiving)event.entityLiving).setAttackTarget(null); + } + + // Mind control + mindcontrol: + if(event.entityLiving.isPotionActive(Wizardry.mindControl) && event.entityLiving instanceof EntityLiving){ + + NBTTagCompound entityNBT = event.entityLiving.getEntityData(); + + if(entityNBT != null && entityNBT.hasKey(MindControl.NBT_KEY)){ + + Entity caster = WizardryUtilities.getEntityByUUID(event.entity.worldObj, UUID.fromString(entityNBT.getString(MindControl.NBT_KEY))); + + // If the target that the event tried to set is already a valid mind control target, nothing happens. + if(WizardryUtilities.isValidTarget(caster, event.target)) break mindcontrol; + + if(caster instanceof EntityLivingBase){ + + if(MindControl.findMindControlTarget((EntityLiving)event.entityLiving, (EntityLivingBase)caster, event.entity.worldObj)){ + // If it worked, skip setting the target to null. + break mindcontrol; + } + } + } + // If the caster couldn't be found or no valid target was found, this just acts like mind trick. + // If the target is null already, no need to set it to null, or infinite loops will occur. + if(event.target != null) ((EntityLiving)event.entityLiving).setAttackTarget(null); + } + } + + @SubscribeEvent + public void onItemPickupEvent(EntityItemPickupEvent event){ + if(event.item.getEntityItem().getItem() == Wizardry.magicCrystal){ + event.entityPlayer.addStat(Wizardry.crystal, 1); + } + } + + @SubscribeEvent + public void onItemTossEvent(ItemTossEvent event){ + + // Prevents conjured items being thrown by dragging and dropping outside the inventory. + if(event.entityItem.getEntityItem().getItem() instanceof ItemSpectralSword + || event.entityItem.getEntityItem().getItem() instanceof ItemSpectralPickaxe + || event.entityItem.getEntityItem().getItem() instanceof ItemSpectralBow + || event.entityItem.getEntityItem().getItem() instanceof ItemSpectralArmour + || event.entityItem.getEntityItem().getItem() instanceof ItemFlamingAxe + || event.entityItem.getEntityItem().getItem() instanceof ItemFrostAxe){ + + event.setCanceled(true); + event.player.inventory.addItemStackToInventory(event.entityItem.getEntityItem()); + } + + // Instantly disenchants an imbued weapon if it is thrown on the ground. + if(event.entityItem.getEntityItem().isItemEnchanted()){ + + // No need to check what enchantments the item has, since remove() does nothing if the element does not exist. + Map enchantments = EnchantmentHelper.getEnchantments(event.entityItem.getEntityItem()); + + // Removes the magic weapon enchantments from the enchantment map + enchantments.remove(Wizardry.magicSword.effectId); + enchantments.remove(Wizardry.magicBow.effectId); + enchantments.remove(Wizardry.flamingWeapon.effectId); + enchantments.remove(Wizardry.freezingWeapon.effectId); + + // Applies the new enchantment map to the item + EnchantmentHelper.setEnchantments(enchantments, event.entityItem.getEntityItem()); + } + } + + @SubscribeEvent + public void onPlayerInteractEvent(PlayerInteractEvent event){ + + if(event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK && event.entityPlayer.isSneaking()){ + + ItemStack wand = event.entityPlayer.getHeldItem(); + + if(wand != null && wand.getItem() instanceof ItemWand && WandHelper.getCurrentSpell(wand) instanceof Clairvoyance){ + + ExtendedPlayer properties = ExtendedPlayer.get(event.entityPlayer); + + if(properties != null){ + + int x = event.x; + int y = event.y; + int z = event.z; + + if(event.face == 0) y--; + if(event.face == 1) y++; + if(event.face == 2) z--; + if(event.face == 3) z++; + if(event.face == 4) x--; + if(event.face == 5) x++; + + properties.setClairvoyancePoint(x, y, z, event.world.provider.dimensionId); + if(!event.world.isRemote){ + event.entityPlayer.addChatMessage(new ChatComponentTranslation("spell.clairvoyance.confirm", WizardryRegistry.clairvoyance.getDisplayNameWithFormatting())); + event.setCanceled(true); + } + } + } + } + } + + @SubscribeEvent + public void onBonemealEvent(BonemealEvent event){ + // Grows crystal flowers when bonemeal is used on grass + if(event.block == Blocks.grass){ + + int x = event.x + event.world.rand.nextInt(8) - event.world.rand.nextInt(8); + int y = event.y + event.world.rand.nextInt(4) - event.world.rand.nextInt(4); + int z = event.z + event.world.rand.nextInt(8) - event.world.rand.nextInt(8); + + if (event.world.isAirBlock(x, y, z) && (!event.world.provider.hasNoSky || y < 127) && Wizardry.crystalFlower.canBlockStay(event.world, x, y, z)) + { + event.world.setBlock(x, y, z, Wizardry.crystalFlower, 0, 2); + } + } + } } \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/WizardryGuiFactory.java b/src/main/java/electroblob/wizardry/WizardryGuiFactory.java index 0f7c0161..1d330a0e 100644 --- a/src/main/java/electroblob/wizardry/WizardryGuiFactory.java +++ b/src/main/java/electroblob/wizardry/WizardryGuiFactory.java @@ -2,10 +2,10 @@ package electroblob.wizardry; import java.util.Set; +import cpw.mods.fml.client.IModGuiFactory; import electroblob.wizardry.client.GuiConfigWizardry; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; -import net.minecraftforge.fml.client.IModGuiFactory; public class WizardryGuiFactory implements IModGuiFactory { @@ -27,8 +27,7 @@ public class WizardryGuiFactory implements IModGuiFactory { return null; } - @SuppressWarnings("deprecation") // It's a bit of Forge that hasn't been tidied up, but we have to implement it. - @Override + @Override public RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement element) { return null; diff --git a/src/main/java/electroblob/wizardry/WizardryGuiHandler.java b/src/main/java/electroblob/wizardry/WizardryGuiHandler.java index ad17f45d..9a0569bd 100644 --- a/src/main/java/electroblob/wizardry/WizardryGuiHandler.java +++ b/src/main/java/electroblob/wizardry/WizardryGuiHandler.java @@ -1,5 +1,10 @@ package electroblob.wizardry; +import cpw.mods.fml.common.network.IGuiHandler; +import electroblob.wizardry.client.GuiArcaneWorkbench; +import electroblob.wizardry.client.GuiPortableCrafting; +import electroblob.wizardry.client.GuiSpellBook; +import electroblob.wizardry.client.GuiWizardHandbook; import electroblob.wizardry.item.ItemSpellBook; import electroblob.wizardry.item.ItemWizardHandbook; import electroblob.wizardry.spell.Spell; @@ -8,9 +13,7 @@ import electroblob.wizardry.tileentity.ContainerPortableWorkbench; import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.fml.common.network.IGuiHandler; public class WizardryGuiHandler implements IGuiHandler { @@ -26,13 +29,13 @@ public class WizardryGuiHandler implements IGuiHandler { public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { if(id == ARCANE_WORKBENCH){ - TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z)); + TileEntity tileEntity = world.getTileEntity(x, y, z); if(tileEntity instanceof TileEntityArcaneWorkbench){ return new ContainerArcaneWorkbench(player.inventory, (TileEntityArcaneWorkbench) tileEntity); } } else if(id == PORTABLE_CRAFTING){ - return new ContainerPortableWorkbench(player.inventory, world, new BlockPos(x, y, z)); + return new ContainerPortableWorkbench(player.inventory, world, x, y, z); } return null; } @@ -41,25 +44,19 @@ public class WizardryGuiHandler implements IGuiHandler { public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { if(id == ARCANE_WORKBENCH){ - TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z)); + TileEntity tileEntity = world.getTileEntity(x, y, z); if(tileEntity instanceof TileEntityArcaneWorkbench){ - return new electroblob.wizardry.client.GuiArcaneWorkbench(player.inventory, (TileEntityArcaneWorkbench) tileEntity); + return new GuiArcaneWorkbench(player.inventory, (TileEntityArcaneWorkbench) tileEntity); } } - else if(id == WIZARD_HANDBOOK - && ((player.getHeldItemMainhand() != null && player.getHeldItemMainhand().getItem() instanceof ItemWizardHandbook) - || (player.getHeldItemOffhand() != null && player.getHeldItemOffhand().getItem() instanceof ItemWizardHandbook))){ - return new electroblob.wizardry.client.GuiWizardHandbook(); + else if(id == WIZARD_HANDBOOK && player.getHeldItem().getItem() instanceof ItemWizardHandbook){ + return new GuiWizardHandbook(); } - else if(id == SPELL_BOOK){ - if(player.getHeldItemMainhand() != null && player.getHeldItemMainhand().getItem() instanceof ItemSpellBook){ - return new electroblob.wizardry.client.GuiSpellBook(Spell.get(player.getHeldItemMainhand().getItemDamage())); - }else if(player.getHeldItemOffhand() != null && player.getHeldItemOffhand().getItem() instanceof ItemSpellBook){ - return new electroblob.wizardry.client.GuiSpellBook(Spell.get(player.getHeldItemOffhand().getItemDamage())); - } + else if(id == SPELL_BOOK && player.getHeldItem().getItem() instanceof ItemSpellBook){ + return new GuiSpellBook(Spell.get(player.getHeldItem().getItemDamage())); } else if(id == PORTABLE_CRAFTING){ - return new electroblob.wizardry.client.GuiPortableCrafting(player.inventory, world, new BlockPos(x, y, z)); + return new GuiPortableCrafting(player.inventory, world, x, y, z); } return null; } diff --git a/src/main/java/electroblob/wizardry/WizardryKeyHandler.java b/src/main/java/electroblob/wizardry/WizardryKeyHandler.java index 9cfc7ab9..ec8bc139 100644 --- a/src/main/java/electroblob/wizardry/WizardryKeyHandler.java +++ b/src/main/java/electroblob/wizardry/WizardryKeyHandler.java @@ -2,13 +2,13 @@ package electroblob.wizardry; import org.lwjgl.input.Keyboard; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.InputEvent; +import cpw.mods.fml.common.network.simpleimpl.IMessage; import electroblob.wizardry.client.ClientProxy; import electroblob.wizardry.packet.PacketControlInput; import electroblob.wizardry.packet.WizardryPacketHandler; import net.minecraft.client.Minecraft; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.gameevent.InputEvent; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; public class WizardryKeyHandler { @@ -25,7 +25,9 @@ public class WizardryKeyHandler { if(Wizardry.proxy instanceof ClientProxy){ - if(ClientProxy.NEXT_SPELL.isPressed() && Minecraft.getMinecraft().inGameHasFocus){ + ClientProxy proxy = (ClientProxy)Wizardry.proxy; + + if(proxy.nextSpell.isPressed() && Minecraft.getMinecraft().inGameHasFocus){ if(!NkeyPressed){ NkeyPressed = true; }else{ @@ -33,12 +35,12 @@ public class WizardryKeyHandler { } if(!NkeyAlreadyPressed){ // Packet building - IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.NEXT_SPELL_KEY); + IMessage msg = new PacketControlInput.Message(1); WizardryPacketHandler.net.sendToServer(msg); } } - if(ClientProxy.PREVIOUS_SPELL.isPressed() && Minecraft.getMinecraft().inGameHasFocus){ + if(proxy.previousSpell.isPressed() && Minecraft.getMinecraft().inGameHasFocus){ if(!BkeyPressed){ BkeyPressed = true; }else{ @@ -46,7 +48,7 @@ public class WizardryKeyHandler { } if(!BkeyAlreadyPressed){ // Packet building - IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.PREVIOUS_SPELL_KEY); + IMessage msg = new PacketControlInput.Message(2); WizardryPacketHandler.net.sendToServer(msg); } } diff --git a/src/main/java/electroblob/wizardry/WizardryRegistry.java b/src/main/java/electroblob/wizardry/WizardryRegistry.java new file mode 100644 index 00000000..3df9ae9b --- /dev/null +++ b/src/main/java/electroblob/wizardry/WizardryRegistry.java @@ -0,0 +1,631 @@ +package electroblob.wizardry; + +import java.util.ArrayList; +import java.util.List; + +import cpw.mods.fml.common.registry.EntityRegistry; +import cpw.mods.fml.common.registry.GameRegistry; +import electroblob.wizardry.entity.EntityArc; +import electroblob.wizardry.entity.EntityFallingGrass; +import electroblob.wizardry.entity.EntityMagicSlime; +import electroblob.wizardry.entity.EntityMeteor; +import electroblob.wizardry.entity.EntityShield; +import electroblob.wizardry.entity.construct.EntityArrowRain; +import electroblob.wizardry.entity.construct.EntityBlackHole; +import electroblob.wizardry.entity.construct.EntityBlizzard; +import electroblob.wizardry.entity.construct.EntityBubble; +import electroblob.wizardry.entity.construct.EntityDecay; +import electroblob.wizardry.entity.construct.EntityEarthquake; +import electroblob.wizardry.entity.construct.EntityFireRing; +import electroblob.wizardry.entity.construct.EntityFireSigil; +import electroblob.wizardry.entity.construct.EntityForcefield; +import electroblob.wizardry.entity.construct.EntityFrostSigil; +import electroblob.wizardry.entity.construct.EntityHailstorm; +import electroblob.wizardry.entity.construct.EntityHammer; +import electroblob.wizardry.entity.construct.EntityHealAura; +import electroblob.wizardry.entity.construct.EntityIceSpike; +import electroblob.wizardry.entity.construct.EntityLightningPulse; +import electroblob.wizardry.entity.construct.EntityLightningSigil; +import electroblob.wizardry.entity.construct.EntityTornado; +import electroblob.wizardry.entity.living.EntityBlazeMinion; +import electroblob.wizardry.entity.living.EntityDecoy; +import electroblob.wizardry.entity.living.EntityEvilWizard; +import electroblob.wizardry.entity.living.EntityIceGiant; +import electroblob.wizardry.entity.living.EntityIceWraith; +import electroblob.wizardry.entity.living.EntityLightningWraith; +import electroblob.wizardry.entity.living.EntityPhoenix; +import electroblob.wizardry.entity.living.EntityShadowWraith; +import electroblob.wizardry.entity.living.EntitySilverfishMinion; +import electroblob.wizardry.entity.living.EntitySkeletonMinion; +import electroblob.wizardry.entity.living.EntitySpiderMinion; +import electroblob.wizardry.entity.living.EntitySpiritHorse; +import electroblob.wizardry.entity.living.EntitySpiritWolf; +import electroblob.wizardry.entity.living.EntityStormElemental; +import electroblob.wizardry.entity.living.EntityWizard; +import electroblob.wizardry.entity.living.EntityZombieMinion; +import electroblob.wizardry.entity.projectile.EntityDarknessOrb; +import electroblob.wizardry.entity.projectile.EntityDart; +import electroblob.wizardry.entity.projectile.EntityFirebolt; +import electroblob.wizardry.entity.projectile.EntityFirebomb; +import electroblob.wizardry.entity.projectile.EntityForceArrow; +import electroblob.wizardry.entity.projectile.EntityForceOrb; +import electroblob.wizardry.entity.projectile.EntityIceCharge; +import electroblob.wizardry.entity.projectile.EntityIceLance; +import electroblob.wizardry.entity.projectile.EntityIceShard; +import electroblob.wizardry.entity.projectile.EntityLightningArrow; +import electroblob.wizardry.entity.projectile.EntityLightningDisc; +import electroblob.wizardry.entity.projectile.EntityMagicMissile; +import electroblob.wizardry.entity.projectile.EntityPoisonBomb; +import electroblob.wizardry.entity.projectile.EntitySmokeBomb; +import electroblob.wizardry.entity.projectile.EntitySpark; +import electroblob.wizardry.entity.projectile.EntitySparkBomb; +import electroblob.wizardry.entity.projectile.EntityThunderbolt; +import electroblob.wizardry.spell.*; +import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench; +import electroblob.wizardry.tileentity.TileEntityMagicLight; +import electroblob.wizardry.tileentity.TileEntityPlayerSave; +import electroblob.wizardry.tileentity.TileEntityStatue; +import electroblob.wizardry.tileentity.TileEntityTimer; +import net.minecraft.entity.EnumCreatureType; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.WeightedRandomChestContent; +import net.minecraft.world.biome.BiomeGenBase; +import net.minecraftforge.common.ChestGenHooks; +import net.minecraftforge.oredict.OreDictionary; + +public final class WizardryRegistry { + + // Usage note on ChestGenHooks: First number is minimum, second is maximum. Third is rarity, lower numbers are more rare [bread = 100]. + // i starts at 1 here so that 'none' does not spawn. + // Earlier problem solved using clever forge hook - extend WeightedRandomChestContent and override generateChestContent. + // Apparently this seems to be incompatible with roguelike dungeons (any others?), in that it generates the same spell book in + // all of the chests that have a spell book in the same dungeon (usually, though it has been known to do different ones on + // different floors). It also appears to be able to generate the 'none' book, which should be impossible... never mind. + // I don't think that's my fault, or I would have seen a 'none' book in a vanilla dungeon by now. + // Another curious observation: Recurrent complex's generators also seem to always generate the same book/wand/armour + // until you restart the game and can generate the 'none' book as well. + // My best guess as to what's happening is that some mods hook into the dungeon loot differently to others, in that + // they take all the WeightedRandomChestContent objects once and pick from them each time rather than making new ones + // for each chest - which is, in theory, a more efficient way of doing things and will speed up world gen a bit, but + // does of course result in custom chest content implementations behaving strangely. The 'none' book thing remains a + // mystery, however. + + /** Called from the preInit method in the main mod class to register the custom dungeon loot. */ + public static void registerLoot(){ + + // The generate loot option only applies to vanilla chests, not wizard tower chests. + if(Wizardry.generateLoot){ + + String[] chestTypes = { + ChestGenHooks.DUNGEON_CHEST, + ChestGenHooks.PYRAMID_JUNGLE_CHEST, + ChestGenHooks.PYRAMID_DESERT_CHEST, + ChestGenHooks.MINESHAFT_CORRIDOR, + ChestGenHooks.STRONGHOLD_CORRIDOR, + ChestGenHooks.STRONGHOLD_CROSSING, + ChestGenHooks.STRONGHOLD_LIBRARY + }; + + for(String chest : chestTypes){ + + ChestGenHooks.addItem(chest, new WeightedRandomSpellBook(new ItemStack(Wizardry.spellBook), 1, 1, Wizardry.SPELL_BOOK_FREQUENCY)); + ChestGenHooks.addItem(chest, new WeightedRandomSpellBook(new ItemStack(Wizardry.magicWand), 1, 1, Wizardry.WAND_FREQUENCY)); + ChestGenHooks.addItem(chest, new WeightedRandomSpellBook(new ItemStack(Wizardry.wizardHat), 1, 1, Wizardry.ARMOUR_FREQUENCY)); + ChestGenHooks.addItem(chest, new WeightedRandomSpellBook(new ItemStack(Wizardry.scroll), 1, 1, Wizardry.SCROLL_FREQUENCY)); + ChestGenHooks.addItem(chest, new WeightedRandomSpellBook(new ItemStack(Wizardry.condenserUpgrade), 1, 1, Wizardry.WAND_UPGRADE_FREQUENCY)); + ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.magicCrystal), 1, 4, Wizardry.CRYSTAL_FREQUENCY)); + ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.arcaneTome, 1, 1), 1, 1, Wizardry.APPRENTICE_TOME_FREQUENCY)); + ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.arcaneTome, 1, 2), 1, 1, Wizardry.ADVANCED_TOME_FREQUENCY)); + ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.arcaneTome, 1, 3), 1, 1, Wizardry.MASTER_TOME_FREQUENCY)); + ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.armourUpgrade), 1, 1, Wizardry.ARMOUR_UPGRADE_FREQUENCY)); + ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.firebomb), 1, 5, Wizardry.FIREBOMB_FREQUENCY)); + ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.poisonBomb), 1, 5, Wizardry.POISON_BOMB_FREQUENCY)); + ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.smokeBomb), 1, 5, Wizardry.SMOKE_BOMB_FREQUENCY)); + if(Wizardry.discoveryMode) ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.identificationScroll), 1, 1, Wizardry.IDENTIFICATION_SCROLL_FREQUENCY)); + + } + } + + // Creates a new ChestGenHooks for wizard towers. + ChestGenHooks chestGen = ChestGenHooks.getInfo(WizardryWorldGenerator.WIZARD_TOWER); + chestGen.setMax(7); + chestGen.setMin(3); + + // Wizard tower chests use exactly the same things, minus the firebombs, poison bombs and smoke bombs + ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomSpellBook(new ItemStack(Wizardry.spellBook), 1, 1, Wizardry.SPELL_BOOK_FREQUENCY)); + ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomSpellBook(new ItemStack(Wizardry.magicWand), 1, 1, Wizardry.WAND_FREQUENCY)); + ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomSpellBook(new ItemStack(Wizardry.wizardHat), 1, 1, Wizardry.ARMOUR_FREQUENCY)); + ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomSpellBook(new ItemStack(Wizardry.scroll), 1, 1, Wizardry.SCROLL_FREQUENCY)); + ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomSpellBook(new ItemStack(Wizardry.condenserUpgrade), 1, 1, Wizardry.WAND_UPGRADE_FREQUENCY)); + ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomChestContent(new ItemStack(Wizardry.magicCrystal), 1, 4, Wizardry.CRYSTAL_FREQUENCY)); + ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomChestContent(new ItemStack(Wizardry.arcaneTome, 1, 1), 1, 1, Wizardry.APPRENTICE_TOME_FREQUENCY)); + ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomChestContent(new ItemStack(Wizardry.arcaneTome, 1, 2), 1, 1, Wizardry.ADVANCED_TOME_FREQUENCY)); + ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomChestContent(new ItemStack(Wizardry.arcaneTome, 1, 3), 1, 1, Wizardry.MASTER_TOME_FREQUENCY)); + ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomChestContent(new ItemStack(Wizardry.armourUpgrade), 1, 1, Wizardry.ARMOUR_UPGRADE_FREQUENCY)); + if(Wizardry.discoveryMode) ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomChestContent(new ItemStack(Wizardry.identificationScroll), 1, 1, Wizardry.IDENTIFICATION_SCROLL_FREQUENCY)); + + } + + /* The name defined here in the regitry is the one Minecraft uses in game for commands like /give, as + * opposed to the one defined earlier with setBlockName() or setUnlocalizedName() which is the one used by + * the lang files. Ideally these should both be the same, but I've written the lang file now, so... */ + + /** Called from the preInit method in the main mod class to register all the blocks. */ + public static void registerBlocks(){ + + GameRegistry.registerBlock(Wizardry.arcaneWorkbench, "arcane_workbench"); + GameRegistry.registerBlock(Wizardry.crystalOre, "crystal_ore"); + GameRegistry.registerBlock(Wizardry.petrifiedStone, "petrified_stone"); + GameRegistry.registerBlock(Wizardry.iceStatue, "ice_statue"); + GameRegistry.registerBlock(Wizardry.magicLight, "magic_light"); + GameRegistry.registerBlock(Wizardry.crystalFlower, "crystal_flower"); + GameRegistry.registerBlock(Wizardry.snare, "snare"); + GameRegistry.registerBlock(Wizardry.transportationStone, "transportation_stone"); + GameRegistry.registerBlock(Wizardry.spectralBlock, "spectral_block"); + GameRegistry.registerBlock(Wizardry.crystalBlock, "crystal_block"); + GameRegistry.registerBlock(Wizardry.meteor, "meteor"); + GameRegistry.registerBlock(Wizardry.vanishingCobweb, "vanishing_cobweb"); + } + + /** Called from the preInit method in the main mod class to register all the items. */ + public static void registerItems(){ + + GameRegistry.registerItem(Wizardry.magicCrystal, "magic_crystal"); + + GameRegistry.registerItem(Wizardry.magicWand, "magic_wand"); + GameRegistry.registerItem(Wizardry.apprenticeWand, "apprentice_wand"); + GameRegistry.registerItem(Wizardry.advancedWand, "advanced_wand"); + GameRegistry.registerItem(Wizardry.masterWand, "master_wand"); + + GameRegistry.registerItem(Wizardry.spellBook, "spell_book"); + GameRegistry.registerItem(Wizardry.arcaneTome, "arcane_tome"); + GameRegistry.registerItem(Wizardry.wizardHandbook, "wizard_handbook"); + + GameRegistry.registerItem(Wizardry.basicFireWand, "basic_fire_wand"); + GameRegistry.registerItem(Wizardry.basicIceWand, "basic_ice_wand"); + GameRegistry.registerItem(Wizardry.basicLightningWand, "basic_lightning_wand"); + GameRegistry.registerItem(Wizardry.basicNecromancyWand, "basic_necromancy_wand"); + GameRegistry.registerItem(Wizardry.basicEarthWand, "basic_earth_wand"); + GameRegistry.registerItem(Wizardry.basicSorceryWand, "basic_sorcery_wand"); + GameRegistry.registerItem(Wizardry.basicHealingWand, "basic_healing_wand"); + + GameRegistry.registerItem(Wizardry.apprenticeFireWand, "apprentice_fire_wand"); + GameRegistry.registerItem(Wizardry.apprenticeIceWand, "apprentice_ice_wand"); + GameRegistry.registerItem(Wizardry.apprenticeLightningWand, "apprentice_lightning_wand"); + GameRegistry.registerItem(Wizardry.apprenticeNecromancyWand, "apprentice_necromancy_wand"); + GameRegistry.registerItem(Wizardry.apprenticeEarthWand, "apprentice_earth_wand"); + GameRegistry.registerItem(Wizardry.apprenticeSorceryWand, "apprentice_sorcery_wand"); + GameRegistry.registerItem(Wizardry.apprenticeHealingWand, "apprentice_healing_wand"); + + GameRegistry.registerItem(Wizardry.advancedFireWand, "advanced_fire_wand"); + GameRegistry.registerItem(Wizardry.advancedIceWand, "advanced_ice_wand"); + GameRegistry.registerItem(Wizardry.advancedLightningWand, "advanced_lightning_wand"); + GameRegistry.registerItem(Wizardry.advancedNecromancyWand, "advanced_necromancy_wand"); + GameRegistry.registerItem(Wizardry.advancedEarthWand, "advanced_earth_wand"); + GameRegistry.registerItem(Wizardry.advancedSorceryWand, "advanced_sorcery_wand"); + GameRegistry.registerItem(Wizardry.advancedHealingWand, "advanced_healing_wand"); + + GameRegistry.registerItem(Wizardry.masterFireWand, "master_fire_wand"); + GameRegistry.registerItem(Wizardry.masterIceWand, "master_ice_wand"); + GameRegistry.registerItem(Wizardry.masterLightningWand, "master_lightning_wand"); + GameRegistry.registerItem(Wizardry.masterNecromancyWand, "master_necromancy_wand"); + GameRegistry.registerItem(Wizardry.masterEarthWand, "master_earth_wand"); + GameRegistry.registerItem(Wizardry.masterSorceryWand, "master_sorcery_wand"); + GameRegistry.registerItem(Wizardry.masterHealingWand, "master_healing_wand"); + + GameRegistry.registerItem(Wizardry.spectralSword, "spectral_sword"); + GameRegistry.registerItem(Wizardry.spectralPickaxe, "spectral_pickaxe"); + GameRegistry.registerItem(Wizardry.spectralBow, "spectral_bow"); + + GameRegistry.registerItem(Wizardry.manaFlask, "mana_flask"); + + GameRegistry.registerItem(Wizardry.storageUpgrade, "storage_upgrade"); + GameRegistry.registerItem(Wizardry.siphonUpgrade, "siphon_upgrade"); + GameRegistry.registerItem(Wizardry.condenserUpgrade, "condenser_upgrade"); + GameRegistry.registerItem(Wizardry.rangeUpgrade, "range_upgrade"); + GameRegistry.registerItem(Wizardry.durationUpgrade, "duration_upgrade"); + GameRegistry.registerItem(Wizardry.cooldownUpgrade, "cooldown_upgrade"); + GameRegistry.registerItem(Wizardry.blastUpgrade, "blast_upgrade"); + GameRegistry.registerItem(Wizardry.attunementUpgrade, "attunement_upgrade"); + + GameRegistry.registerItem(Wizardry.flamingAxe, "flaming_axe"); + GameRegistry.registerItem(Wizardry.frostAxe, "frost_axe"); + + GameRegistry.registerItem(Wizardry.firebomb, "firebomb"); + GameRegistry.registerItem(Wizardry.poisonBomb, "poison_bomb"); + + GameRegistry.registerItem(Wizardry.blankScroll, "blank_scroll"); + GameRegistry.registerItem(Wizardry.scroll, "scroll"); + + GameRegistry.registerItem(Wizardry.armourUpgrade, "armour_upgrade"); + + GameRegistry.registerItem(Wizardry.magicSilk, "magic_silk"); + + GameRegistry.registerItem(Wizardry.wizardHat, "wizard_hat"); + GameRegistry.registerItem(Wizardry.wizardRobe, "wizard_robe"); + GameRegistry.registerItem(Wizardry.wizardLeggings, "wizard_leggings"); + GameRegistry.registerItem(Wizardry.wizardBoots, "wizard_boots"); + + GameRegistry.registerItem(Wizardry.wizardHatFire, "wizard_hat_fire"); + GameRegistry.registerItem(Wizardry.wizardRobeFire, "wizard_robe_fire"); + GameRegistry.registerItem(Wizardry.wizardLeggingsFire, "wizard_leggings_fire"); + GameRegistry.registerItem(Wizardry.wizardBootsFire, "wizard_boots_fire"); + + GameRegistry.registerItem(Wizardry.wizardHatIce, "wizard_hat_ice"); + GameRegistry.registerItem(Wizardry.wizardRobeIce, "wizard_robe_ice"); + GameRegistry.registerItem(Wizardry.wizardLeggingsIce, "wizard_leggings_ice"); + GameRegistry.registerItem(Wizardry.wizardBootsIce, "wizard_boots_ice"); + + GameRegistry.registerItem(Wizardry.wizardHatLightning, "wizard_hat_lightning"); + GameRegistry.registerItem(Wizardry.wizardRobeLightning, "wizard_robe_lightning"); + GameRegistry.registerItem(Wizardry.wizardLeggingsLightning, "wizard_leggings_lightning"); + GameRegistry.registerItem(Wizardry.wizardBootsLightning, "wizard_boots_lightning"); + + GameRegistry.registerItem(Wizardry.wizardHatNecromancy, "wizard_hat_necromancy"); + GameRegistry.registerItem(Wizardry.wizardRobeNecromancy, "wizard_robe_necromancy"); + GameRegistry.registerItem(Wizardry.wizardLeggingsNecromancy, "wizard_leggings_necromancy"); + GameRegistry.registerItem(Wizardry.wizardBootsNecromancy, "wizard_boots_necromancy"); + + GameRegistry.registerItem(Wizardry.wizardHatEarth, "wizard_hat_earth"); + GameRegistry.registerItem(Wizardry.wizardRobeEarth, "wizard_robe_earth"); + GameRegistry.registerItem(Wizardry.wizardLeggingsEarth, "wizard_leggings_earth"); + GameRegistry.registerItem(Wizardry.wizardBootsEarth, "wizard_boots_earth"); + + GameRegistry.registerItem(Wizardry.wizardHatSorcery, "wizard_hat_sorcery"); + GameRegistry.registerItem(Wizardry.wizardRobeSorcery, "wizard_robe_sorcery"); + GameRegistry.registerItem(Wizardry.wizardLeggingsSorcery, "wizard_leggings_sorcery"); + GameRegistry.registerItem(Wizardry.wizardBootsSorcery, "wizard_boots_sorcery"); + + GameRegistry.registerItem(Wizardry.wizardHatHealing, "wizard_hat_healing"); + GameRegistry.registerItem(Wizardry.wizardRobeHealing, "wizard_robe_healing"); + GameRegistry.registerItem(Wizardry.wizardLeggingsHealing, "wizard_leggings_healing"); + GameRegistry.registerItem(Wizardry.wizardBootsHealing, "wizard_boots_healing"); + + GameRegistry.registerItem(Wizardry.spawnWizard, "spawn_wizard"); + + GameRegistry.registerItem(Wizardry.spectralHelmet, "spectral_helmet"); + GameRegistry.registerItem(Wizardry.spectralChestplate, "spectral_chestplate"); + GameRegistry.registerItem(Wizardry.spectralLeggings, "spectral_leggings"); + GameRegistry.registerItem(Wizardry.spectralBoots, "spectral_boots"); + + GameRegistry.registerItem(Wizardry.smokeBomb, "smoke_bomb"); + + GameRegistry.registerItem(Wizardry.identificationScroll, "identification_scroll"); + } + + /** Called from the preInit method in the main mod class to register all the tileentities. */ + public static void registerTileEntities(){ + + GameRegistry.registerTileEntity(TileEntityArcaneWorkbench.class, Wizardry.MODID + "ArcaneWorkbenchTileEntity"); + GameRegistry.registerTileEntity(TileEntityStatue.class, Wizardry.MODID + "PetrifiedStoneTileEntity"); + GameRegistry.registerTileEntity(TileEntityMagicLight.class, Wizardry.MODID + "MagicLightTileEntity"); + GameRegistry.registerTileEntity(TileEntityTimer.class, Wizardry.MODID + "TimerTileEntity"); + GameRegistry.registerTileEntity(TileEntityPlayerSave.class, Wizardry.MODID + "TileEntityPlayerSave"); + } + + /** Called from the preInit method in the main mod class to register all the entities. */ + public static void registerEntities(Wizardry wizardry){ + + int id = 0; // Incrementable index for the mod specific entity id. + + EntityRegistry.registerModEntity(EntityZombieMinion.class, "Zombie Minion", id++, wizardry, 128, 3, true); + EntityRegistry.registerModEntity(EntityMagicMissile.class, "Magic Missile", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityArc.class, "Arc", id++, wizardry, 128, 10, false); + EntityRegistry.registerModEntity(EntitySkeletonMinion.class, "Skeleton Minion", id++, wizardry, 128, 3, true); + EntityRegistry.registerModEntity(EntitySparkBomb.class, "Spark Bomb", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntitySpiritWolf.class, "Spirit Wolf", id++, wizardry, 128, 3, true); + EntityRegistry.registerModEntity(EntityIceShard.class, "Ice Shard", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityBlazeMinion.class, "Blaze Minion", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityIceWraith.class, "Ice Wraith", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityLightningWraith.class, "Lightning Wraith", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityBlackHole.class, "Black Hole", id++, wizardry, 128, 10, false); + EntityRegistry.registerModEntity(EntityShield.class, "Shield", id++, wizardry, 128, 1, true); + EntityRegistry.registerModEntity(EntityMeteor.class, "Meteor", id++, wizardry, 128, 5, true); + EntityRegistry.registerModEntity(EntityBlizzard.class, "Blizzard", id++, wizardry, 128, 10, false); + EntityRegistry.registerModEntity(EntityWizard.class, "Wizard", id++, wizardry, 128, 3, true); + EntityRegistry.registerModEntity(EntityBubble.class, "Bubble", id++, wizardry, 128, 3, false); + EntityRegistry.registerModEntity(EntityTornado.class, "Tornado", id++, wizardry, 128, 1, false); + EntityRegistry.registerModEntity(EntityHammer.class, "Lightning Hammer", id++, wizardry, 128, 1, true); + EntityRegistry.registerModEntity(EntityFirebomb.class, "Firebomb", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityForceOrb.class, "Force Orb", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityArrowRain.class, "Arrow Rain", id++, wizardry, 128, 10, false); + EntityRegistry.registerModEntity(EntitySpark.class, "Spark", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityShadowWraith.class, "Shadow Wraith", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityDarknessOrb.class, "Darkness Orb", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntitySpiderMinion.class, "Spider Minion", id++, wizardry, 128, 3, true); + EntityRegistry.registerModEntity(EntityHealAura.class, "Healing Aura", id++, wizardry, 128, 10, false); + EntityRegistry.registerModEntity(EntityFireSigil.class, "Fire Sigil", id++, wizardry, 128, 10, false); + EntityRegistry.registerModEntity(EntityFrostSigil.class, "Frost Sigil", id++, wizardry, 128, 10, false); + EntityRegistry.registerModEntity(EntityLightningSigil.class, "Lightning Sigil", id++, wizardry, 128, 10, false); + EntityRegistry.registerModEntity(EntityLightningArrow.class, "Lightning Arrow", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityFirebolt.class, "Firebolt", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityPoisonBomb.class, "Poison Bomb", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityIceCharge.class, "Ice Charge", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityForceArrow.class, "Force Arrow", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityDart.class, "Dart", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityMagicSlime.class, "Magic Slime", id++, wizardry, 128, 3, true); + EntityRegistry.registerModEntity(EntityForcefield.class, "Forcefield", id++, wizardry, 128, 10, false); + EntityRegistry.registerModEntity(EntityFireRing.class, "Ring of Fire", id++, wizardry, 128, 10, false); + EntityRegistry.registerModEntity(EntityLightningDisc.class, "Lightning Disc", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityThunderbolt.class, "Thunderbolt", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityIceGiant.class, "Ice Giant", id++, wizardry, 128, 3, true); + EntityRegistry.registerModEntity(EntitySpiritHorse.class, "Spirit Horse", id++, wizardry, 128, 3, true); + EntityRegistry.registerModEntity(EntityPhoenix.class, "Phoenix", id++, wizardry, 128, 3, true); + EntityRegistry.registerModEntity(EntitySilverfishMinion.class, "Silverfish Minion", id++, wizardry, 128, 3, true); + EntityRegistry.registerModEntity(EntityDecay.class, "Decay", id++, wizardry, 128, 10, false); + EntityRegistry.registerModEntity(EntityStormElemental.class, "Storm Elemental", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityEarthquake.class, "Earthquake", id++, wizardry, 128, 10, false); + EntityRegistry.registerModEntity(EntityFallingGrass.class, "Falling Grass", id++, wizardry, 128, 5, true); + EntityRegistry.registerModEntity(EntityIceLance.class, "Ice Lance", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityHailstorm.class, "Hailstorm", id++, wizardry, 128, 10, false); + EntityRegistry.registerModEntity(EntitySmokeBomb.class, "Smoke Bomb", id++, wizardry, 128, 10, true); + EntityRegistry.registerModEntity(EntityEvilWizard.class, "Evil Wizard", id++, wizardry, 128, 3, true); + EntityRegistry.registerModEntity(EntityDecoy.class, "Decoy", id++, wizardry, 128, 3, true); + EntityRegistry.registerModEntity(EntityIceSpike.class, "Ice Spike", id++, wizardry, 128, 1, true); + EntityRegistry.registerModEntity(EntityLightningPulse.class, "Lightning Pulse", id++, wizardry, 128, 10, false); + + List biomes = new ArrayList(); + for(BiomeGenBase biome : BiomeGenBase.getBiomeGenArray()){ + if(biome != null){ + biomes.add(biome); + } + } + // For reference: 5, 1, 1 are the parameters for the witch in vanilla. + EntityRegistry.addSpawn(EntityEvilWizard.class, 3, 1, 1, EnumCreatureType.monster, biomes.toArray(new BiomeGenBase[biomes.size()])); + + } + + /** Static instance of the none spell, used for various purposes. */ + public static Spell none; + /** Static instance of the magic missile spell, used for crafting spell books and by wizards. */ + public static Spell magicMissile; + /** Static instance of the transportation spell, used for chat messages. */ + public static Spell transportation; + /** Static instance of the clairvoyance spell, used for chat messages. */ + public static Spell clairvoyance; + + /** Called from the preInit method in the main mod class to register all the spells in wizardry. */ + public static void registerSpells(){ + + // Wizardry 1.0 spells + + Spell.register(none = new None()); + Spell.register(magicMissile = new MagicMissile()); + Spell.register(new Ignite()); + Spell.register(new Freeze()); + Spell.register(new Snowball()); + Spell.register(new Arc()); + Spell.register(new Thunderbolt()); + Spell.register(new SummonZombie()); + Spell.register(new Snare()); + Spell.register(new Dart()); + Spell.register(new Light()); + Spell.register(new Telekinesis()); + Spell.register(new Heal()); + + Spell.register(new Fireball()); + Spell.register(new FlameRay()); + Spell.register(new Firebomb()); + Spell.register(new FireSigil()); + Spell.register(new Firebolt()); + Spell.register(new FrostRay()); + Spell.register(new SummonSnowGolem()); + Spell.register(new IceShard()); + Spell.register(new IceStatue()); + Spell.register(new FrostSigil()); + Spell.register(new LightningRay()); + Spell.register(new SparkBomb()); + Spell.register(new HomingSpark()); + Spell.register(new LightningSigil()); + Spell.register(new LightningArrow()); + Spell.register(new LifeDrain()); + Spell.register(new SummonSkeleton()); + Spell.register(new Metamorphosis()); + Spell.register(new Wither()); + Spell.register(new Poison()); + Spell.register(new GrowthAura()); + Spell.register(new Bubble()); + Spell.register(new Whirlwind()); + Spell.register(new PoisonBomb()); + Spell.register(new SummonSpiritWolf()); + Spell.register(new Blink()); + Spell.register(new Agility()); + Spell.register(new ConjureSword()); + Spell.register(new ConjurePickaxe()); + Spell.register(new ConjureBow()); + Spell.register(new ForceArrow()); + Spell.register(new Shield()); + Spell.register(new ReplenishHunger()); + Spell.register(new CureEffects()); + Spell.register(new HealAlly()); + + Spell.register(new SummonBlaze()); + Spell.register(new RingOfFire()); + Spell.register(new Detonate()); + Spell.register(new FireResistance()); + Spell.register(new Fireskin()); + Spell.register(new FlamingAxe()); + Spell.register(new Blizzard()); + Spell.register(new SummonIceWraith()); + Spell.register(new IceShroud()); + Spell.register(new IceCharge()); + Spell.register(new FrostAxe()); + Spell.register(new InvokeWeather()); + Spell.register(new ChainLightning()); + Spell.register(new LightningBolt()); + Spell.register(new SummonLightningWraith()); + Spell.register(new StaticAura()); + Spell.register(new LightningDisc()); + Spell.register(new MindControl()); + Spell.register(new SummonWitherSkeleton()); + Spell.register(new Entrapment()); + Spell.register(new WitherSkull()); + Spell.register(new DarknessOrb()); + Spell.register(new ShadowWard()); + Spell.register(new Decay()); + Spell.register(new WaterBreathing()); + Spell.register(new Tornado()); + Spell.register(new Glide()); + Spell.register(new SummonSpiritHorse()); + Spell.register(new SpiderSwarm()); + Spell.register(new Slime()); + Spell.register(new Petrify()); + Spell.register(new Invisibility()); + Spell.register(new Levitation()); + Spell.register(new ForceOrb()); + Spell.register(transportation = new Transportation()); + Spell.register(new SpectralPathway()); + Spell.register(new PhaseStep()); + Spell.register(new VanishingBox()); + Spell.register(new GreaterHeal()); + Spell.register(new HealingAura()); + Spell.register(new Forcefield()); + Spell.register(new Ironflesh()); + Spell.register(new Transience()); + + Spell.register(new Meteor()); + Spell.register(new Firestorm()); + Spell.register(new SummonPhoenix()); + Spell.register(new IceAge()); + Spell.register(new WallOfFrost()); + Spell.register(new SummonIceGiant()); + Spell.register(new Thunderstorm()); + Spell.register(new LightningHammer()); + Spell.register(new PlagueOfDarkness()); + Spell.register(new SummonSkeletonLegion()); + Spell.register(new SummonShadowWraith()); + Spell.register(new ForestsCurse()); + Spell.register(new Flight()); + Spell.register(new SilverfishSwarm()); + Spell.register(new BlackHole()); + Spell.register(new Shockwave()); + Spell.register(new SummonIronGolem()); + Spell.register(new ArrowRain()); + Spell.register(new Diamondflesh()); + Spell.register(new FontOfVitality()); + + // Wizardry 1.1 spells + + Spell.register(new SmokeBomb()); + Spell.register(new MindTrick()); + Spell.register(new Leap()); + + Spell.register(new PocketFurnace()); + Spell.register(new Intimidate()); + Spell.register(new Banish()); + Spell.register(new SixthSense()); + Spell.register(new Darkvision()); + Spell.register(clairvoyance = new Clairvoyance()); + Spell.register(new PocketWorkbench()); + Spell.register(new ImbueWeapon()); + Spell.register(new InvigoratingPresence()); + Spell.register(new Oakflesh()); + + Spell.register(new GreaterFireball()); + Spell.register(new FlamingWeapon()); + Spell.register(new IceLance()); + Spell.register(new FreezingWeapon()); + Spell.register(new IceSpikes()); + Spell.register(new LightningPulse()); + Spell.register(new CurseOfSoulbinding()); + Spell.register(new Cobwebs()); + Spell.register(new Decoy()); + Spell.register(new ArcaneJammer()); + Spell.register(new ConjureArmour()); + Spell.register(new GroupHeal()); + + Spell.register(new Hailstorm()); + Spell.register(new LightningWeb()); + Spell.register(new SummonStormElemental()); + Spell.register(new Earthquake()); + Spell.register(new FontOfMana()); + } + + /** Called from the init method in the main mod class to register all the recipes. */ + public static void registerRecipes(){ + + ItemStack ironIngotStack = new ItemStack(Items.iron_ingot); + ItemStack magicCrystalStack = new ItemStack(Wizardry.magicCrystal); + ItemStack magicWandStack = new ItemStack(Wizardry.magicWand, 1, EnumTier.BASIC.maxCharge); + ItemStack goldNuggetStack = new ItemStack(Items.gold_nugget); + ItemStack stickStack = new ItemStack(Items.stick); + ItemStack bookStack = new ItemStack(Items.book); + ItemStack stringStack = new ItemStack(Items.string); + ItemStack spellBookStack = new ItemStack(Wizardry.spellBook, 1, WizardryRegistry.magicMissile.id()); + ItemStack arcaneWorkbenchStack = new ItemStack(Wizardry.arcaneWorkbench); + ItemStack stoneStack = new ItemStack(Blocks.stone); + ItemStack lapisBlockStack = new ItemStack(Blocks.lapis_block); + ItemStack purpleCarpetStack = new ItemStack(Blocks.carpet, 1, 10); + ItemStack wizardHandbookStack = new ItemStack(Wizardry.wizardHandbook); + ItemStack crystalFlowerStack = new ItemStack(Wizardry.crystalFlower); + ItemStack magicCrystalStack1 = new ItemStack(Wizardry.magicCrystal, 2); + ItemStack magicCrystalStack2 = new ItemStack(Wizardry.magicCrystal, 9); + ItemStack crystalBlockStack = new ItemStack(Wizardry.crystalBlock); + ItemStack manaFlaskStack = new ItemStack(Wizardry.manaFlask); + ItemStack bottleStack = new ItemStack(Items.glass_bottle); + ItemStack gunpowderStack = new ItemStack(Items.gunpowder); + ItemStack blazePowderStack = new ItemStack(Items.blaze_powder); + ItemStack spiderEyeStack = new ItemStack(Items.spider_eye); + // Coal or charcoal is equally fine, hence the wildcard value + ItemStack coalStack = new ItemStack(Items.coal, 1, OreDictionary.WILDCARD_VALUE); + ItemStack firebombStack = new ItemStack(Wizardry.firebomb, 3); + ItemStack poisonBombStack = new ItemStack(Wizardry.poisonBomb, 3); + ItemStack smokeBombStack = new ItemStack(Wizardry.smokeBomb, 3); + ItemStack transportationStoneStack = new ItemStack(Wizardry.transportationStone, 2); + ItemStack silkStack = new ItemStack(Wizardry.magicSilk); + ItemStack silkStack1 = new ItemStack(Wizardry.magicSilk, 2); + ItemStack hatStack = new ItemStack(Wizardry.wizardHat); + ItemStack robeStack = new ItemStack(Wizardry.wizardRobe); + ItemStack leggingsStack = new ItemStack(Wizardry.wizardLeggings); + ItemStack bootsStack = new ItemStack(Wizardry.wizardBoots); + ItemStack scrollStack = new ItemStack(Wizardry.blankScroll); + ItemStack paperStack = new ItemStack(Items.paper); + + GameRegistry.addRecipe(magicWandStack, " x", " y ", "z ", 'x', magicCrystalStack, 'y', stickStack, 'z', goldNuggetStack); + GameRegistry.addRecipe(spellBookStack, " x ", "xyx", " x ", 'x', magicCrystalStack, 'y', bookStack); + GameRegistry.addRecipe(arcaneWorkbenchStack, "vwv", "xyx", "zzz", 'v', goldNuggetStack, 'w', purpleCarpetStack, 'x', magicCrystalStack, 'y', lapisBlockStack, 'z', stoneStack); + GameRegistry.addRecipe(manaFlaskStack, "yyy", "yxy", "yyy", 'x', bottleStack, 'y', magicCrystalStack); + GameRegistry.addRecipe(transportationStoneStack, " x ", "xyx", " x ", 'x', stoneStack, 'y', magicCrystalStack); + GameRegistry.addRecipe(hatStack, "yyy", "y y", 'y', silkStack); + GameRegistry.addRecipe(robeStack, "y y", "yyy", "yyy", 'y', silkStack); + GameRegistry.addRecipe(leggingsStack, "yyy", "y y", "y y", 'y', silkStack); + GameRegistry.addRecipe(bootsStack, "y y", "y y", 'y', silkStack); + GameRegistry.addRecipe(silkStack1, " x ", "xyx", " x ", 'x', stringStack, 'y', magicCrystalStack); + GameRegistry.addRecipe(crystalBlockStack, "zzz", "zzz", "zzz", 'z', magicCrystalStack); + + GameRegistry.addShapelessRecipe(wizardHandbookStack, bookStack, magicCrystalStack); + GameRegistry.addShapelessRecipe(magicCrystalStack1, crystalFlowerStack); + GameRegistry.addShapelessRecipe(magicCrystalStack2, crystalBlockStack); + if(Wizardry.firebombIsCraftable) GameRegistry.addShapelessRecipe(firebombStack, bottleStack, gunpowderStack, blazePowderStack, blazePowderStack); + if(Wizardry.poisonBombIsCraftable) GameRegistry.addShapelessRecipe(poisonBombStack, bottleStack, gunpowderStack, spiderEyeStack, spiderEyeStack); + if(Wizardry.smokeBombIsCraftable) GameRegistry.addShapelessRecipe(smokeBombStack, bottleStack, gunpowderStack, coalStack, coalStack); + if(Wizardry.useAlternateScrollRecipe){ + GameRegistry.addShapelessRecipe(scrollStack, paperStack, stringStack, magicCrystalStack); + }else{ + GameRegistry.addShapelessRecipe(scrollStack, paperStack, stringStack); + } + + + // Mana flask recipes + ItemStack miscWandStack; + + for(int i=0; i getEntitiesWithinRadius(double radius, double x, double y, double z, World world){ + return getEntitiesWithinRadius(radius, x, y, z, world, EntityLivingBase.class); + } + + /** + * Returns all entities of the specified type within the specified radius of the given coordinates. This is different to using + * a raw AABB because a raw AABB will search in a cube volume rather than a sphere. + * Note that this does not exclude any entities; if any specific entities are to be excluded this must be + * checked when iterating through the list. + * @see {@link WizardryUtilities#getEntitiesWithinRadius(double, double, double, double, World)} + * @param radius The search radius + * @param x The x coordinate to search around + * @param y The y coordinate to search around + * @param z The z coordinate to search around + * @param world The world to search in + * @param entityType The class of entity to search for; pass in Entity.class for all entities + */ + public static List getEntitiesWithinRadius(double radius, double x, double y, double z, World world, Class entityType){ + AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(x - radius, y - radius, z - radius, x + radius, y + radius, z + radius); + List entityList = world.getEntitiesWithinAABB(entityType, aabb); + for(int i=0;i radius){ + entityList.remove(i); + } + } + return entityList; + } + + // ^ Handy syntax using type parameters here! + // I *think* that eclipse, for whatever reason, was not showing an 'unchecked' warning here. If you think about it, + // if this method returns a generic list type I could, in theory, put strings or something in it and then when + // invoking the method store its result as a List, which would cause a ClassCastException. Using + // this handy syntax prevents that from happening. TL;DR: Always use type parameters when available, they're there + // for a reason. Minecraft is bad in this respect because it doesn't use them in places like World. + + /** + * Gets an entity from its UUID. Note that you should check this isn't null. + * @param world The world the entity is in + * @param id The entity's UUID + * @return The Entity that has the given UUID, or null if no such entity exists in the specified world. + */ + public static Entity getEntityByUUID(World world, UUID id){ + for(Object object : world.loadedEntityList){ + if(object instanceof Entity){ + Entity entity = (Entity)object; + // This is a perfect example of where you need to use .equals() and not ==. For most applications, + // this was unnoticeable until world reload because the UUID instance or entity instance is stored. + // Fixed now though. Of course, you could alternatively compare the string representations. + if(entity.getUniqueID().equals(id)){ + return entity; + } + } + } + return null; + } + + /** + * Does a block ray trace (NOT entities) from an entity's eyes (i.e. properly...) + */ + public static MovingObjectPosition rayTrace(double range, World world, EntityLivingBase entity, boolean hitLiquids) + { + Vec3 vec3 = Vec3.createVectorHelper(entity.posX, entity.posY + entity.getEyeHeight(), entity.posZ); + Vec3 vec31 = entity.getLookVec(); + Vec3 vec32 = vec3.addVector(vec31.xCoord * range, vec31.yCoord * range, vec31.zCoord * range); + return world.rayTraceBlocks(vec3, vec32, hitLiquids); + } + + /** + * Helper method which does a rayTrace for entities from an entity's eye level in the direction they are looking + * with a specified range, using the tracePath method. Tidies up the code a bit. Border size defaults to 1. + * + * @param world + * @param entity + * @param range + * @return + */ + public static MovingObjectPosition standardEntityRayTrace(World world, EntityLivingBase entity, double range){ + double dx = entity.getLookVec().xCoord * range; + double dy = entity.getLookVec().yCoord * range; + double dz = entity.getLookVec().zCoord * range; + HashSet hashset = new HashSet(1); + hashset.add(entity); + return WizardryUtilities.tracePath(world, (float)entity.posX, (float)(entity.posY + entity.getEyeHeight()), (float)entity.posZ, (float)(entity.posX + dx), (float)(entity.posY + entity.getEyeHeight() + dy), (float)(entity.posZ + dz), 1.0f, hashset, false); + } + + /** + * Helper method which does a rayTrace for entities from a entity's eye level in the direction they are looking + * with a specified range and radius, using the tracePath method. Tidies up the code a bit. + * + * @param world + * @param entity + * @param range + * @param borderSize + * @return + */ + public static MovingObjectPosition standardEntityRayTrace(World world, EntityLivingBase entity, double range, float borderSize){ + double dx = entity.getLookVec().xCoord * range; + double dy = entity.getLookVec().yCoord * range; + double dz = entity.getLookVec().zCoord * range; + HashSet hashset = new HashSet(1); + hashset.add(entity); + return WizardryUtilities.tracePath(world, (float)entity.posX, (float)(entity.posY + entity.getEyeHeight()), (float)entity.posZ, (float)(entity.posX + dx), (float)(entity.posY + entity.getEyeHeight() + dy), (float)(entity.posZ + dz), borderSize, hashset, false); + } + + /** + * Method for ray tracing entities (the useless default method doesn't work, despite EnumHitType having an ENTITY field...) + * You can also use this for seeking. + * + * @param world + * @param x startX + * @param y startY + * @param z startZ + * @param tx endX + * @param ty endY + * @param tz endZ + * @param borderSize extra area to examine around line for entities + * @param excluded any excluded entities (the player, etc) + * @return a MovingObjectPosition of either the block hit (no entity hit), the entity hit (hit an entity), or null for nothing hit + */ + public static MovingObjectPosition tracePath(World world, float x, float y, float z, float tx, float ty, float tz, float borderSize, HashSet excluded, boolean collideablesOnly){ + + Vec3 startVec = Vec3.createVectorHelper(x, y, z); + Vec3 lookVec = Vec3.createVectorHelper(tx-x, ty-y, tz-z); + Vec3 endVec = Vec3.createVectorHelper(tx, ty, tz); + float minX = x < tx ? x : tx; + float minY = y < ty ? y : ty; + float minZ = z < tz ? z : tz; + float maxX = x > tx ? x : tx; + float maxY = y > ty ? y : ty; + float maxZ = z > tz ? z : tz; + AxisAlignedBB bb = AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ).expand(borderSize, borderSize, borderSize); + List allEntities = world.getEntitiesWithinAABBExcludingEntity(null, bb); + MovingObjectPosition blockHit = world.rayTraceBlocks(startVec, endVec); + startVec = Vec3.createVectorHelper(x, y, z); + endVec = Vec3.createVectorHelper(tx, ty, tz); + float maxDistance = (float) endVec.distanceTo(startVec); + if(blockHit!=null) + { + maxDistance = (float) blockHit.hitVec.distanceTo(startVec); + } + Entity closestHitEntity = null; + float closestHit = maxDistance; + float currentHit = 0.f; + AxisAlignedBB entityBb;// = ent.getBoundingBox(); + MovingObjectPosition intercept; + for(Entity ent : allEntities) + { + if((ent.canBeCollidedWith() || !collideablesOnly) && ((excluded != null && !excluded.contains(ent)) || excluded == null)) + { + float entBorder = ent.getCollisionBorderSize(); + entityBb = ent.boundingBox; + if(entityBb!=null) + { + entityBb = entityBb.expand(entBorder, entBorder, entBorder); + intercept = entityBb.calculateIntercept(startVec, endVec); + if(intercept!=null) + { + currentHit = (float) intercept.hitVec.distanceTo(startVec); + if(currentHit < closestHit || currentHit==0) + { + closestHit = currentHit; + closestHitEntity = ent; + } + } + } + } + } + if(closestHitEntity!=null) + { + blockHit = new MovingObjectPosition(closestHitEntity); + } + return blockHit; + } + + // Just what benefit does having posY be the eye position on the first person client actually give? + + /** + * Gets the y coordinate of the given player's eyes. This is to cover an inconsistency between the value of + * EntityPlayer.posY on the first person client and everywhere else; in first person (i.e. when + * Minecraft.getMinecraft().thePlayer == player) player.posY is the eye position, but everywhere else it is the + * feet position. This is intended for use when spawning particles, since this is the only situation where the + * discrepancy is likely to matter. + */ + public static double getPlayerEyesPos(EntityPlayer player){ + return Wizardry.proxy.getPlayerEyesPos(player); + } + + /** + * Gets the y coordinate of the given entity's feet. This is to cover an inconsistency between the value of + * EntityPlayer.posY on the first person client and everywhere else; in first person (i.e. when + * Minecraft.getMinecraft().thePlayer == player) player.posY is the eye position, but everywhere else it is the + * feet position. This is intended for use when spawning particles, since this is the only situation where the + * discrepancy is likely to matter. + */ + public static double getEntityFeetPos(Entity entity){ + if(entity instanceof EntityPlayer){ + // For some reason, EntityPlayer.getEyeHeight() always returns 0.12, so I have replicated the behaviour + // of the same method from EntityLivingBase and subtracted that instead. + return getPlayerEyesPos((EntityPlayer)entity) - entity.height*0.85f; + }else{ + return entity.posY; + } + } + + /** + * Verifies that the given string is a valid string representation of a UUID. More specifically, returns true if and + * only if the given string is not null and matches the regular expression:

    + *

    /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/

    + * which is the regex equivlent of the standard string representation of a UUID as described in {@link UUID#toString()}. + * This method is intended to be used as a check to prevent an {@link IllegalArgumentException} from occurring when + * calling {@link UUID#fromString(String)}. + * @param string The string to be checked + * @return Whether the given string is a valid string representation of a UUID + */ + public static boolean verifyUUIDString(String string){ + return string != null && string.matches("/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/"); + } + + /** + * Returns whether the given target can be attacked by the given attacker. It is up to the caller of this method + * to work out what this means; it doesn't necessarily mean the target is completely immune (for example, revenge + * targeting might reasonably bypass this). This method is intended for use where the damage is indirect and/or + * unavoidable; direct attacks should not check this method. Currently this means the following situations check + * this method: + *

    + * - AI targeting for summoned creatures
    + * - AI targeting for mind-controlled creatures
    + * - Constructs with an area of effect
    + * - Instantaneous spells with an area of effect around the caster (e.g. forest's curse, thunderstorm)
    + * - Any lightning chaining effects
    + * - Any projectiles which seek targets + *

    + * Also note that the friendly fire option is dealt with + * in the event handler. This method acts as a sort of wrapper for all the ADS stuff in {@link ExtendedPlayer}; more + * details about the ally designation system can be found there. + * + * @param attacker The entity that cast the spell originally + * @param target The entity being attacked + * + * @return False under any of the following circumstances, true otherwise: + *

    + * - The target is the attacker (this isn't as stupid as it sounds - anything with an AoE might cause this to be + * true, as can summoned creatures) + *

    + * - The target and the attacker are both players and the target is an ally of the attacker (but the + * attacker need not be an ally of the target) + *

    + * - The target is a creature that was summoned/controlled by the attacker or by an ally of the attacker. + */ + public static boolean isValidTarget(Entity attacker, Entity target){ + + // Don't need to check if either entity is null since instanceof does this anyway. + + // Tests whether the target is the attacker + if(target == attacker) return false; + + // Tests whether the target is a creature that was summoned by the attacker + if(target instanceof EntitySummonedCreature && ((EntitySummonedCreature)target).getCaster() == attacker){ + return false; + } + + // Tests whether the target is a creature that was mind controlled by the attacker + if(target instanceof EntityLiving && ((EntityLivingBase)target).isPotionActive(Wizardry.mindControl)){ + + NBTTagCompound entityNBT = target.getEntityData(); + + if(entityNBT != null && entityNBT.hasKey(MindControl.NBT_KEY)){ + if(attacker == WizardryUtilities.getEntityByUUID(target.worldObj, UUID.fromString(entityNBT.getString(MindControl.NBT_KEY)))){ + return false; + } + } + } + + // Ally section + if(attacker instanceof EntityPlayer && ExtendedPlayer.get((EntityPlayer)attacker) != null){ + + if(target instanceof EntityPlayer){ + // Tests whether the target is an ally of the attacker + if(ExtendedPlayer.get((EntityPlayer)attacker).isPlayerAlly((EntityPlayer)target)){ + return false; + } + + }else if(target instanceof EntitySummonedCreature){ + // Tests whether the target is a creature that was summoned by an ally of the attacker + if(((EntitySummonedCreature)target).getCaster() instanceof EntityPlayer + && ExtendedPlayer.get((EntityPlayer)attacker).isPlayerAlly((EntityPlayer)((EntitySummonedCreature)target).getCaster())){ + return false; + } + + }else if(target instanceof EntityLiving && ((EntityLivingBase)target).isPotionActive(Wizardry.mindControl)){ + // Tests whether the target is a creature that was mind controlled by an ally of the attacker + NBTTagCompound entityNBT = target.getEntityData(); + + if(entityNBT != null && entityNBT.hasKey(MindControl.NBT_KEY)){ + + Entity controller = WizardryUtilities.getEntityByUUID(target.worldObj, UUID.fromString(entityNBT.getString(MindControl.NBT_KEY))); + + if(controller instanceof EntityPlayer && ExtendedPlayer.get((EntityPlayer)attacker).isPlayerAlly((EntityPlayer)controller)){ + return false; + } + } + } + } + + return true; + } + + /** Helper method for testing if the second player is an ally of the first player. Makes the code neater. */ + public static boolean isPlayerAlly(EntityPlayer allyOf, EntityPlayer possibleAlly) { + + ExtendedPlayer properties = ExtendedPlayer.get(allyOf); + + if(properties != null && properties.isPlayerAlly(possibleAlly)) return true; + + return false; + } + + /** + * See {@link WizardryUtilities#getStandardWeightedRandomSpellId(Random, boolean)}. isContinuous defaults to false. + */ + public static int getStandardWeightedRandomSpellId(Random random){ + return getStandardWeightedRandomSpellId(random, false); + } + + /** + * Helper method which gets a spell id according to the standard weighting. The tier is a weighted random value; + * the actual spell within that tier is completely random. Will not return the id of a spell which has been + * disabled in the config. This is for simple stuff like chests and drops; more complex generators like wizard + * trades don't use this method. + *

    + * For reference, the standard weighting is as follows: + * Basic: 60%, Apprentice: 25%, Advanced: 10%, Master: 5% + * + * @param random An instance of the Random class + * @param nonContinuous Whether the spells must be non-continuous (used for scrolls) + * @return A random spell id number + */ + public static int getStandardWeightedRandomSpellId(Random random, boolean nonContinuous){ + + int randomiser = random.nextInt(20); + EnumTier tier; + + if(randomiser < 12){ + tier = EnumTier.BASIC; + }else if(randomiser < 17){ + tier = EnumTier.APPRENTICE; + }else if(randomiser < 19){ + tier = EnumTier.ADVANCED; + }else{ + tier = EnumTier.MASTER; + } + + List spells = Spell.getSpells(new Spell.TierElementFilter(tier, null)); + if(nonContinuous) spells.retainAll(Spell.getSpells(Spell.nonContinuousSpells)); + + // Ensures the tier chosen actually has spells in it, and if not uses BASIC instead. BASIC always has at least + // the NONE spell since this spell cannot be disabled. + if(spells.isEmpty()){ + spells = Spell.getSpells(new Spell.TierElementFilter(EnumTier.BASIC, null)); + if(nonContinuous) spells.retainAll(Spell.getSpells(Spell.nonContinuousSpells)); + } + + // Finds a random spell in the list and returns its id. + return spells.get(random.nextInt(spells.size())).id(); + } + + /** + * Helper method to return the appropriate armour item based on element and slot. + * Currently used to iterate through armour for registering charging recipes and for chest generation. + * @param slot 0 = head, 1 = body, 2 = legs, 3 = feet + */ + public static Item getArmour(EnumElement element, int slot){ + Item armour = null; + if(element == null){ + switch(slot){ + case 0: + armour = Wizardry.wizardHat; + break; + case 1: + armour = Wizardry.wizardRobe; + break; + case 2: + armour = Wizardry.wizardLeggings; + break; + case 3: + armour = Wizardry.wizardBoots; + break; + default: + break; + } + }else{ + switch(element){ + case FIRE: + switch(slot){ + case 0: + armour = Wizardry.wizardHatFire; + break; + case 1: + armour = Wizardry.wizardRobeFire; + break; + case 2: + armour = Wizardry.wizardLeggingsFire; + break; + case 3: + armour = Wizardry.wizardBootsFire; + break; + default: + break; + } + break; + case HEALING: + switch(slot){ + case 0: + armour = Wizardry.wizardHatHealing; + break; + case 1: + armour = Wizardry.wizardRobeHealing; + break; + case 2: + armour = Wizardry.wizardLeggingsHealing; + break; + case 3: + armour = Wizardry.wizardBootsHealing; + break; + default: + break; + } + break; + case ICE: + switch(slot){ + case 0: + armour = Wizardry.wizardHatIce; + break; + case 1: + armour = Wizardry.wizardRobeIce; + break; + case 2: + armour = Wizardry.wizardLeggingsIce; + break; + case 3: + armour = Wizardry.wizardBootsIce; + break; + default: + break; + } + break; + case LIGHTNING: + switch(slot){ + case 0: + armour = Wizardry.wizardHatLightning; + break; + case 1: + armour = Wizardry.wizardRobeLightning; + break; + case 2: + armour = Wizardry.wizardLeggingsLightning; + break; + case 3: + armour = Wizardry.wizardBootsLightning; + break; + default: + break; + } + break; + case NECROMANCY: + switch(slot){ + case 0: + armour = Wizardry.wizardHatNecromancy; + break; + case 1: + armour = Wizardry.wizardRobeNecromancy; + break; + case 2: + armour = Wizardry.wizardLeggingsNecromancy; + break; + case 3: + armour = Wizardry.wizardBootsNecromancy; + break; + default: + break; + } + break; + case SORCERY: + switch(slot){ + case 0: + armour = Wizardry.wizardHatSorcery; + break; + case 1: + armour = Wizardry.wizardRobeSorcery; + break; + case 2: + armour = Wizardry.wizardLeggingsSorcery; + break; + case 3: + armour = Wizardry.wizardBootsSorcery; + break; + default: + break; + } + break; + case EARTH: + switch(slot){ + case 0: + armour = Wizardry.wizardHatEarth; + break; + case 1: + armour = Wizardry.wizardRobeEarth; + break; + case 2: + armour = Wizardry.wizardLeggingsEarth; + break; + case 3: + armour = Wizardry.wizardBootsEarth; + break; + default: + break; + } + break; + default: + switch(slot){ + case 0: + armour = Wizardry.wizardHat; + break; + case 1: + armour = Wizardry.wizardRobe; + break; + case 2: + armour = Wizardry.wizardLeggings; + break; + case 3: + armour = Wizardry.wizardBoots; + break; + default: + break; + } + break; + } + } + return armour; + } + + /** + * Helper method to return the appropriate wand based on tier and element. + * Currently used in the packet handler for upgrading wands, for chest generation and to iterate through + * wands for charging recipes. + */ + public static Item getWand(EnumTier tier, EnumElement element){ + Item wand = null; + if(element == null){ + switch(tier){ + case BASIC: + wand = Wizardry.magicWand; + break; + case APPRENTICE: + wand = Wizardry.apprenticeWand; + break; + case ADVANCED: + wand = Wizardry.advancedWand; + break; + case MASTER: + wand = Wizardry.masterWand; + break; + default: + break; + } + }else{ + switch(element){ + case FIRE: + switch(tier){ + case BASIC: + wand = Wizardry.basicFireWand; + break; + case APPRENTICE: + wand = Wizardry.apprenticeFireWand; + break; + case ADVANCED: + wand = Wizardry.advancedFireWand; + break; + case MASTER: + wand = Wizardry.masterFireWand; + break; + default: + break; + } + break; + case HEALING: + switch(tier){ + case BASIC: + wand = Wizardry.basicHealingWand; + break; + case APPRENTICE: + wand = Wizardry.apprenticeHealingWand; + break; + case ADVANCED: + wand = Wizardry.advancedHealingWand; + break; + case MASTER: + wand = Wizardry.masterHealingWand; + break; + default: + break; + } + break; + case ICE: + switch(tier){ + case BASIC: + wand = Wizardry.basicIceWand; + break; + case APPRENTICE: + wand = Wizardry.apprenticeIceWand; + break; + case ADVANCED: + wand = Wizardry.advancedIceWand; + break; + case MASTER: + wand = Wizardry.masterIceWand; + break; + default: + break; + } + break; + case LIGHTNING: + switch(tier){ + case BASIC: + wand = Wizardry.basicLightningWand; + break; + case APPRENTICE: + wand = Wizardry.apprenticeLightningWand; + break; + case ADVANCED: + wand = Wizardry.advancedLightningWand; + break; + case MASTER: + wand = Wizardry.masterLightningWand; + break; + default: + break; + } + break; + case NECROMANCY: + switch(tier){ + case BASIC: + wand = Wizardry.basicNecromancyWand; + break; + case APPRENTICE: + wand = Wizardry.apprenticeNecromancyWand; + break; + case ADVANCED: + wand = Wizardry.advancedNecromancyWand; + break; + case MASTER: + wand = Wizardry.masterNecromancyWand; + break; + default: + break; + } + break; + case SORCERY: + switch(tier){ + case BASIC: + wand = Wizardry.basicSorceryWand; + break; + case APPRENTICE: + wand = Wizardry.apprenticeSorceryWand; + break; + case ADVANCED: + wand = Wizardry.advancedSorceryWand; + break; + case MASTER: + wand = Wizardry.masterSorceryWand; + break; + default: + break; + } + break; + case EARTH: + switch(tier){ + case BASIC: + wand = Wizardry.basicEarthWand; + break; + case APPRENTICE: + wand = Wizardry.apprenticeEarthWand; + break; + case ADVANCED: + wand = Wizardry.advancedEarthWand; + break; + case MASTER: + wand = Wizardry.masterEarthWand; + break; + default: + break; + } + break; + default: + switch(tier){ + case BASIC: + wand = Wizardry.magicWand; + break; + case APPRENTICE: + wand = Wizardry.apprenticeWand; + break; + case ADVANCED: + wand = Wizardry.advancedWand; + break; + case MASTER: + wand = Wizardry.masterWand; + break; + default: + break; + } + break; + } + } + return wand; + } + +} diff --git a/src/main/java/electroblob/wizardry/WizardryWorldGenerator.java b/src/main/java/electroblob/wizardry/WizardryWorldGenerator.java index 74fdab00..7528aa4a 100644 --- a/src/main/java/electroblob/wizardry/WizardryWorldGenerator.java +++ b/src/main/java/electroblob/wizardry/WizardryWorldGenerator.java @@ -1,43 +1,26 @@ package electroblob.wizardry; -import java.util.HashSet; +import java.util.ArrayList; +import java.util.List; import java.util.Random; -import java.util.Set; - -import org.apache.commons.lang3.ArrayUtils; +import cpw.mods.fml.common.IWorldGenerator; import electroblob.wizardry.entity.living.EntityEvilWizard; import electroblob.wizardry.entity.living.EntityWizard; -import electroblob.wizardry.registry.WizardryBlocks; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.block.BlockChest; -import net.minecraft.block.BlockColored; -import net.minecraft.block.BlockLeaves; +import net.minecraft.block.Block; +import net.minecraft.block.BlockLeavesBase; import net.minecraft.block.BlockLiquid; -import net.minecraft.block.BlockPlanks; -import net.minecraft.block.BlockSlab; -import net.minecraft.block.BlockTorch; -import net.minecraft.block.BlockSlab.EnumBlockHalf; -import net.minecraft.block.state.IBlockState; -import net.minecraft.init.Biomes; import net.minecraft.init.Blocks; import net.minecraft.inventory.IInventory; -import net.minecraft.item.EnumDyeColor; import net.minecraft.item.ItemDoor; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.WeightedRandomChestContent; import net.minecraft.world.World; -import net.minecraft.world.WorldServer; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.chunk.IChunkGenerator; +import net.minecraft.world.biome.BiomeGenBase; import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.gen.feature.WorldGenMinable; -import net.minecraft.world.storage.loot.LootContext; -import net.minecraft.world.storage.loot.LootTable; import net.minecraftforge.common.BiomeDictionary; +import net.minecraftforge.common.ChestGenHooks; import net.minecraftforge.common.IPlantable; -import net.minecraftforge.fml.common.IWorldGenerator; public class WizardryWorldGenerator implements IWorldGenerator { @@ -45,19 +28,20 @@ public class WizardryWorldGenerator implements IWorldGenerator { public static final String WIZARD_TOWER = Wizardry.MODID + "wizardTower"; @Override - public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkProvider){ + public void generate(Random random, int chunkX, int chunkZ, World world, + IChunkProvider chunkGenerator, IChunkProvider chunkProvider) { - for(int id : Wizardry.settings.oreDimensions){ - if(id == world.provider.getDimension()) this.addOreSpawn(WizardryBlocks.crystal_ore.getDefaultState(), world, random, chunkX * 16, chunkZ * 16, 16, 16, 5, 7, 5, 30); + for(int id : Wizardry.oreDimensions){ + if(id == world.provider.dimensionId) this.addOreSpawn(Wizardry.crystalOre, world, random, chunkX * 16, chunkZ * 16, 16, 16, 5, 7, 5, 30); } - for(int id : Wizardry.settings.flowerDimensions){ - if(id == world.provider.getDimension()) this.generatePlant(WizardryBlocks.crystal_flower.getDefaultState(), world, random, chunkX * 16, chunkZ * 16, 2, 20); + for(int id : Wizardry.flowerDimensions){ + if(id == world.provider.dimensionId) this.generatePlant(Wizardry.crystalFlower, world, random, chunkX * 16, chunkZ * 16, 2, 20); } if(world.getWorldInfo().isMapFeaturesEnabled()){ - for(int id : Wizardry.settings.towerDimensions){ - if(id == world.provider.getDimension()) this.generateWizardTower(world, random, chunkX * 16, chunkZ * 16); + for(int id : Wizardry.towerDimensions){ + if(id == world.provider.dimensionId) this.generateWizardTower(world, random, chunkX * 16, chunkZ * 16); } } } @@ -77,9 +61,9 @@ public class WizardryWorldGenerator implements IWorldGenerator { * @param An int for the minimum Y-Coordinate height at which this block may spawn * @param An int for the maximum Y-Coordinate height at which this block may spawn **/ - public void addOreSpawn(IBlockState state, World world, Random random, int blockXPos, int blockZPos, int maxX, int maxZ, int maxVeinSize, int chancesToSpawn, int minY, int maxY) + public void addOreSpawn(Block block, World world, Random random, int blockXPos, int blockZPos, int maxX, int maxZ, int maxVeinSize, int chancesToSpawn, int minY, int maxY) { - //int maxPossY = minY + (maxY - 1); + int maxPossY = minY + (maxY - 1); assert maxY > minY: "The maximum Y must be greater than the Minimum Y"; assert maxX > 0 && maxX <= 16: "addOreSpawn: The Maximum X must be greater than 0 and less than 16"; assert minY > 0: "addOreSpawn: The Minimum Y must be greater than 0"; @@ -92,7 +76,7 @@ public class WizardryWorldGenerator implements IWorldGenerator { int posX = blockXPos + random.nextInt(maxX); int posY = minY + random.nextInt(diffBtwnMinMaxY); int posZ = blockZPos + random.nextInt(maxZ); - (new WorldGenMinable(state, maxVeinSize)).generate(world, random, new BlockPos(posX, posY, posZ)); + (new WorldGenMinable(block, maxVeinSize)).generate(world, random, posX, posY, posZ); } } @@ -106,8 +90,7 @@ public class WizardryWorldGenerator implements IWorldGenerator { * @param chancesToSpawn Number of chances to spawn a flower patch * @param groupSize The number of times to try generating a flower per flower patch spawn */ - public void generatePlant(IBlockState state, World world, Random random, int x, int z, int chancesToSpawn, int groupSize){ - + public void generatePlant(Block block, World world, Random random, int x, int z, int chancesToSpawn, int groupSize){ for(int i = 0; i < chancesToSpawn; i++){ int randPosX = x + random.nextInt(16); int randPosY = random.nextInt(256); @@ -117,12 +100,10 @@ public class WizardryWorldGenerator implements IWorldGenerator { int i1 = randPosX + random.nextInt(8) - random.nextInt(8); int j1 = randPosY + random.nextInt(4) - random.nextInt(4); int k1 = randPosZ + random.nextInt(8) - random.nextInt(8); - - BlockPos pos = new BlockPos(i1, j1, k1); - if(world.isBlockLoaded(pos) && world.isAirBlock(pos) && (!world.provider.getHasNoSky() || j1 < 127) && state.getBlock().canPlaceBlockOnSide(world, pos, EnumFacing.UP)){ + if(world.blockExists(i1, j1, k1) && world.isAirBlock(i1, j1, k1) && (!world.provider.hasNoSky || j1 < 127) && block.canBlockStay(world, i1, j1, k1)){ - world.setBlockState(pos, state, 2); + world.setBlock(i1, j1, k1, block, 0, 2); } } } @@ -134,20 +115,21 @@ public class WizardryWorldGenerator implements IWorldGenerator { public void generateWizardTower(World world, Random random, int chunkX, int chunkZ){ // Allows the config file to set the rarity value to 0 to disable tower generation completely. - if(Wizardry.settings.towerRarity == 0) return; + if(Wizardry.towerRarity == 0) return; // Compensates for the lack of space in forests. Math.max is required since treeless biomes have treesPerChunk = -999 //double treeFactor = 70 - Math.max((double)world.getBiomeGenForCoords(chunkX, chunkZ).theBiomeDecorator.treesPerChunk, 0) * 1.5d; // Multiplied by 70 to (roughly) retain the old rarity scale - if(random.nextInt((int)(Wizardry.settings.towerRarity * 70)) == 0){ - - BlockPos origin = new BlockPos(chunkX + random.nextInt(16), 0, chunkZ + random.nextInt(16)); + if(random.nextInt((int)(Wizardry.towerRarity * 70)) == 0){ + + int posX = chunkX + random.nextInt(16); + int posZ = chunkZ + random.nextInt(16); // Despite what its name suggests, this method does not return the position of a liquid. It is in fact // exactly what is needed here since it is used for placing villages and stuff, and doesn't include leaves // or other foliage. - origin = origin.up(world.getTopSolidOrLiquidBlock(origin).getY() - 1); + int posY = world.getTopSolidOrLiquidBlock(posX, posZ) - 1; int[][][] towerBlueprint = towerBlueprintSmall; @@ -159,82 +141,140 @@ public class WizardryWorldGenerator implements IWorldGenerator { } // 0 = West, 1 = North, 2 = East, 3 = South (The way you would face when walking out of the door) - EnumFacing orientation = EnumFacing.getHorizontal(random.nextInt(4)); + int orientation = random.nextInt(4); boolean flip = random.nextBoolean(); - - if(checkSpaceForTower(world, origin, towerBlueprint, orientation, flip)){ - // == Setup == - + /* It seems there is something specific about sand which makes it very unlikely (but NOT impossible) for + * the towers to generate on it... + * Edit: The culprit was canBlockSeeTheSky, so I've taken that out and replaced it with getTopSolidOrLiquidBlock + * (which also greatly increases the efficiency of the generator since it doesn't even try underground blocks). + * In addition, I have added a check for solid blocks in the way of the tower; see checkForSpace. */ + + // Debugging + //System.out.println("Tried to generate wizard tower at (" + posX + ", " + posY + ", " + posZ + "); Biome: " + // + world.getBiomeGenForCoords(posX, posZ).biomeName + ", Can block see sky: " + // + world.canBlockSeeTheSky(posX, posY, posZ) + ", Is block normal cube: " + // + world.isBlockNormalCubeDefault(posX, posY, posZ, false) + ", Block: " + // + world.getBlock(posX, posY, posZ).getLocalizedName()); + + // These conditions are no longer necessary thanks to world.getTopSolidOrLiquidBlock + //if((world.canBlockSeeTheSky(posX, posY, posZ) || world.getBlock(posX, posY, posZ) == Blocks.grass) && + //if(!world.isAirBlock(posX, posY, posZ) && world.isBlockNormalCubeDefault(posX, posY, posZ, false) && + + if(checkSpaceForTower(world, posX, posY, posZ, towerBlueprint, orientation, flip)){ + boolean evilWizard = random.nextInt(5) == 0; - IBlockState wallMaterial = Blocks.COBBLESTONE.getDefaultState(); - BlockPlanks.EnumType woodType = BlockPlanks.EnumType.OAK; - - Biome biome = world.getBiome(origin); + Block wallMaterial = Blocks.cobblestone; + int woodType = 0; + BiomeGenBase biome = world.getBiomeGenForCoords(posX, posZ); // The order of these is somewhat important in that biomes can be many types, so the last of these checks - // that is true gets priority. Generally speaking, the later the check, the more specific it is. - if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.DENSE)) wallMaterial = Blocks.MOSSY_COBBLESTONE.getDefaultState(); - if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.SWAMP)) wallMaterial = Blocks.MOSSY_COBBLESTONE.getDefaultState(); - if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.SANDY)) wallMaterial = Blocks.SANDSTONE.getDefaultState(); - if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.NETHER)) wallMaterial = Blocks.NETHER_BRICK.getDefaultState(); - if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.MOUNTAIN)) wallMaterial = Blocks.STONEBRICK.getDefaultState(); - if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.MESA)) wallMaterial = Blocks.HARDENED_CLAY.getDefaultState(); + // that is true gets priority + if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.DENSE)) wallMaterial = Blocks.mossy_cobblestone; + if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.SWAMP)) wallMaterial = Blocks.mossy_cobblestone; + if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.SANDY)) wallMaterial = Blocks.sandstone; + if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.NETHER)) wallMaterial = Blocks.nether_brick; + if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.MOUNTAIN)) wallMaterial = Blocks.stonebrick; + if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.MESA)) wallMaterial = Blocks.hardened_clay; // Unfortunately, I can't check all the wood types with the biome dictionary - if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.CONIFEROUS)) woodType = BlockPlanks.EnumType.SPRUCE; - if(biome == Biomes.BIRCH_FOREST || biome == Biomes.BIRCH_FOREST_HILLS) woodType = BlockPlanks.EnumType.BIRCH; - if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.JUNGLE)) woodType = BlockPlanks.EnumType.JUNGLE; - if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.SAVANNA)) woodType = BlockPlanks.EnumType.ACACIA; + if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.CONIFEROUS)) woodType = 1; + if(biome == BiomeGenBase.birchForest || biome == BiomeGenBase.birchForestHills) woodType = 2; + if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.JUNGLE)) woodType = 3; + if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.SAVANNA)) woodType = 4; // Not technically a tree type, but I think it fits quite well anyway - if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.SPOOKY)) woodType = BlockPlanks.EnumType.DARK_OAK; - - IBlockState[] blockStateList = new IBlockState[]{ + if(BiomeDictionary.isBiomeOfType(biome, BiomeDictionary.Type.SPOOKY)) woodType = 5; + + Block[] blockList = new Block[]{ null, - Blocks.AIR.getDefaultState(), - Blocks.PLANKS.getDefaultState().withProperty(BlockPlanks.VARIANT, woodType), - Blocks.BOOKSHELF.getDefaultState(), - Blocks.STAINED_HARDENED_CLAY.getDefaultState().withProperty(BlockColored.COLOR, - EnumDyeColor.values()[random.nextInt(EnumDyeColor.values().length)]), - Blocks.WOODEN_SLAB.getDefaultState().withProperty(BlockSlab.HALF, EnumBlockHalf.BOTTOM), - Blocks.WOODEN_SLAB.getDefaultState().withProperty(BlockSlab.HALF, EnumBlockHalf.TOP), + Blocks.air, + Blocks.planks, + Blocks.bookshelf, + Blocks.stained_hardened_clay, + Blocks.wooden_slab, + Blocks.wooden_slab, wallMaterial, - Blocks.GLASS_PANE.getDefaultState(), - Blocks.OAK_DOOR.getDefaultState(), - WizardryBlocks.arcane_workbench.getDefaultState(), - Blocks.TORCH.getDefaultState(), - evilWizard ? Blocks.CHEST.getDefaultState() : Blocks.BOOKSHELF.getDefaultState() + Blocks.glass_pane, + Blocks.wooden_door, + Wizardry.arcaneWorkbench, + Blocks.torch, + evilWizard ? Blocks.chest : Blocks.bookshelf }; - Set blocksPlaced = new HashSet(); - - // == Foundations == + int[] metadataList = new int[]{0, 0, woodType, 0, random.nextInt(15), woodType, woodType + 8, 0, 0, 0, 0, 0, 0}; + + List blocksPlaced = new ArrayList(); // Fills in foundations. This is done first so the door always has something to be placed on. boolean flag = true; - - // BlockPos is immutable, so I'm not sure if simply saying pos1 = pos will be sufficient. - BlockPos layerCentre = new BlockPos(origin); + int y1 = 0; while(flag){ - flag = false; - - for(BlockPos offset : foundationLayer){ - if(!world.isBlockNormalCube(layerCentre.add(offset), false)){ - world.setBlockState(layerCentre.add(offset), wallMaterial); - blocksPlaced.add(layerCentre.add(offset)); - // Keeps going as long as something was filled in. - flag = true; - } + if(!world.isBlockNormalCubeDefault(posX - 2, posY + y1, posZ - 1, false)){ + world.setBlock(posX - 2, posY + y1, posZ - 1, wallMaterial); + blocksPlaced.add(new int[]{posX - 2, posY + y1, posZ - 1}); + flag = true; } - - layerCentre = layerCentre.down(); + if(!world.isBlockNormalCubeDefault(posX - 2, posY + y1, posZ, false)){ + world.setBlock(posX - 2, posY + y1, posZ, wallMaterial); + blocksPlaced.add(new int[]{posX - 2, posY + y1, posZ}); + flag = true; + } + if(!world.isBlockNormalCubeDefault(posX - 2, posY + y1, posZ + 1, false)){ + world.setBlock(posX - 2, posY + y1, posZ + 1, wallMaterial); + blocksPlaced.add(new int[]{posX - 2, posY + y1, posZ + 1}); + flag = true; + } + if(!world.isBlockNormalCubeDefault(posX + 2, posY + y1, posZ - 1, false)){ + world.setBlock(posX + 2, posY + y1, posZ - 1, wallMaterial); + blocksPlaced.add(new int[]{posX + 2, posY + y1, posZ - 1}); + flag = true; + } + if(!world.isBlockNormalCubeDefault(posX + 2, posY + y1, posZ, false)){ + world.setBlock(posX + 2, posY + y1, posZ, wallMaterial); + blocksPlaced.add(new int[]{posX + 2, posY + y1, posZ}); + flag = true; + } + if(!world.isBlockNormalCubeDefault(posX + 2, posY + y1, posZ + 1, false)){ + world.setBlock(posX + 2, posY + y1, posZ + 1, wallMaterial); + blocksPlaced.add(new int[]{posX + 2, posY + y1, posZ + 1}); + flag = true; + } + if(!world.isBlockNormalCubeDefault(posX - 1, posY + y1, posZ - 2, false)){ + world.setBlock(posX - 1, posY + y1, posZ - 2, wallMaterial); + blocksPlaced.add(new int[]{posX - 1, posY + y1, posZ - 2}); + flag = true; + } + if(!world.isBlockNormalCubeDefault(posX, posY + y1, posZ - 2, false)){ + world.setBlock(posX, posY + y1, posZ - 2, wallMaterial); + blocksPlaced.add(new int[]{posX, posY + y1, posZ - 2}); + flag = true; + } + if(!world.isBlockNormalCubeDefault(posX + 1, posY + y1, posZ - 2, false)){ + world.setBlock(posX + 1, posY + y1, posZ - 2, wallMaterial); + blocksPlaced.add(new int[]{posX + 1, posY + y1, posZ - 2}); + flag = true; + } + if(!world.isBlockNormalCubeDefault(posX - 1, posY + y1, posZ + 2, false)){ + world.setBlock(posX - 1, posY + y1, posZ + 2, wallMaterial); + blocksPlaced.add(new int[]{posX - 1, posY + y1, posZ + 2}); + flag = true; + } + if(!world.isBlockNormalCubeDefault(posX, posY + y1, posZ + 2, false)){ + world.setBlock(posX, posY + y1, posZ + 2, wallMaterial); + blocksPlaced.add(new int[]{posX, posY + y1, posZ + 2}); + flag = true; + } + if(!world.isBlockNormalCubeDefault(posX + 1, posY + y1, posZ + 2, false)){ + world.setBlock(posX + 1, posY + y1, posZ + 2, wallMaterial); + blocksPlaced.add(new int[]{posX + 1, posY + y1, posZ + 2}); + flag = true; + } + y1--; } - // == Main Structure == - // It is assumed that the width of the blueprint is the same all the way up, and that the layers are square. int width = towerBlueprint[0].length-1; @@ -243,52 +283,46 @@ public class WizardryWorldGenerator implements IWorldGenerator { int x1 = 0, z1 = 0; + // Main structure for(int y=0; y 3 || world.getBlockState(pos1).getBlock() instanceof BlockLiquid)){ + if(towerBlueprint[y][z1][x1] != 0 && !WizardryUtilities.canBlockBeReplacedB(world, posX + x - width/2, posY + y, posZ + z - width/2) + && !(world.getBlock(posX + x - width/2, posY + y, posZ + z - width/2) instanceof IPlantable) + && !(world.getBlock(posX + x - width/2, posY + y, posZ + z - width/2) instanceof BlockLeavesBase) + && (y > 3 || world.getBlock(posX + x - width/2, posY + y, posZ + z - width/2) instanceof BlockLiquid)){ return false; } } @@ -465,22 +440,6 @@ public class WizardryWorldGenerator implements IWorldGenerator { return true; } - - /** Array of relative positions of each block in a layer of foundations. */ - private static final BlockPos[] foundationLayer = new BlockPos[]{ - new BlockPos(-2, 0, -1), - new BlockPos(-2, 0, 0), - new BlockPos(-2, 0, 1), - new BlockPos(2, 0, -1), - new BlockPos(2, 0, 0), - new BlockPos(2, 0, 1), - new BlockPos(-1, 0, -2), - new BlockPos(0, 0, -2), - new BlockPos(1, 0, -2), - new BlockPos(-1, 0, 2), - new BlockPos(0, 0, 2), - new BlockPos(1, 0, 2), - }; /** * 3D matrix of integers representing the different blocks which make up the wizard tower. The blocks corresponding diff --git a/src/main/java/electroblob/wizardry/block/BlockArcaneWorkbench.java b/src/main/java/electroblob/wizardry/block/BlockArcaneWorkbench.java index 4a0c3f8f..06b0ba97 100644 --- a/src/main/java/electroblob/wizardry/block/BlockArcaneWorkbench.java +++ b/src/main/java/electroblob/wizardry/block/BlockArcaneWorkbench.java @@ -4,36 +4,49 @@ import java.util.Random; import electroblob.wizardry.Wizardry; import electroblob.wizardry.WizardryGuiHandler; +import electroblob.wizardry.client.GuiArcaneWorkbench; import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench; +import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; -import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumBlockRenderType; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IBlockAccess; +import net.minecraft.util.IIcon; import net.minecraft.world.World; -public class BlockArcaneWorkbench extends BlockContainer { +public class BlockArcaneWorkbench extends BlockContainer{ - private static final AxisAlignedBB AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.75D, 1.0D); + public IIcon[] icons = new IIcon[6]; public BlockArcaneWorkbench(){ - super(Material.ROCK); + super(Material.rock); + this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F); this.setLightLevel(0.8f); + this.setCreativeTab(CreativeTabs.tabDecorations); + this.setBlockTextureName("wizardry:arcane_workbench"); + } + + @Override + public void registerBlockIcons(IIconRegister par1IconRegister) { + this.icons[0] = par1IconRegister.registerIcon(this.textureName + "_bottom"); + this.icons[1] = par1IconRegister.registerIcon(this.textureName + "_top"); + this.icons[2] = par1IconRegister.registerIcon(this.textureName + "_side"); + this.icons[3] = par1IconRegister.registerIcon(this.textureName + "_side"); + this.icons[4] = par1IconRegister.registerIcon(this.textureName + "_side"); + this.icons[5] = par1IconRegister.registerIcon(this.textureName + "_side"); } + + @Override - public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){ - return AABB; - } + public IIcon getIcon(int side, int meta) { + return this.icons[side]; + } @Override public TileEntity createNewTileEntity(World world, int metadata) { @@ -41,39 +54,32 @@ public class BlockArcaneWorkbench extends BlockContainer { } @Override - public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) { - return false; - } - + public boolean renderAsNormalBlock() + { + return false; + } + @Override - public EnumBlockRenderType getRenderType(IBlockState state) { - return EnumBlockRenderType.MODEL; - } - + public boolean isOpaqueCube() + { + return false; + } + @Override - public boolean isOpaqueCube(IBlockState state) { - return false; - } - - @Override - public boolean onBlockActivated(World world, BlockPos pos, IBlockState block, EntityPlayer player, - EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ){ - - TileEntity tileEntity = world.getTileEntity(pos); - - if(tileEntity == null || player.isSneaking()){ + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int metadata, float what, float these, float are) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity == null || player.isSneaking()) { return false; } - - player.openGui(Wizardry.instance, WizardryGuiHandler.ARCANE_WORKBENCH, world, pos.getX(), pos.getY(), pos.getZ()); + player.openGui(Wizardry.instance, WizardryGuiHandler.ARCANE_WORKBENCH, world, x, y, z); return true; } @Override - public void breakBlock(World world, BlockPos pos, IBlockState block) + public void breakBlock(World par1World, int par2, int par3, int par4, Block block, int par6) { Random random = new Random(); - TileEntityArcaneWorkbench tileentityarcaneworkbench = (TileEntityArcaneWorkbench)world.getTileEntity(pos); + TileEntityArcaneWorkbench tileentityarcaneworkbench = (TileEntityArcaneWorkbench)par1World.getTileEntity(par2, par3, par4); if (tileentityarcaneworkbench != null) { @@ -87,7 +93,7 @@ public class BlockArcaneWorkbench extends BlockContainer { float f1 = random.nextFloat() * 0.8F + 0.1F; EntityItem entityitem; - for (float f2 = random.nextFloat() * 0.8F + 0.1F; itemstack.stackSize > 0; world.spawnEntityInWorld(entityitem)) + for (float f2 = random.nextFloat() * 0.8F + 0.1F; itemstack.stackSize > 0; par1World.spawnEntityInWorld(entityitem)) { int k1 = random.nextInt(21) + 10; @@ -97,7 +103,7 @@ public class BlockArcaneWorkbench extends BlockContainer { } itemstack.stackSize -= k1; - entityitem = new EntityItem(world, (double)((float)pos.getX() + f), (double)((float)pos.getY() + f1), (double)((float)pos.getZ() + f2), new ItemStack(itemstack.getItem(), k1, itemstack.getItemDamage())); + entityitem = new EntityItem(par1World, (double)((float)par2 + f), (double)((float)par3 + f1), (double)((float)par4 + f2), new ItemStack(itemstack.getItem(), k1, itemstack.getItemDamage())); float f3 = 0.05F; entityitem.motionX = (double)((float)random.nextGaussian() * f3); entityitem.motionY = (double)((float)random.nextGaussian() * f3 + 0.2F); @@ -105,7 +111,7 @@ public class BlockArcaneWorkbench extends BlockContainer { if (itemstack.hasTagCompound()) { - entityitem.getEntityItem().setTagCompound(((NBTTagCompound)itemstack.getTagCompound().copy())); + entityitem.getEntityItem().setTagCompound((NBTTagCompound)itemstack.getTagCompound().copy()); } } } @@ -113,8 +119,8 @@ public class BlockArcaneWorkbench extends BlockContainer { //par1World.func_96440_m(par2, par3, par4, block); } - - super.breakBlock(world, pos, block); + + super.breakBlock(par1World, par2, par3, par4, block, par6); } } diff --git a/src/main/java/electroblob/wizardry/block/BlockCrystal.java b/src/main/java/electroblob/wizardry/block/BlockCrystal.java new file mode 100644 index 00000000..7488b2c2 --- /dev/null +++ b/src/main/java/electroblob/wizardry/block/BlockCrystal.java @@ -0,0 +1,16 @@ +package electroblob.wizardry.block; + +import java.util.Random; + +import electroblob.wizardry.Wizardry; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.item.Item; + +public class BlockCrystal extends Block { + + public BlockCrystal(Material material) { + super(material); + setHarvestLevel("pickaxe", 2); + } +} diff --git a/src/main/java/electroblob/wizardry/block/BlockCrystalFlower.java b/src/main/java/electroblob/wizardry/block/BlockCrystalFlower.java index 9aded57a..7d01265c 100644 --- a/src/main/java/electroblob/wizardry/block/BlockCrystalFlower.java +++ b/src/main/java/electroblob/wizardry/block/BlockCrystalFlower.java @@ -2,67 +2,142 @@ package electroblob.wizardry.block; import java.util.Random; +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardryBlocks; -import electroblob.wizardry.util.WizardryParticleType; -import net.minecraft.block.BlockBush; -import net.minecraft.block.SoundType; +import net.minecraft.block.Block; import net.minecraft.block.material.Material; -import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.common.EnumPlantType; -import net.minecraftforge.event.entity.player.BonemealEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.common.IPlantable; +import net.minecraftforge.common.util.ForgeDirection; -// Extending BlockBush allows me to remove nearly everything from this class. -@Mod.EventBusSubscriber -public class BlockCrystalFlower extends BlockBush { - - private static final AxisAlignedBB AABB = new AxisAlignedBB(0.5F - 0.2f, 0.0F, 0.5F - 0.2f, 0.5F + 0.2f, 0.2f * 3.0F, 0.5F + 0.2f); +public class BlockCrystalFlower extends Block implements IPlantable { public BlockCrystalFlower(Material par2Material) { super(par2Material); this.setLightLevel(0.5f); + this.setBlockBounds(0.5F - 0.2f, 0.0F, 0.5F - 0.2f, 0.5F + 0.2f, 0.2f * 3.0F, 0.5F + 0.2f); this.setTickRandomly(true); - this.setSoundType(SoundType.PLANT); } @Override - public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) - { - return AABB; - } - - @Override - public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random){ + public void randomDisplayTick(World world, int x, int y, int z, Random random){ if(world.isRemote && random.nextBoolean()){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, pos.getX()+random.nextDouble(), pos.getY()+random.nextDouble()/2+0.5, pos.getZ()+random.nextDouble(), 0d, 0.01, 0d, 20 + random.nextInt(10), 0.5f + (random.nextFloat()/2), 0.5f + (random.nextFloat()/2), 0.5f + (random.nextFloat()/2)); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x+random.nextDouble(), y+random.nextDouble()/2+0.5, z+random.nextDouble(), 0d, 0.01, 0d, 20 + random.nextInt(10), 0.5f + (random.nextFloat()/2), 0.5f + (random.nextFloat()/2), 0.5f + (random.nextFloat()/2)); } } + + /** + * Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z + */ + @Override + public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4) + { + return super.canPlaceBlockAt(par1World, par2, par3, par4) && canBlockStay(par1World, par2, par3, par4); + } + + /** + * Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been + * cleared to be reused) + */ + @Override + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) + { + return null; + } + + /** + * Gets passed in the blockID of the block below and supposed to return true if its allowed to grow on the type of + * blockID passed in. Args: blockID + */ + protected boolean canThisPlantGrowOnThisBlockID(Block par1) + { + return par1 == Blocks.grass || par1 == Blocks.dirt || par1 == Blocks.farmland; + } + + /** + * Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are + * their own) Args: x, y, z, neighbor blockID + */ + @Override + public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, Block par5) + { + super.onNeighborBlockChange(par1World, par2, par3, par4, par5); + this.checkFlowerChange(par1World, par2, par3, par4); + } + + /** + * Ticks the block if it's been scheduled + */ + @Override + public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random) + { + this.checkFlowerChange(par1World, par2, par3, par4); + } + + protected final void checkFlowerChange(World par1World, int par2, int par3, int par4) + { + if (!this.canBlockStay(par1World, par2, par3, par4)) + { + this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0); + par1World.setBlock(par2, par3, par4, Blocks.air, 0, 2); + } + } + + /** + * Can this block stay at this position. Similar to canPlaceBlockAt except gets checked often with plants. + */ + @Override + public boolean canBlockStay(World par1World, int par2, int par3, int par4) + { + Block soil = par1World.getBlock(par2, par3 - 1, par4); + return (par1World.getFullBlockLightValue(par2, par3, par4) >= 8 || par1World.canBlockSeeTheSky(par2, par3, par4)) && + (soil != null && soil.canSustainPlant(par1World, par2, par3 - 1, par4, ForgeDirection.UP, this)); + } + + /** + * Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two + * adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block. + */ + @Override + public boolean isOpaqueCube() + { + return false; + } + + /** + * If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc) + */ + @Override + public boolean renderAsNormalBlock() + { + return false; + } + + /** + * The type of render function that is called for this block + */ + @Override + public int getRenderType() + { + return 1; + } @Override - public EnumPlantType getPlantType(IBlockAccess world, BlockPos pos) { + public EnumPlantType getPlantType(IBlockAccess world, int x, int y, int z) { return EnumPlantType.Plains; } - @SubscribeEvent - public static void onBonemealEvent(BonemealEvent event){ - // Grows crystal flowers when bonemeal is used on grass - if(event.getBlock().getBlock() == Blocks.GRASS){ + @Override + public Block getPlant(IBlockAccess world, int x, int y, int z) { + return this; + } - BlockPos pos = event.getPos().add(event.getWorld().rand.nextInt(8) - event.getWorld().rand.nextInt(8), - event.getWorld().rand.nextInt(4) - event.getWorld().rand.nextInt(4), - event.getWorld().rand.nextInt(8) - event.getWorld().rand.nextInt(8)); - - if (event.getWorld().isAirBlock(new BlockPos(pos)) && (!event.getWorld().provider.getHasNoSky() || pos.getY() < 127) && WizardryBlocks.crystal_flower.canPlaceBlockAt(event.getWorld(), pos)) - { - event.getWorld().setBlockState(pos, WizardryBlocks.crystal_flower.getDefaultState(), 2); - } - } + @Override + public int getPlantMetadata(IBlockAccess world, int x, int y, int z) { + return 0; } } diff --git a/src/main/java/electroblob/wizardry/block/BlockCrystalOre.java b/src/main/java/electroblob/wizardry/block/BlockCrystalOre.java index dc594dc0..0b572cc4 100644 --- a/src/main/java/electroblob/wizardry/block/BlockCrystalOre.java +++ b/src/main/java/electroblob/wizardry/block/BlockCrystalOre.java @@ -2,24 +2,23 @@ package electroblob.wizardry.block; import java.util.Random; -import electroblob.wizardry.registry.WizardryItems; +import electroblob.wizardry.Wizardry; import net.minecraft.block.Block; -import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.block.state.IBlockState; import net.minecraft.item.Item; public class BlockCrystalOre extends Block { public BlockCrystalOre(Material material) { super(material); - this.setSoundType(SoundType.STONE); + setStepSound(Block.soundTypeStone); + setBlockName("crystalOre"); setResistance(5.0F); setHarvestLevel("pickaxe", 2); } @Override - public int quantityDropped(IBlockState state, int fortune, Random random) + public int quantityDropped(int meta, int fortune, Random random) { if(fortune > 0){ return random.nextInt(2) + 1 + random.nextInt(fortune); @@ -29,7 +28,7 @@ public class BlockCrystalOre extends Block { } @Override - public Item getItemDropped(IBlockState state, Random random, int fortune){ - return WizardryItems.magic_crystal; + public Item getItemDropped(int Metadata, Random random, int fortune){ + return Wizardry.magicCrystal; } } diff --git a/src/main/java/electroblob/wizardry/block/BlockMagicLight.java b/src/main/java/electroblob/wizardry/block/BlockMagicLight.java index c3ef8499..7287e618 100644 --- a/src/main/java/electroblob/wizardry/block/BlockMagicLight.java +++ b/src/main/java/electroblob/wizardry/block/BlockMagicLight.java @@ -1,40 +1,26 @@ package electroblob.wizardry.block; +import java.util.Random; + import electroblob.wizardry.tileentity.TileEntityMagicLight; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; -import net.minecraft.block.state.IBlockState; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumBlockRenderType; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IBlockAccess; +import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.World; public class BlockMagicLight extends BlockContainer { - - private static final AxisAlignedBB AABB = new AxisAlignedBB(0, 0, 0, 0, 0, 0); public BlockMagicLight(Material par2Material) { super(par2Material); this.setLightLevel(1.0f); + this.setBlockBounds(0, 0, 0, 0, 0, 0); } - - @Override - public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, World worldIn, BlockPos pos){ - // The other two bounding box methods in Block aren't nullable, so this is the only one that can return NULL_AABB. - return NULL_AABB; - } - - @Override - public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){ - return AABB; - } - @Override - public boolean isCollidable(){ - return false; - } + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4) + { + return null; + } @Override public TileEntity createNewTileEntity(World world, int metadata) { @@ -42,17 +28,13 @@ public class BlockMagicLight extends BlockContainer { } @Override - public boolean isOpaqueCube(IBlockState state) { - return false; - } + public boolean renderAsNormalBlock() + { + return false; + } @Override - public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) { + public boolean isOpaqueCube(){ return false; } - - @Override - public EnumBlockRenderType getRenderType(IBlockState state) { - return EnumBlockRenderType.ENTITYBLOCK_ANIMATED; - } } diff --git a/src/main/java/electroblob/wizardry/block/BlockSnare.java b/src/main/java/electroblob/wizardry/block/BlockSnare.java index d020a580..5a554c4c 100644 --- a/src/main/java/electroblob/wizardry/block/BlockSnare.java +++ b/src/main/java/electroblob/wizardry/block/BlockSnare.java @@ -2,103 +2,84 @@ package electroblob.wizardry.block; import java.util.Random; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.MagicDamage.DamageType; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.tileentity.TileEntityPlayerSave; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; -import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.MobEffects; import net.minecraft.item.Item; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.EnumBlockRenderType; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IBlockAccess; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.DamageSource; import net.minecraft.world.World; -// TODO: Apparently you shouldn't extend BlockContainer. I feel like BlockArcaneWorkbench should, but what about the rest? -public class BlockSnare extends BlockContainer { +import net.minecraftforge.common.util.ForgeDirection; - private static final AxisAlignedBB AABB = new AxisAlignedBB(0.0f, 0.0f, 0.0f, 1.0f, 0.0625f, 1.0f); +public class BlockSnare extends BlockContainer { public BlockSnare(Material par2Material){ super(par2Material); - this.setSoundType(SoundType.PLANT); + this.setBlockBounds(0.0f, 0.0f, 0.0f, 1.0f, 0.0625f, 1.0f); } @Override - public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){ - return AABB; - } + public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4){ + return null; + } @Override - public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, World worldIn, BlockPos pos){ - return NULL_AABB; - } - - @Override - public boolean hasTileEntity(IBlockState state){ + public boolean hasTileEntity(int metadata){ return true; } @Override - public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity) { - + public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity){ if(!world.isRemote && entity instanceof EntityLivingBase){ - if(world.getTileEntity(pos) instanceof TileEntityPlayerSave){ - - TileEntityPlayerSave tileentity = (TileEntityPlayerSave)world.getTileEntity(pos); - + if(world.getTileEntity(x, y, z) instanceof TileEntityPlayerSave){ + TileEntityPlayerSave tileentity = (TileEntityPlayerSave)world.getTileEntity(x, y, z); if(WizardryUtilities.isValidTarget(tileentity.getCaster(), entity)){ ((EntityLivingBase)entity).attackEntityFrom(MagicDamage.causeDirectMagicDamage(tileentity.getCaster(), DamageType.MAGIC), 6); - ((EntityLivingBase)entity).addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, 100, 2)); - - world.destroyBlock(pos, false); + ((EntityLivingBase)entity).addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 100, 2)); + world.func_147480_a(x, y, z, false); } } } } - // The similarly named onNeighborChange method does NOT do the same thing. - @SuppressWarnings("deprecation") @Override - public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn){ - super.neighborChanged(state, world, pos, blockIn); - if(!world.isSideSolid(pos.down(), EnumFacing.UP, false)){ - world.setBlockToAir(pos); + public void onNeighborBlockChange(World world, int x, int y, int z, Block block) + { + super.onNeighborBlockChange(world, x, y, z, block); + if(!world.isSideSolid(x, y-1, z, ForgeDirection.UP)){ + world.setBlockToAir(x, y, z); } } @Override - public BlockRenderLayer getBlockLayer(){ - return BlockRenderLayer.CUTOUT; - } - - @Override - public EnumBlockRenderType getRenderType(IBlockState state){ - return EnumBlockRenderType.MODEL; - } - - @Override - public boolean isOpaqueCube(IBlockState state){ + public boolean renderAsNormalBlock() + { return false; } - + @Override - public boolean isFullCube(IBlockState state){ - return false; + public boolean isOpaqueCube() + { + return false; } @Override - public Item getItemDropped(IBlockState state, Random rand, int fortune){ + public int getRenderType(){ + return 23; + } + + @Override + public Item getItemDropped(int a, Random random, int b){ return null; } diff --git a/src/main/java/electroblob/wizardry/block/BlockSpectral.java b/src/main/java/electroblob/wizardry/block/BlockSpectral.java index 23837eea..3bf42f7c 100644 --- a/src/main/java/electroblob/wizardry/block/BlockSpectral.java +++ b/src/main/java/electroblob/wizardry/block/BlockSpectral.java @@ -2,106 +2,73 @@ package electroblob.wizardry.block; import java.util.Random; +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardryBlocks; import electroblob.wizardry.tileentity.TileEntityTimer; -import electroblob.wizardry.util.WizardryParticleType; import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; -import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.block.state.IBlockState; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.EnumBlockRenderType; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraftforge.event.world.BlockEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -// For future reference - extend BlockContainer whenever possible because it has methods for removing tile entities on -// block break. -@Mod.EventBusSubscriber +// For future reference - extend BlockContainer whenever possible because it has methods for removing tile entities on block break. public class BlockSpectral extends BlockContainer { public BlockSpectral(Material material) { super(material); - this.setSoundType(SoundType.GLASS); - } - - // Replaces getRenderBlockPass - @Override - public BlockRenderLayer getBlockLayer(){ - return BlockRenderLayer.TRANSLUCENT; - } - - @Override - public EnumBlockRenderType getRenderType(IBlockState state) { - return EnumBlockRenderType.MODEL; } - // Apparently it's OK to override this, despite it being deprecated. More importantly, it being deprecated is not - // Forge's doing, rather it is Mojang themselves misusing the @Deprecated annotation to mean 'internal, don't call'. @Override - public boolean isOpaqueCube(IBlockState state){ + public int getRenderBlockPass() + { + return 1; + } + + @Override + public boolean isOpaqueCube() + { return false; } - + @Override - public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) { - return false; - } - + public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5) + { + Block block = par1IBlockAccess.getBlock(par2, par3, par4); + return block == this ? false : super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5); + } + @Override - public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random) { - // Middle of block - Wizardry.proxy.spawnParticle(WizardryParticleType.DUST, world, pos.getX()+random.nextDouble(), pos.getY()+random.nextDouble(), pos.getZ()+random.nextDouble(), 0, 0, 0, (int)(16.0D / (Math.random() * 0.8D + 0.2D)), - 0.4f + random.nextFloat()*0.2f, 0.6f + random.nextFloat()*0.4f, 0.6f + random.nextFloat()*0.4f); - // Top surface - Wizardry.proxy.spawnParticle(WizardryParticleType.DUST, world, pos.getX()+random.nextDouble(), pos.getY()+1, pos.getZ()+random.nextDouble(), 0, 0, 0, (int)(16.0D / (Math.random() * 0.8D + 0.2D)), - 0.4f + random.nextFloat()*0.2f, 0.6f + random.nextFloat()*0.4f, 0.6f + random.nextFloat()*0.4f); - Wizardry.proxy.spawnParticle(WizardryParticleType.DUST, world, pos.getX()+random.nextDouble(), pos.getY()+1, pos.getZ()+random.nextDouble(), 0, 0, 0, (int)(16.0D / (Math.random() * 0.8D + 0.2D)), - 0.4f + random.nextFloat()*0.2f, 0.6f + random.nextFloat()*0.4f, 0.6f + random.nextFloat()*0.4f); - } - + public void randomDisplayTick(World world, int x, int y, int z, Random random){ + // Middle of block + Wizardry.proxy.spawnParticle(EnumParticleType.DUST, world, x+random.nextDouble(), y+random.nextDouble(), z+random.nextDouble(), 0, 0, 0, (int)(16.0D / (Math.random() * 0.8D + 0.2D)), + 0.4f + random.nextFloat()*0.2f, 0.6f + random.nextFloat()*0.4f, 0.6f + random.nextFloat()*0.4f); + // Top surface + Wizardry.proxy.spawnParticle(EnumParticleType.DUST, world, x+random.nextDouble(), y+1, z+random.nextDouble(), 0, 0, 0, (int)(16.0D / (Math.random() * 0.8D + 0.2D)), + 0.4f + random.nextFloat()*0.2f, 0.6f + random.nextFloat()*0.4f, 0.6f + random.nextFloat()*0.4f); + Wizardry.proxy.spawnParticle(EnumParticleType.DUST, world, x+random.nextDouble(), y+1, z+random.nextDouble(), 0, 0, 0, (int)(16.0D / (Math.random() * 0.8D + 0.2D)), + 0.4f + random.nextFloat()*0.2f, 0.6f + random.nextFloat()*0.4f, 0.6f + random.nextFloat()*0.4f); + } + // Overriden to make the block always look full brightness despite not emitting full light. @Override - public int getPackedLightmapCoords(IBlockState state, IBlockAccess source, BlockPos pos) { - return 15; - } + public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4) + { + return 15; + } @Override public TileEntity createNewTileEntity(World world, int metadata) { return new TileEntityTimer(1200); } + /** + * Returns the quantity of items to drop on block destruction. + */ @Override - public int quantityDropped(Random par1Random){ + public int quantityDropped(Random par1Random) + { return 0; } - - @SuppressWarnings("deprecation") - @SideOnly(Side.CLIENT) - @Override - public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side){ - - IBlockState iblockstate = blockAccess.getBlockState(pos.offset(side)); - Block block = iblockstate.getBlock(); - - return block == this ? false : super.shouldSideBeRendered(blockState, blockAccess, pos, side); - } - - @SubscribeEvent - public static void onBlockPlaceEvent(BlockEvent.PlaceEvent event){ - // Spectral blocks cannot be built on - if(event.getPlacedAgainst() == WizardryBlocks.spectral_block){ - event.setCanceled(true); - } - } } diff --git a/src/main/java/electroblob/wizardry/block/BlockStatue.java b/src/main/java/electroblob/wizardry/block/BlockStatue.java index 3b3e9b5e..364483c9 100644 --- a/src/main/java/electroblob/wizardry/block/BlockStatue.java +++ b/src/main/java/electroblob/wizardry/block/BlockStatue.java @@ -2,50 +2,43 @@ package electroblob.wizardry.block; import java.util.Random; -import electroblob.wizardry.spell.Petrify; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import electroblob.wizardry.tileentity.TileEntityStatue; import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; -import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; -import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.EnumBlockRenderType; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.Facing; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; public class BlockStatue extends BlockContainer { private boolean isIce; - public BlockStatue(Material material) { - super(material); - this.isIce = material == Material.ICE; + public BlockStatue(Material par2Material) { + super(par2Material); + this.isIce = par2Material == Material.ice; if(this.isIce){ this.slipperiness = 0.98F; - this.setSoundType(SoundType.GLASS); } } - + @Override - public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos){ + public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) { // Not a good idea to call getBlockBoundsMinX() or whatever from in here, since this method changes those! if(!this.isIce){ - if(world.getTileEntity(pos) instanceof TileEntityStatue){ + if(world.getTileEntity(x, y, z) instanceof TileEntityStatue){ - TileEntityStatue statue = (TileEntityStatue)world.getTileEntity(pos); + TileEntityStatue statue = (TileEntityStatue)world.getTileEntity(x, y, z); if(statue.creature != null){ - // Block bounds are set to match the width and height of the entity, clamped to within 1 block. - return new AxisAlignedBB((float)Math.max(0.5 - statue.creature.width/2, 0), 0, + this.setBlockBounds((float)Math.max(0.5 - statue.creature.width/2, 0), 0, (float)Math.max(0.5 - statue.creature.width/2, 0), (float)Math.min(0.5 + statue.creature.width/2, 1), // This checks if the block is the top one and if so reduces its height so the top lines up with @@ -55,92 +48,125 @@ public class BlockStatue extends BlockContainer { } } } - - return FULL_BLOCK_AABB; } - - // getCollisionBoundingBox eventually calls getBoundingBox anyway, and since I want the collision box and the block - // outline to be the same here, I've removed that getCollisionBoundingBox entirely. - // The number of these methods is quite simply ridiculous. This one seems to be for placement logic and block - // connections (fences, glass panes, etc.)... - @Override public boolean isFullCube(IBlockState state) { return false; } - // ...this one isn't used much but has something to do with redstone... - @Override public boolean isBlockNormalCube(IBlockState state) { return false; } - // ... this one is for most other game logic... - @Override public boolean isNormalCube(IBlockState state) { return false; } - // Forge version of the above method. I still need to override both though because vanilla uses the other one. - @Override public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) { return false; } - // ... and this one is for rendering. - @Override public boolean isOpaqueCube(IBlockState state){ return false; } - @Override - public BlockRenderLayer getBlockLayer(){ - return this.isIce ? BlockRenderLayer.TRANSLUCENT : BlockRenderLayer.SOLID; + public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) { + + if(!this.isIce){ + + if(world.getTileEntity(x, y, z) instanceof TileEntityStatue){ + + TileEntityStatue statue = (TileEntityStatue)world.getTileEntity(x, y, z); + + if(statue.creature != null){ + // Block bounds are set to match the width and height of the entity, clamped to within 1 block. + return AxisAlignedBB.getBoundingBox(x + Math.max(0.5 - statue.creature.width/2, 0), + y, z + Math.max(0.5 - statue.creature.width/2, 0), + x + Math.min(0.5 + statue.creature.width/2, 1), + // This checks if the block is the top one and if so reduces its height so the top lines up with + // the top of the entity model + statue.position == statue.parts ? y + (float)Math.min(statue.creature.height - statue.parts + 1, 1) : y + 1, + z + Math.min(0.5 + statue.creature.width/2, 1)); + } + } + } + + return super.getCollisionBoundingBoxFromPool(world, x, y, z); } - + @Override - public EnumBlockRenderType getRenderType(IBlockState state){ - return this.isIce ? EnumBlockRenderType.MODEL : EnumBlockRenderType.ENTITYBLOCK_ANIMATED; + public boolean renderAsNormalBlock(){ + return false; + } + + @Override + public boolean canRenderInPass(int pass){ + return this.isIce ? super.canRenderInPass(pass) : false; + } + + @Override + public boolean isOpaqueCube(){ + return false;// !this.isIce; + } + + @Override + public int getRenderBlockPass() + { + return this.isIce? 1 : 0; } @Override public TileEntity createNewTileEntity(World world, int metadata) { return new TileEntityStatue(this.isIce); } - + /* @Override - public int quantityDropped(Random random){ + public void randomDisplayTick(World world, int x, int y, int z, Random random){ + if(this.isIce){ + float brightness = 0.5f + (random.nextFloat()/2); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySparkleFX(world, x + random.nextDouble(), y + random.nextDouble(), z + random.nextDouble(), 0, 0, 0, null, brightness, brightness + 0.1f, 1.0f, true)); + } + } + */ + + + /** + * Returns the quantity of items to drop on block destruction. + */ + @Override + public int quantityDropped(Random par1Random) + { return 0; } - + + /** + * Returns true if the given side of this block type should be rendered, if the adjacent block is at the given + * coordinates. Args: blockAccess, x, y, z, side + */ @Override - public void breakBlock(World world, BlockPos pos, IBlockState state){ - - if(!world.isRemote){ - - TileEntityStatue tileentity = (TileEntityStatue)world.getTileEntity(pos); - + @SideOnly(Side.CLIENT) + public boolean shouldSideBeRendered(IBlockAccess p_149646_1_, int p_149646_2_, int p_149646_3_, int p_149646_4_, int p_149646_5_) + { + Block block = p_149646_1_.getBlock(p_149646_2_, p_149646_3_, p_149646_4_); + + return block == this ? false : super.shouldSideBeRendered(p_149646_1_, p_149646_2_, p_149646_3_, p_149646_4_, p_149646_5_); + } + + @Override + public void breakBlock(World par1World, int x, int y, int z, Block block, int par6) + { + if(!par1World.isRemote){ + TileEntityStatue tileentity = (TileEntityStatue)par1World.getTileEntity(x, y, z); if(tileentity != null){ if(tileentity.parts == 2){ if(tileentity.position == 2){ - world.destroyBlock(pos.down(), false); + // func_147480_a is the method that causes the block to smash as if broken by a player. + // Used to be called destroyBlock. The boolean is whether the block should drop items. + par1World.func_147480_a(x, y-1, z, false); }else{ - world.destroyBlock(pos.up(), false); + par1World.func_147480_a(x, y+1, z, false); } }else if(tileentity.parts == 3){ if(tileentity.position == 3){ - world.destroyBlock(pos.down(), false); - world.destroyBlock(pos.down(2), false); + par1World.func_147480_a(x, y-1, z, false); + par1World.func_147480_a(x, y-2, z, false); }else if(tileentity.position == 2){ - world.destroyBlock(pos.down(), false); - world.destroyBlock(pos.up(), false); + par1World.func_147480_a(x, y-1, z, false); + par1World.func_147480_a(x, y+1, z, false); }else{ - world.destroyBlock(pos.up(), false); - world.destroyBlock(pos.up(2), false); + par1World.func_147480_a(x, y+1, z, false); + par1World.func_147480_a(x, y+2, z, false); } } } // This is only when position == 1 because world.destroyBlock calls this function for the other blocks. if(tileentity != null && tileentity.position == 1 && tileentity.creature != null){ - tileentity.creature.getEntityData().removeTag(Petrify.NBT_KEY); tileentity.creature.isDead = false; - world.spawnEntityInWorld(tileentity.creature); + par1World.spawnEntityInWorld(tileentity.creature); } } - - super.breakBlock(world, pos, state); + super.breakBlock(par1World, x, y, z, block, par6); } - - @SuppressWarnings("deprecation") - @SideOnly(Side.CLIENT) - @Override - public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side){ - - IBlockState iblockstate = blockAccess.getBlockState(pos.offset(side)); - Block block = iblockstate.getBlock(); - - return this.isIce && block == this ? false : super.shouldSideBeRendered(blockState, blockAccess, pos, side); - } } diff --git a/src/main/java/electroblob/wizardry/block/BlockTransportationStone.java b/src/main/java/electroblob/wizardry/block/BlockTransportationStone.java index 681d5266..f555b9e1 100644 --- a/src/main/java/electroblob/wizardry/block/BlockTransportationStone.java +++ b/src/main/java/electroblob/wizardry/block/BlockTransportationStone.java @@ -2,114 +2,148 @@ package electroblob.wizardry.block; import java.util.Random; -import electroblob.wizardry.WizardData; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryRegistry; import electroblob.wizardry.item.ItemWand; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.registry.WizardryBlocks; +import electroblob.wizardry.spell.Spell; import net.minecraft.block.Block; import net.minecraft.block.material.Material; -import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.world.IBlockAccess; +import net.minecraft.util.ChatComponentTranslation; import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; -public class BlockTransportationStone extends Block { - - private static final AxisAlignedBB AABB = new AxisAlignedBB(0.0625f*5, 0, 0.0625f*5, 0.0625f*11, 0.0625f*6, 0.0625f*11); +public class BlockTransportationStone extends Block{ public BlockTransportationStone(Material material){ super(material); + this.setBlockBounds(0.0625f*5, 0, 0.0625f*5, 0.0625f*11, 0.0625f*6, 0.0625f*11); this.setTickRandomly(true); } - - @Override - public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){ - return AABB; - } - - // The number of these methods is quite simply ridiculous. This one seems to be for placement logic and block - // connections (fences, glass panes, etc.)... - @Override public boolean isFullCube(IBlockState state) { return false; } - // ...this one isn't used much but has something to do with redstone... - @Override public boolean isBlockNormalCube(IBlockState state) { return false; } - // ... this one is for most other game logic... - @Override public boolean isNormalCube(IBlockState state) { return false; } - // Forge version of the above method. I still need to override both though because vanilla uses the other one. - @Override public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) { return false; } - // ... and this one is for rendering. - @Override public boolean isOpaqueCube(IBlockState state){ return false; } - - @Override - public void onNeighborChange(IBlockAccess world, BlockPos pos, BlockPos neighbor){ - - super.onNeighborChange(world, pos, neighbor); - - if(!world.isSideSolid(pos.down(), EnumFacing.UP, false) && world instanceof World){ - this.dropBlockAsItem((World) world, pos, world.getBlockState(pos), 0); - ((World)world).setBlockToAir(pos); - } - } - - @Override - public void updateTick(World world, BlockPos pos, IBlockState state, Random random) { - if(!world.isSideSolid(pos.down(), EnumFacing.UP)){ - this.dropBlockAsItem(world, pos, world.getBlockState(pos), 0); - world.setBlockToAir(pos); + @Override + public boolean isOpaqueCube(){ + return false; + } + + @Override + public boolean renderAsNormalBlock(){ + return false; + } + + @Override + public void onNeighborBlockChange(World world, int x, int y, int z, Block block) + { + super.onNeighborBlockChange(world, x, y, z, block); + if(!world.isSideSolid(x, y-1, z, ForgeDirection.UP)){ + this.dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0); + world.setBlockToAir(x, y, z); } - } + } @Override - public boolean canPlaceBlockAt(World world, BlockPos pos){ - return super.canPlaceBlockAt(world, pos) && world.isSideSolid(pos.down(), EnumFacing.UP); - } + public void updateTick(World world, int x, int y, int z, Random random) + { + if(!world.isSideSolid(x, y-1, z, ForgeDirection.UP)){ + this.dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0); + world.setBlockToAir(x, y, z); + } + } @Override - public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, - EnumHand hand, ItemStack stack, EnumFacing side, float hitX, float hitY, float hitZ) { - - if(stack != null && stack.getItem() instanceof ItemWand){ - if(WizardData.get(player) != null){ + public boolean canPlaceBlockAt(World par1World, int x, int y, int z) + { + return super.canPlaceBlockAt(par1World, x, y, z) && par1World.isSideSolid(x, y-1, z, ForgeDirection.UP); + } + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityplayer, int par6, float par7, float par8, float par9) + { + if(entityplayer.getHeldItem() != null && entityplayer.getHeldItem().getItem() instanceof ItemWand){ + if(ExtendedPlayer.get(entityplayer) != null){ + ExtendedPlayer extendedplayer = ExtendedPlayer.get(entityplayer); - WizardData data = WizardData.get(player); - - for(int x=-1; x<=1; x++){ - for(int z=-1; z<=1; z++){ - BlockPos pos1 = pos.add(x, 0, z); - if(testForCircle(world, pos1)){ - data.setStoneCircleLocation(pos1, world.provider.getDimension()); - if(!world.isRemote) player.addChatMessage(new TextComponentTranslation("tile.wizardry:transportation_stone.confirm", Spells.transportation.getNameForTranslationFormatted())); - return true; - } - } + int x1=x-1, z1=z-1; + if(testForCircle(world, x1, y, z1)){ + extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId); + if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name); + return true; } - if(!world.isRemote) player.addChatMessage(new TextComponentTranslation("tile.wizardry:transportation_stone.invalid")); + x1=x; + z1=z-1; + if(testForCircle(world, x1, y, z1)){ + extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId); + if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name); + return true; + } + + x1=x+1; + z1=z-1; + if(testForCircle(world, x1, y, z1)){ + extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId); + if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name); + return true; + } + + x1=x-1; + z1=z; + if(testForCircle(world, x1, y, z1)){ + extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId); + if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name); + return true; + } + + x1=x+1; + z1=z; + if(testForCircle(world, x1, y, z1)){ + extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId); + if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name); + return true; + } + + x1=x-1; + z1=z+1; + if(testForCircle(world, x1, y, z1)){ + extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId); + if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name); + return true; + } + + x1=x; + z1=z+1; + if(testForCircle(world, x1, y, z1)){ + extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId); + if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name); + return true; + } + + x1=x+1; + z1=z+1; + if(testForCircle(world, x1, y, z1)){ + extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId); + if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name); + return true; + } + + if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.invalid"));//"You must make a circle with 8 stones of transportation first!"); return true; } } return false; - } + } /** Returns whether the specified location is surrounded by a complete cicle of 8 transportation stones. */ - public static boolean testForCircle(World world, BlockPos pos){ - - if(world.getBlockState(pos).getMaterial().blocksMovement()) return false; - - for(int x=-1; x<=1; x++){ - for(int z=-1; z<=1; z++){ - if(world.getBlockState(pos.add(x, 0, z)).getBlock() != WizardryBlocks.transportation_stone){ - if(x != 0 || z != 0) return false; - } - } - } - - return true; + public static boolean testForCircle(World world, int x, int y, int z){ + return world.getBlock(x-1, y, z-1) == Wizardry.transportationStone + && world.getBlock(x, y, z-1) == Wizardry.transportationStone + && world.getBlock(x+1, y, z-1) == Wizardry.transportationStone + && world.getBlock(x-1, y, z) == Wizardry.transportationStone + && !world.getBlock(x, y, z).getMaterial().blocksMovement() + && world.getBlock(x+1, y, z) == Wizardry.transportationStone + && world.getBlock(x-1, y, z+1) == Wizardry.transportationStone + && world.getBlock(x, y, z+1) == Wizardry.transportationStone + && world.getBlock(x+1, y, z+1) == Wizardry.transportationStone; } } diff --git a/src/main/java/electroblob/wizardry/block/BlockVanishingCobweb.java b/src/main/java/electroblob/wizardry/block/BlockVanishingCobweb.java index 3dcc77cd..b96fa137 100644 --- a/src/main/java/electroblob/wizardry/block/BlockVanishingCobweb.java +++ b/src/main/java/electroblob/wizardry/block/BlockVanishingCobweb.java @@ -2,19 +2,17 @@ package electroblob.wizardry.block; import java.util.Random; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.Wizardry; import electroblob.wizardry.tileentity.TileEntityTimer; +import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; -import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.EnumBlockRenderType; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; // For future reference - extend BlockContainer whenever possible because it has methods for removing tile entities on block break. public class BlockVanishingCobweb extends BlockContainer { @@ -22,32 +20,15 @@ public class BlockVanishingCobweb extends BlockContainer { public BlockVanishingCobweb(Material material) { super(material); } - - @SideOnly(Side.CLIENT) - public BlockRenderLayer getBlockLayer() + + @Override + public int getRenderType() { - return BlockRenderLayer.CUTOUT; + return 1; } - + @Override - public EnumBlockRenderType getRenderType(IBlockState state){ - return EnumBlockRenderType.MODEL; - } - - @Override - public boolean isOpaqueCube(IBlockState state) - { - return false; - } - - @Override - public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, World worldIn, BlockPos pos) - { - return NULL_AABB; - } - - @Override - public boolean isFullCube(IBlockState state) + public boolean isOpaqueCube() { return false; } @@ -58,12 +39,22 @@ public class BlockVanishingCobweb extends BlockContainer { } @Override - public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity){ + public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity) + { entity.setInWeb(); } - + @Override - public int quantityDropped(Random par1Random){ + public AxisAlignedBB getCollisionBoundingBoxFromPool(World p_149668_1_, int p_149668_2_, int p_149668_3_, int p_149668_4_) { + return null; + } + + /** + * Returns the quantity of items to drop on block destruction. + */ + @Override + public int quantityDropped(Random par1Random) + { return 0; } diff --git a/src/main/java/electroblob/wizardry/client/ClientProxy.java b/src/main/java/electroblob/wizardry/client/ClientProxy.java index 5863acec..a92d164f 100644 --- a/src/main/java/electroblob/wizardry/client/ClientProxy.java +++ b/src/main/java/electroblob/wizardry/client/ClientProxy.java @@ -5,25 +5,32 @@ import java.util.HashMap; import org.lwjgl.input.Keyboard; +import cpw.mods.fml.client.config.GuiConfigEntries.NumberSliderEntry; +import cpw.mods.fml.client.registry.ClientRegistry; +import cpw.mods.fml.client.registry.RenderingRegistry; import electroblob.wizardry.CommonProxy; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.SpellGlyphData; -import electroblob.wizardry.WizardData; +import electroblob.wizardry.WandHelper; import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryRegistry; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.client.model.ModelSpiritHorse; +import electroblob.wizardry.client.model.ModelSpiritWolf; import electroblob.wizardry.client.model.ModelWizardArmour; -import electroblob.wizardry.client.particle.ParticleBlizzard; -import electroblob.wizardry.client.particle.ParticleDarkMagic; -import electroblob.wizardry.client.particle.ParticleDust; -import electroblob.wizardry.client.particle.ParticleGiantBubble; -import electroblob.wizardry.client.particle.ParticleIce; -import electroblob.wizardry.client.particle.ParticleLeaf; -import electroblob.wizardry.client.particle.ParticleMagicFlame; -import electroblob.wizardry.client.particle.ParticlePath; -import electroblob.wizardry.client.particle.ParticleRotatingSparkle; -import electroblob.wizardry.client.particle.ParticleSnow; -import electroblob.wizardry.client.particle.ParticleSpark; -import electroblob.wizardry.client.particle.ParticleSparkle; -import electroblob.wizardry.client.particle.ParticleTornado; -import electroblob.wizardry.client.renderer.LayerStone; +import electroblob.wizardry.client.particle.EntityBlizzardFX; +import electroblob.wizardry.client.particle.EntityDarkMagicFX; +import electroblob.wizardry.client.particle.EntityDustFX; +import electroblob.wizardry.client.particle.EntityIceFX; +import electroblob.wizardry.client.particle.EntityLeafFX; +import electroblob.wizardry.client.particle.EntityMagicBubbleFX; +import electroblob.wizardry.client.particle.EntityMagicFireFX; +import electroblob.wizardry.client.particle.EntityPathFX; +import electroblob.wizardry.client.particle.EntitySnowFX; +import electroblob.wizardry.client.particle.EntitySparkFX; +import electroblob.wizardry.client.particle.EntitySparkleFX; +import electroblob.wizardry.client.particle.EntityTornadoFX; import electroblob.wizardry.client.renderer.RenderArc; import electroblob.wizardry.client.renderer.RenderArcaneWorkbench; import electroblob.wizardry.client.renderer.RenderBlackHole; @@ -32,6 +39,7 @@ import electroblob.wizardry.client.renderer.RenderBubble; import electroblob.wizardry.client.renderer.RenderDecay; import electroblob.wizardry.client.renderer.RenderDecoy; import electroblob.wizardry.client.renderer.RenderEvilWizard; +import electroblob.wizardry.client.renderer.RenderFallingGrass; import electroblob.wizardry.client.renderer.RenderFireRing; import electroblob.wizardry.client.renderer.RenderForceArrow; import electroblob.wizardry.client.renderer.RenderHammer; @@ -41,14 +49,25 @@ import electroblob.wizardry.client.renderer.RenderLightningDisc; import electroblob.wizardry.client.renderer.RenderLightningPulse; import electroblob.wizardry.client.renderer.RenderMagicArrow; import electroblob.wizardry.client.renderer.RenderMagicLight; +import electroblob.wizardry.client.renderer.RenderMagicSlime; +import electroblob.wizardry.client.renderer.RenderMeteor; import electroblob.wizardry.client.renderer.RenderPhoenix; import electroblob.wizardry.client.renderer.RenderProjectile; import electroblob.wizardry.client.renderer.RenderSigil; +import electroblob.wizardry.client.renderer.RenderSilverfishMinion; +import electroblob.wizardry.client.renderer.RenderSkeletonMinion; +import electroblob.wizardry.client.renderer.RenderSpiderMinion; import electroblob.wizardry.client.renderer.RenderSpiritHorse; import electroblob.wizardry.client.renderer.RenderSpiritWolf; import electroblob.wizardry.client.renderer.RenderStatue; +import electroblob.wizardry.client.renderer.RenderTranslucentItem; import electroblob.wizardry.client.renderer.RenderWizard; +import electroblob.wizardry.client.renderer.RenderWraithMinion; +import electroblob.wizardry.client.renderer.RenderZombieMinion; import electroblob.wizardry.entity.EntityArc; +import electroblob.wizardry.entity.EntityFallingGrass; +import electroblob.wizardry.entity.EntityMagicSlime; +import electroblob.wizardry.entity.EntityMeteor; import electroblob.wizardry.entity.EntityShield; import electroblob.wizardry.entity.construct.EntityArrowRain; import electroblob.wizardry.entity.construct.EntityBlackHole; @@ -67,6 +86,7 @@ import electroblob.wizardry.entity.construct.EntityIceSpike; import electroblob.wizardry.entity.construct.EntityLightningPulse; import electroblob.wizardry.entity.construct.EntityLightningSigil; import electroblob.wizardry.entity.construct.EntityTornado; +import electroblob.wizardry.entity.living.EntityBlazeMinion; import electroblob.wizardry.entity.living.EntityDecoy; import electroblob.wizardry.entity.living.EntityEvilWizard; import electroblob.wizardry.entity.living.EntityIceGiant; @@ -74,12 +94,15 @@ import electroblob.wizardry.entity.living.EntityIceWraith; import electroblob.wizardry.entity.living.EntityLightningWraith; import electroblob.wizardry.entity.living.EntityPhoenix; import electroblob.wizardry.entity.living.EntityShadowWraith; +import electroblob.wizardry.entity.living.EntitySilverfishMinion; +import electroblob.wizardry.entity.living.EntitySkeletonMinion; +import electroblob.wizardry.entity.living.EntitySpiderMinion; import electroblob.wizardry.entity.living.EntitySpiritHorse; import electroblob.wizardry.entity.living.EntitySpiritWolf; import electroblob.wizardry.entity.living.EntityStormElemental; +import electroblob.wizardry.entity.living.EntitySummonedCreature; import electroblob.wizardry.entity.living.EntityWizard; -import electroblob.wizardry.entity.living.ISpellCaster; -import electroblob.wizardry.entity.living.ISummonedCreature; +import electroblob.wizardry.entity.living.EntityZombieMinion; import electroblob.wizardry.entity.projectile.EntityDarknessOrb; import electroblob.wizardry.entity.projectile.EntityDart; import electroblob.wizardry.entity.projectile.EntityFirebolt; @@ -97,81 +120,86 @@ import electroblob.wizardry.entity.projectile.EntitySmokeBomb; import electroblob.wizardry.entity.projectile.EntitySpark; import electroblob.wizardry.entity.projectile.EntitySparkBomb; import electroblob.wizardry.entity.projectile.EntityThunderbolt; -import electroblob.wizardry.event.SpellCastEvent; -import electroblob.wizardry.event.SpellCastEvent.Source; +import electroblob.wizardry.item.ItemFlamingAxe; +import electroblob.wizardry.item.ItemFrostAxe; import electroblob.wizardry.item.ItemScroll; +import electroblob.wizardry.item.ItemSpectralArmour; +import electroblob.wizardry.item.ItemSpectralBow; +import electroblob.wizardry.item.ItemSpectralPickaxe; +import electroblob.wizardry.item.ItemSpectralSword; import electroblob.wizardry.item.ItemSpellBook; import electroblob.wizardry.item.ItemWand; import electroblob.wizardry.packet.PacketCastContinuousSpell; import electroblob.wizardry.packet.PacketCastSpell; -import electroblob.wizardry.packet.PacketNPCCastSpell; import electroblob.wizardry.packet.PacketPlayerSync.Message; import electroblob.wizardry.packet.PacketTransportation; -import electroblob.wizardry.registry.Spells; import electroblob.wizardry.spell.Clairvoyance; -import electroblob.wizardry.spell.None; import electroblob.wizardry.spell.Spell; import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench; import electroblob.wizardry.tileentity.TileEntityMagicLight; import electroblob.wizardry.tileentity.TileEntityStatue; -import electroblob.wizardry.util.WandHelper; -import electroblob.wizardry.util.WizardryParticleType; -import net.minecraft.block.state.IBlockState; +import net.minecraft.block.Block; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.renderer.entity.RenderBlaze; +import net.minecraft.client.model.ModelSlime; +import net.minecraft.client.particle.EntityDiggingFX; import net.minecraft.client.resources.I18n; import net.minecraft.client.settings.KeyBinding; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.monster.EntityBlaze; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.SoundEvent; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; +import net.minecraft.util.Vec3; import net.minecraft.world.World; +import net.minecraftforge.client.MinecraftForgeClient; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.config.Property; -import net.minecraftforge.fml.client.config.GuiConfigEntries.NumberSliderEntry; -import net.minecraftforge.fml.client.registry.ClientRegistry; -import net.minecraftforge.fml.client.registry.RenderingRegistry; -/** - * The client proxy for wizardry. - * @author Electroblob - * @since Wizardry 1.0 - */ public class ClientProxy extends CommonProxy { /** Static instance of the mixed font renderer */ public static MixedFontRenderer mixedFontRenderer; // Key Bindings - public static final KeyBinding NEXT_SPELL = new KeyBinding("key.wizardry.next_spell", Keyboard.KEY_N, "key.categories.wizardry"); - public static final KeyBinding PREVIOUS_SPELL = new KeyBinding("key.wizardry.previous_spell", Keyboard.KEY_B, "key.categories.wizardry"); + public static final KeyBinding nextSpell = new KeyBinding("key.next_spell", Keyboard.KEY_N, "key.categories.wizardry"); + public static final KeyBinding previousSpell = new KeyBinding("key.previous_spell", Keyboard.KEY_B, "key.categories.wizardry"); // Armour Model - public static final ModelBiped WIZARD_ARMOUR_MODEL = new ModelWizardArmour(0.75f); - - // SECTION Registry - // =============================================================================================================== + public static ModelBiped wizardArmourModel = new ModelWizardArmour(0.75f); @Override public ModelBiped getWizardArmourModel(){ - return WIZARD_ARMOUR_MODEL; + return wizardArmourModel; + } + + @Override + public double getPlayerEyesPos(EntityPlayer player){ + return Minecraft.getMinecraft().thePlayer == player ? player.posY : player.posY + player.eyeHeight; + } + + @Override + public Vec3 getWandTipPosition(EntityLivingBase entity){ + // Behaves differently in first person + if(Minecraft.getMinecraft().thePlayer == entity && Minecraft.getMinecraft().gameSettings.thirdPersonView == 0){ + return Vec3.createVectorHelper(entity.posX, entity.boundingBox.minY + 1.2, entity.posZ); + }else{ + return super.getWandTipPosition(entity); + } } @Override public void registerKeyBindings(){ - ClientRegistry.registerKeyBinding(NEXT_SPELL); - ClientRegistry.registerKeyBinding(PREVIOUS_SPELL); + ClientRegistry.registerKeyBinding(nextSpell); + ClientRegistry.registerKeyBinding(previousSpell); + } + + @Override + public void registerEventHandlers(){ + super.registerEventHandlers(); + MinecraftForge.EVENT_BUS.register(new WizardryClientEventHandler()); } @Override @@ -179,37 +207,15 @@ public class ClientProxy extends CommonProxy { MinecraftForge.EVENT_BUS.register(new GuiSpellDisplay(Minecraft.getMinecraft())); } - @Override - public void initMixedFontRenderer(){ - mixedFontRenderer = new MixedFontRenderer(Minecraft.getMinecraft().gameSettings, - new ResourceLocation("textures/font/ascii.png"), Minecraft.getMinecraft().renderEngine, false); - } - - // SECTION Misc - // =============================================================================================================== - @Override public void setToNumberSliderEntry(Property property) { property.setConfigEntryClass(NumberSliderEntry.class); } - @Override - public World getTheWorld() { - return Minecraft.getMinecraft().theWorld; - } - - @Override - public void playMovingSound(Entity entity, SoundEvent sound, float volume, float pitch, boolean repeat){ - Minecraft.getMinecraft().getSoundHandler().playSound(new MovingSoundEntity(entity, sound, volume, pitch, repeat)); - } - - // SECTION Items - // =============================================================================================================== - @Override public FontRenderer getFontRenderer(ItemStack stack){ - Spell spell = Spells.none; + Spell spell = WizardryRegistry.none; if(stack.getItem() instanceof ItemWand){ spell = WandHelper.getCurrentSpell(stack); @@ -217,10 +223,8 @@ public class ClientProxy extends CommonProxy { spell = Spell.get(stack.getItemDamage()); } - if(Minecraft.getMinecraft().thePlayer != null && Wizardry.settings.discoveryMode - && WizardData.get(Minecraft.getMinecraft().thePlayer) != null - && !Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode - && !WizardData.get(Minecraft.getMinecraft().thePlayer).hasSpellBeenDiscovered(spell)){ + if(Wizardry.discoveryMode && ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer) != null && !Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode + && !ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer).hasSpellBeenDiscovered(spell)){ return mixedFontRenderer; } @@ -232,184 +236,111 @@ public class ClientProxy extends CommonProxy { // Displays [Empty slot] if spell is continuous. Spell spell = Spell.get(scroll.getItemDamage()); - if(spell.isContinuous) spell = Spells.none; + if(spell.isContinuous) spell = WizardryRegistry.none; EntityPlayer player = Minecraft.getMinecraft().thePlayer; boolean discovered = true; // It seems that this method is called when the world is loading, before thePlayer has been initialised. // If the player is null, the spell is assumed to be discovered. - if(player != null && Wizardry.settings.discoveryMode && !player.capabilities.isCreativeMode - && WizardData.get(player) != null && !WizardData.get(player).hasSpellBeenDiscovered(spell)){ + if(player != null && Wizardry.discoveryMode && !player.capabilities.isCreativeMode + && ExtendedPlayer.get(player) != null && !ExtendedPlayer.get(player).hasSpellBeenDiscovered(spell)){ discovered = false; } if(discovered){ - return I18n.format("item.wizardry:scroll.name", spell.getDisplayName()).trim(); + return I18n.format("item.scroll.name", spell.getDisplayName()).trim(); }else{ - return I18n.format("item.wizardry:scroll.undiscovered.name", "#" + SpellGlyphData.getGlyphName(spell, player.worldObj) + "#").trim(); + return I18n.format("item.scroll.undiscovered.name", "#" + SpellGlyphData.getGlyphName(spell, player.worldObj) + "#").trim(); } } @Override - public double getConjuredBowDurability(ItemStack stack){ - EntityPlayer player = Minecraft.getMinecraft().thePlayer; - if(player.getActiveItemStack() == stack){ - return (double)(stack.getItemDamage() + (player.getItemInUseMaxCount()) ) / (double)stack.getMaxDamage(); - } - return super.getConjuredBowDurability(stack); - } - - // SECTION Particles - // =============================================================================================================== - - @Override - public void spawnParticle(WizardryParticleType type, World world, double x, double y, double z, double velX, double velY, double velZ, int maxAge, float r, float g, float b, boolean doGravity, double radius){ + public void spawnParticle(EnumParticleType type, World world, double x, double y, double z, double velX, double velY, double velZ, int maxAge, float r, float g, float b, boolean doGravity, double radius){ - // Colour values are now automatically clamped to between 0 and 1, as values outside this range seem to - // cause strange effects in 1.10 (or more specifically, particles that are bright pink!) - // TODO: This is a terrible dirty fix, but it'll do for now. Find a nicer way in future. - if(type != WizardryParticleType.MAGIC_FIRE) r = MathHelper.clamp_float(r, 0, 1); - g = MathHelper.clamp_float(g, 0, 1); - b = MathHelper.clamp_float(b, 0, 1); - switch(type){ case BLIZZARD: - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleBlizzard(world, maxAge, x, z, radius, y)); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityBlizzardFX(world, r, g, b, maxAge, x, z, radius, y)); break; case BRIGHT_DUST: - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleDust(world, x, y, z, velX, velY, velZ, r, g, b, false)); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityDustFX(world, x, y, z, velX, velY, velZ, r, g, b, false)); break; case DARK_MAGIC: - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleDarkMagic(world, x, y, z, velX, velY, velZ, r, g, b)); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityDarkMagicFX(world, x, y, z, velX, velY, velZ, r, g, b)); break; case DUST: - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleDust(world, x, y, z, velX, velY, velZ, r, g, b, true)); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityDustFX(world, x, y, z, velX, velY, velZ, r, g, b, true)); break; case ICE: - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleIce(world, x, y, z, velX, velY, velZ, maxAge)); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityIceFX(world, x, y, z, velX, velY, velZ, maxAge)); break; case LEAF: - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleLeaf(world, x, y, z, velX, velY, velZ, maxAge)); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityLeafFX(world, x, y, z, velX, velY, velZ, maxAge)); break; case MAGIC_BUBBLE: - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleGiantBubble(world, x, y, z, velX, velY, velZ)); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityMagicBubbleFX(world, x, y, z, velX, velY, velZ)); break; case MAGIC_FIRE: - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleMagicFlame(world, x, y, z, velX, velY, velZ, maxAge, r == 0 ? 1 + world.rand.nextFloat() : r)); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityMagicFireFX(world, x, y, z, velX, velY, velZ, maxAge, r == 0 ? 1 + world.rand.nextFloat() : r)); break; case PATH: - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticlePath(world, x, y, z, velX, velY, velZ, r, g, b, maxAge)); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityPathFX(world, x, y, z, velX, velY, velZ, r, g, b, maxAge)); break; case SNOW: - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleSnow(world, x, y, z, velX, velY, velZ)); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySnowFX(world, x, y, z, velX, velY, velZ)); break; case SPARK: - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleSpark(world, x, y, z, velX, velY, velZ)); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySparkFX(world, x, y, z, velX, velY, velZ)); break; case SPARKLE: - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleSparkle(world, x, y, z, velX, velY, velZ, r, g, b, maxAge, doGravity)); - break; - case SPARKLE_ROTATING: - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleRotatingSparkle(world, maxAge, x, z, radius, y, r, g, b)); - break; - default: + Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySparkleFX(world, x, y, z, velX, velY, velZ, r, g, b, maxAge, doGravity)); break; } } @Override - public void spawnTornadoParticle(World world, double x, double y, double z, double velX, double velZ, double radius, int maxAge, IBlockState block, BlockPos pos){ - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleTornado(world, maxAge, x, z, radius, y, velX, velZ, block).setBlockPos(pos));//, world.rand.nextInt(6))); + public void spawnDigParticle(World world, double x, double y, double z, double velX, double velY, double velZ, Block block){ + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityDiggingFX(world, x, y, z, velX, velY, velZ, block, 0)); } - // SECTION Packet Handlers - // =============================================================================================================== + @Override + public void spawnTornadoParticle(World world, double x, double y, double z, double velX, double velZ, double radius, int maxAge, Block block, int metadata){ + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityTornadoFX(world, maxAge, x, z, radius, y, velX, velZ, block, metadata, world.rand.nextInt(6))); + } + + @Override + public void playMovingSound(Entity entity, String soundName, float volume, float pitch, boolean repeat){ + Minecraft.getMinecraft().getSoundHandler().playSound(new MovingSoundEntity(entity, soundName, volume, pitch, repeat)); + } @Override public void handleCastSpellPacket(PacketCastSpell.Message message){ World world = Minecraft.getMinecraft().theWorld; Entity caster = world.getEntityByID(message.casterID); + Entity target = world.getEntityByID(message.targetID); Spell spell = Spell.get(message.spellID); - // Should always be true + if(caster instanceof EntityPlayer){ - ((EntityPlayer)caster).setActiveHand(message.hand); + ItemStack stack = ((EntityPlayer)caster).getHeldItem(); + + if(stack != null) ((EntityPlayer)caster).setItemInUse(stack, stack.getMaxItemUseDuration()); // Duration isn't needed because it only ever affects things server-side, and anything that is // seen client-side gets synced elsewhere. - spell.cast(world, (EntityPlayer)caster, message.hand, 0, message.modifiers); - - Source source = Source.OTHER; - - if(((EntityPlayer)caster).getHeldItem(message.hand) != null){ - Item item = ((EntityPlayer)caster).getHeldItem(message.hand).getItem(); - if(item instanceof ItemWand){ - source = Source.WAND; - }else if(item instanceof ItemScroll){ - source = Source.SCROLL; - } - } - - // No need to check if the spell succeeded, because the packet is only ever sent when it succeeds. - // The handler for this event now deals with discovery. - MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post((EntityPlayer)caster, spell, message.modifiers, source)); - - }else{ - Wizardry.logger.warn("Recieved a PacketCastSpell, but the caster ID was not the ID of a player"); - } - } - - @Override - public void handleCastContinuousSpellPacket(PacketCastContinuousSpell.Message message){ + spell.cast(world, (EntityPlayer)caster, 0, message.damageMultiplier, message.rangeMultiplier, 1, message.blastMultiplier); - World world = Minecraft.getMinecraft().theWorld; - Entity caster = world.getEntityByID(message.casterID); - Spell spell = Spell.get(message.spellID); - // Should always be true - if(caster instanceof EntityPlayer){ + // Updates the spell discovery data client-side. Could be done by calling sync(), but that means sending + // another packet unnecessarily. + if(ExtendedPlayer.get((EntityPlayer)caster) != null){ + ExtendedPlayer.get((EntityPlayer)caster).discoverSpell(spell); + } - WizardData data = WizardData.get((EntityPlayer)caster); - - if(data != null){ - if(data.isCasting()){ - WizardData.get((EntityPlayer)caster).stopCastingContinuousSpell(); - }else{ - WizardData.get((EntityPlayer)caster).startCastingContinuousSpell(spell, message.modifiers); - } - } - }else{ - Wizardry.logger.warn("Recieved a PacketCastContinuousSpell, but the caster ID was not the ID of a player"); } - } - - @Override - public void handleNPCCastSpellPacket(PacketNPCCastSpell.Message message){ - - World world = Minecraft.getMinecraft().theWorld; - Entity caster = world.getEntityByID(message.casterID); - Entity target = message.targetID == -1 ? null : world.getEntityByID(message.targetID); - Spell spell = Spell.get(message.spellID); - // Should always be true - if(caster instanceof EntityLiving){ - - if(target instanceof EntityLivingBase){ - - spell.cast(world, (EntityLiving)caster, message.hand, 0, (EntityLivingBase)target, message.modifiers); - // Again, no need to check if the spell succeeded, because the packet is only ever sent when it succeeds. - MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post((EntityLiving)caster, spell, message.modifiers, Source.NPC)); - } - - if(caster instanceof ISpellCaster){ - if(spell.isContinuous || spell instanceof None){ - ((ISpellCaster)caster).setContinuousSpell(spell); - ((EntityLiving)caster).setAttackTarget((EntityLivingBase)target); - } - } - }else{ - Wizardry.logger.warn("Recieved a PacketNPCCastSpell, but the caster ID was not the ID of an EntityLiving"); + else if(caster instanceof EntityLiving && target instanceof EntityLivingBase){ + spell.cast(world, (EntityLiving)caster, (EntityLivingBase)target, message.damageMultiplier, message.rangeMultiplier, 1, message.blastMultiplier); } } @@ -418,39 +349,37 @@ public class ClientProxy extends CommonProxy { World world = Minecraft.getMinecraft().theWorld; Entity caster = world.getEntityByID(message.casterID); - // Moved from when the packet is sent to when it is received; fixes the sound not playing in first person. - caster.playSound(SoundEvents.BLOCK_PORTAL_TRAVEL, 1, 1); for(int i=0; i<20; i++){ double radius = 1; double angle = world.rand.nextDouble()*Math.PI*2; double x = caster.posX + radius*Math.cos(angle); - double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble()*2; + double y = WizardryUtilities.getEntityFeetPos(caster) + world.rand.nextDouble()*2; double z = caster.posZ + radius*Math.sin(angle); - Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleSparkle(world, x, y, z, 0, 0.02, 0, 0.6f, 1.0f, 0.6f, 80 + world.rand.nextInt(10))); + Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySparkleFX(world, x, y, z, 0, 0.02, 0, 0.6f, 1.0f, 0.6f, 80 + world.rand.nextInt(10))); } for(int i=0; i<20; i++){ double radius = 1; double angle = world.rand.nextDouble()*Math.PI*2; double x = caster.posX + radius*Math.cos(angle); - double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble()*2; + double y = WizardryUtilities.getEntityFeetPos(caster) + world.rand.nextDouble()*2; double z = caster.posZ + radius*Math.sin(angle); - world.spawnParticle(EnumParticleTypes.VILLAGER_HAPPY, x, y, z, 0, 0.02, 0); + world.spawnParticle("happyVillager", x, y, z, 0, 0.02, 0); } for(int i=0; i<20; i++){ double radius = 1; double angle = world.rand.nextDouble()*Math.PI*2; double x = caster.posX + radius*Math.cos(angle); - double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble()*2; + double y = WizardryUtilities.getEntityFeetPos(caster) + world.rand.nextDouble()*2; double z = caster.posZ + radius*Math.sin(angle); - world.spawnParticle(EnumParticleTypes.ENCHANTMENT_TABLE, x, y, z, 0, 0.02, 0); + world.spawnParticle("enchantmenttable", x, y, z, 0, 0.02, 0); } } @Override public void handlePlayerSyncPacket(Message message){ - WizardData properties = WizardData.get(Minecraft.getMinecraft().thePlayer); + ExtendedPlayer properties = ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer); if(properties != null){ @@ -461,8 +390,8 @@ public class ClientProxy extends CommonProxy { }else{ Entity entity = Minecraft.getMinecraft().theWorld.getEntityByID(message.selectedMinionID); - if(entity instanceof ISummonedCreature){ - properties.selectedMinion = new WeakReference((ISummonedCreature)entity); + if(entity instanceof EntitySummonedCreature){ + properties.selectedMinion = new WeakReference(entity); }else{ properties.selectedMinion = null; } @@ -472,7 +401,7 @@ public class ClientProxy extends CommonProxy { @Override public void handleGlyphDataPacket(electroblob.wizardry.packet.PacketGlyphData.Message message){ - + SpellGlyphData data = SpellGlyphData.get(Minecraft.getMinecraft().theWorld); data.randomNames = new HashMap(); @@ -485,109 +414,165 @@ public class ClientProxy extends CommonProxy { } } + @Override + public void handleCastContinuousSpellPacket(PacketCastContinuousSpell.Message message){ + + World world = Minecraft.getMinecraft().theWorld; + Entity caster = world.getEntityByID(message.casterID); + Spell spell = Spell.get(message.spellID); + // This should always be true + if(caster instanceof EntityPlayer){ + + ExtendedPlayer properties = ExtendedPlayer.get((EntityPlayer)caster); + + if(properties != null){ + if(properties.isCasting()){ + ExtendedPlayer.get((EntityPlayer)caster).stopCastingContinuousSpell(); + }else{ + ExtendedPlayer.get((EntityPlayer)caster).startCastingContinuousSpell(spell, message.damageMultiplier, message.rangeMultiplier, 1, message.blastMultiplier); + } + } + } + } + @Override public void handleClairvoyancePacket(electroblob.wizardry.packet.PacketClairvoyance.Message message) { Clairvoyance.spawnPathPaticles(Minecraft.getMinecraft().theWorld, message.path, message.durationMultiplier); } - // SECTION Rendering - // =============================================================================================================== - - private static final ResourceLocation ICE_WRAITH_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/ice_wraith.png"); - private static final ResourceLocation LIGHTNING_WRAITH_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_wraith.png"); - /** Static instance of the statue renderer, used to access the block breaking texture. */ - public static RenderStatue renderStatue; - @Override - public void initialiseLayers(){ - LayerStone.initialiseLayers(); + public double getWandDisplayDamage(ItemStack stack){ + ExtendedPlayer properties = ExtendedPlayer.get(net.minecraft.client.Minecraft.getMinecraft().thePlayer); + // If the player is creative or this wand is not the wand being used, the arbitrary placeholder damage is not displayed. + if(net.minecraft.client.Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode || net.minecraft.client.Minecraft.getMinecraft().thePlayer.getHeldItem() != stack){ + return (double)stack.getItemDamageForDisplay() / (double)stack.getMaxDamage(); + }else{ + return (double)(stack.getItemDamageForDisplay() + properties.damageToApply) / (double)stack.getMaxDamage(); + } } @Override - public void registerRenderers(){ + public int getConjuredItemDisplayDamage(ItemStack stack){ + if(stack.getItem() instanceof ItemSpectralSword){ + ExtendedPlayer properties = ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer); + return stack.getItemDamage() + properties.conjuredSwordDuration; + + }else if(stack.getItem() instanceof ItemSpectralPickaxe){ + ExtendedPlayer properties = ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer); + return stack.getItemDamage() + properties.conjuredPickaxeDuration; + + }else if(stack.getItem() instanceof ItemSpectralBow){ + ExtendedPlayer properties = ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer); + return stack.getItemDamage() + properties.conjuredBowDuration; + + }else if(stack.getItem() instanceof ItemSpectralArmour){ + ExtendedPlayer properties = ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer); + return stack.getItemDamage() + properties.conjuredArmourDuration; + + }else if(stack.getItem() instanceof ItemFlamingAxe){ + ExtendedPlayer properties = ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer); + return stack.getItemDamage() + properties.flamingAxeDuration; + + }else if(stack.getItem() instanceof ItemFrostAxe){ + ExtendedPlayer properties = ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer); + return stack.getItemDamage() + properties.frostAxeDuration; + } + + return 0; + } + + @Override + public void registerRenderers() { + + mixedFontRenderer = new MixedFontRenderer(Minecraft.getMinecraft().gameSettings, + new ResourceLocation("textures/font/ascii.png"), Minecraft.getMinecraft().renderEngine, false); + // Minions - // Yet another advantage to the new system: turns out you don't even need to register the renderer if you - // just want the vanilla one for the mob you're extending. - - // An anonymous class in a lambda expression! No point writing a separate class really, is there? - RenderingRegistry.registerEntityRenderingHandler(EntityLightningWraith.class, manager -> new RenderBlaze(manager){ - @Override - protected ResourceLocation getEntityTexture(EntityBlaze entity){ - return LIGHTNING_WRAITH_TEXTURE; - } - }); - - RenderingRegistry.registerEntityRenderingHandler(EntityIceWraith.class, manager -> new RenderBlaze(manager){ - @Override - protected ResourceLocation getEntityTexture(EntityBlaze entity){ - return ICE_WRAITH_TEXTURE; - } - }); - - RenderingRegistry.registerEntityRenderingHandler(EntityIceGiant.class, RenderIceGiant::new); - RenderingRegistry.registerEntityRenderingHandler(EntityPhoenix.class, RenderPhoenix::new); + RenderingRegistry.registerEntityRenderingHandler(EntityZombieMinion.class, new RenderZombieMinion()); + RenderingRegistry.registerEntityRenderingHandler(EntitySkeletonMinion.class, new RenderSkeletonMinion()); + RenderingRegistry.registerEntityRenderingHandler(EntitySpiderMinion.class, new RenderSpiderMinion()); + RenderingRegistry.registerEntityRenderingHandler(EntityBlazeMinion.class, new RenderWraithMinion(new ResourceLocation("textures/entity/blaze.png"))); + RenderingRegistry.registerEntityRenderingHandler(EntityIceWraith.class, new RenderWraithMinion(new ResourceLocation("wizardry:textures/entity/ice_wraith.png"))); + RenderingRegistry.registerEntityRenderingHandler(EntityLightningWraith.class, new RenderWraithMinion(new ResourceLocation("wizardry:textures/entity/lightning_wraith.png"))); + RenderingRegistry.registerEntityRenderingHandler(EntityMagicSlime.class, new RenderMagicSlime(new ModelSlime(16), new ModelSlime(0), 0.25F)); + RenderingRegistry.registerEntityRenderingHandler(EntityIceGiant.class, new RenderIceGiant()); + RenderingRegistry.registerEntityRenderingHandler(EntityPhoenix.class, new RenderPhoenix()); + RenderingRegistry.registerEntityRenderingHandler(EntitySilverfishMinion.class, new RenderSilverfishMinion()); // Projectiles - RenderingRegistry.registerEntityRenderingHandler(EntityMagicMissile.class, manager -> new RenderMagicArrow(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/magic_missile.png"), false, 8.0, 4.0, 16, 9, false)); - RenderingRegistry.registerEntityRenderingHandler(EntityIceShard.class, manager -> new RenderMagicArrow(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/ice_shard.png"), false, 8.0, 2.0, 16, 5, false)); - RenderingRegistry.registerEntityRenderingHandler(EntityLightningArrow.class, manager -> new RenderMagicArrow(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_arrow.png"), true, 8.0, 2.0, 16, 5, false)); - RenderingRegistry.registerEntityRenderingHandler(EntityDart.class, manager -> new RenderMagicArrow(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/dart.png"), false, 8.0, 2.0, 16, 5, true)); - RenderingRegistry.registerEntityRenderingHandler(EntityIceLance.class, manager -> new RenderMagicArrow(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/ice_lance.png"), false, 16.0, 3.0, 22, 5, true)); + RenderingRegistry.registerEntityRenderingHandler(EntityMagicMissile.class, new RenderMagicArrow(new ResourceLocation("wizardry:textures/entity/magic_missile.png"), false, 8.0, 4.0, 16, 9, false)); + RenderingRegistry.registerEntityRenderingHandler(EntityIceShard.class, new RenderMagicArrow(new ResourceLocation("wizardry:textures/entity/ice_shard.png"), false, 8.0, 2.0, 16, 5, false)); + RenderingRegistry.registerEntityRenderingHandler(EntityLightningArrow.class, new RenderMagicArrow(new ResourceLocation("wizardry:textures/entity/lightning_arrow.png"), true, 8.0, 2.0, 16, 5, false)); + RenderingRegistry.registerEntityRenderingHandler(EntityDart.class, new RenderMagicArrow(new ResourceLocation("wizardry:textures/entity/dart.png"), false, 8.0, 2.0, 16, 5, true)); + RenderingRegistry.registerEntityRenderingHandler(EntityIceLance.class, new RenderMagicArrow(new ResourceLocation("wizardry:textures/entity/ice_lance.png"), false, 16.0, 3.0, 22, 5, true)); - RenderingRegistry.registerEntityRenderingHandler(EntityForceArrow.class, RenderForceArrow::new); + RenderingRegistry.registerEntityRenderingHandler(EntityForceArrow.class, new RenderForceArrow()); // Creatures - RenderingRegistry.registerEntityRenderingHandler(EntitySpiritWolf.class, manager -> new RenderSpiritWolf(manager, 0.5f)); - RenderingRegistry.registerEntityRenderingHandler(EntitySpiritHorse.class, manager -> new RenderSpiritHorse(manager, 0.5f)); - RenderingRegistry.registerEntityRenderingHandler(EntityWizard.class, RenderWizard::new); - RenderingRegistry.registerEntityRenderingHandler(EntityEvilWizard.class, RenderEvilWizard::new); - RenderingRegistry.registerEntityRenderingHandler(EntityDecoy.class, RenderDecoy::new); + RenderingRegistry.registerEntityRenderingHandler(EntitySpiritWolf.class, new RenderSpiritWolf(new ModelSpiritWolf(), new ModelSpiritWolf(), 0.5f)); + RenderingRegistry.registerEntityRenderingHandler(EntitySpiritHorse.class, new RenderSpiritHorse(new ModelSpiritHorse(), 0.5f)); + RenderingRegistry.registerEntityRenderingHandler(EntityWizard.class, new RenderWizard()); + RenderingRegistry.registerEntityRenderingHandler(EntityEvilWizard.class, new RenderEvilWizard()); + RenderingRegistry.registerEntityRenderingHandler(EntityDecoy.class, new RenderDecoy()); // Throwables - RenderingRegistry.registerEntityRenderingHandler(EntitySparkBomb.class, manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/entity/spark_bomb.png"), false)); - RenderingRegistry.registerEntityRenderingHandler(EntityFirebomb.class, manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/items/firebomb.png"), false)); - RenderingRegistry.registerEntityRenderingHandler(EntityPoisonBomb.class, manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/items/poison_bomb.png"), false)); - RenderingRegistry.registerEntityRenderingHandler(EntityIceCharge.class, manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/entity/ice_charge.png"), false)); - RenderingRegistry.registerEntityRenderingHandler(EntityForceOrb.class, manager -> new RenderProjectile(manager, 0.7f, new ResourceLocation(Wizardry.MODID, "textures/entity/force_orb.png"), true)); - RenderingRegistry.registerEntityRenderingHandler(EntitySpark.class, manager -> new RenderProjectile(manager, 0.4f, new ResourceLocation(Wizardry.MODID, "textures/entity/spark.png"), true)); - RenderingRegistry.registerEntityRenderingHandler(EntityDarknessOrb.class, manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/entity/darkness_orb.png"), true)); - RenderingRegistry.registerEntityRenderingHandler(EntityFirebolt.class, manager -> new RenderProjectile(manager, 0.2f, new ResourceLocation(Wizardry.MODID, "textures/entity/firebolt.png"), false)); - RenderingRegistry.registerEntityRenderingHandler(EntityLightningDisc.class, manager -> new RenderLightningDisc(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_sigil.png"), 2.0f)); - RenderingRegistry.registerEntityRenderingHandler(EntitySmokeBomb.class, manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/items/smoke_bomb.png"), false)); + RenderingRegistry.registerEntityRenderingHandler(EntitySparkBomb.class, new RenderProjectile(0.6f, new ResourceLocation("wizardry:textures/entity/spark_bomb.png"), false)); + RenderingRegistry.registerEntityRenderingHandler(EntityFirebomb.class, new RenderProjectile(0.6f, new ResourceLocation("wizardry:textures/items/firebomb.png"), false)); + RenderingRegistry.registerEntityRenderingHandler(EntityPoisonBomb.class, new RenderProjectile(0.6f, new ResourceLocation("wizardry:textures/items/poison_bomb.png"), false)); + RenderingRegistry.registerEntityRenderingHandler(EntityIceCharge.class, new RenderProjectile(0.6f, new ResourceLocation("wizardry:textures/entity/ice_charge.png"), false)); + RenderingRegistry.registerEntityRenderingHandler(EntityForceOrb.class, new RenderProjectile(0.7f, new ResourceLocation("wizardry:textures/entity/force_orb.png"), true)); + RenderingRegistry.registerEntityRenderingHandler(EntitySpark.class, new RenderProjectile(0.4f, new ResourceLocation("wizardry:textures/entity/spark.png"), true)); + RenderingRegistry.registerEntityRenderingHandler(EntityDarknessOrb.class, new RenderProjectile(0.6f, new ResourceLocation("wizardry:textures/entity/darkness_orb.png"), true)); + RenderingRegistry.registerEntityRenderingHandler(EntityFirebolt.class, new RenderProjectile(0.2f, new ResourceLocation("wizardry:textures/entity/firebolt.png"), false)); + RenderingRegistry.registerEntityRenderingHandler(EntityLightningDisc.class, new RenderLightningDisc(new ResourceLocation("wizardry:textures/entity/lightning_sigil.png"), 2.0f)); + RenderingRegistry.registerEntityRenderingHandler(EntitySmokeBomb.class, new RenderProjectile(0.6f, new ResourceLocation("wizardry:textures/items/smoke_bomb.png"), false)); // Effects and constructs - RenderingRegistry.registerEntityRenderingHandler(EntityArc.class, RenderArc::new); - RenderingRegistry.registerEntityRenderingHandler(EntityBlackHole.class, RenderBlackHole::new); - RenderingRegistry.registerEntityRenderingHandler(EntityShield.class, RenderBlank::new); - RenderingRegistry.registerEntityRenderingHandler(EntityBubble.class, RenderBubble::new); - RenderingRegistry.registerEntityRenderingHandler(EntityHammer.class, RenderHammer::new); - RenderingRegistry.registerEntityRenderingHandler(EntityIceSpike.class, RenderIceSpike::new); + RenderingRegistry.registerEntityRenderingHandler(EntityArc.class, new RenderArc()); + RenderingRegistry.registerEntityRenderingHandler(EntityBlackHole.class, new RenderBlackHole()); + RenderingRegistry.registerEntityRenderingHandler(EntityShield.class, new RenderBlank()); + RenderingRegistry.registerEntityRenderingHandler(EntityMeteor.class, new RenderMeteor()); + RenderingRegistry.registerEntityRenderingHandler(EntityBubble.class, new RenderBubble()); + RenderingRegistry.registerEntityRenderingHandler(EntityHammer.class, new RenderHammer()); + RenderingRegistry.registerEntityRenderingHandler(EntityFallingGrass.class, new RenderFallingGrass()); + RenderingRegistry.registerEntityRenderingHandler(EntityIceSpike.class, new RenderIceSpike()); // Stuff that doesn't render - RenderingRegistry.registerEntityRenderingHandler(EntityBlizzard.class, RenderBlank::new); - RenderingRegistry.registerEntityRenderingHandler(EntityTornado.class, RenderBlank::new); - RenderingRegistry.registerEntityRenderingHandler(EntityArrowRain.class, RenderBlank::new); - RenderingRegistry.registerEntityRenderingHandler(EntityShadowWraith.class, RenderBlank::new); - RenderingRegistry.registerEntityRenderingHandler(EntityForcefield.class, RenderBlank::new); - RenderingRegistry.registerEntityRenderingHandler(EntityThunderbolt.class, RenderBlank::new); - RenderingRegistry.registerEntityRenderingHandler(EntityStormElemental.class, RenderBlank::new); - RenderingRegistry.registerEntityRenderingHandler(EntityEarthquake.class, RenderBlank::new); - RenderingRegistry.registerEntityRenderingHandler(EntityHailstorm.class, RenderBlank::new); + RenderingRegistry.registerEntityRenderingHandler(EntityBlizzard.class, new RenderBlank()); + RenderingRegistry.registerEntityRenderingHandler(EntityTornado.class, new RenderBlank()); + RenderingRegistry.registerEntityRenderingHandler(EntityArrowRain.class, new RenderBlank()); + RenderingRegistry.registerEntityRenderingHandler(EntityShadowWraith.class, new RenderBlank()); + RenderingRegistry.registerEntityRenderingHandler(EntityForcefield.class, new RenderBlank()); + RenderingRegistry.registerEntityRenderingHandler(EntityThunderbolt.class, new RenderBlank()); + RenderingRegistry.registerEntityRenderingHandler(EntityStormElemental.class, new RenderBlank()); + RenderingRegistry.registerEntityRenderingHandler(EntityEarthquake.class, new RenderBlank()); + RenderingRegistry.registerEntityRenderingHandler(EntityHailstorm.class, new RenderBlank()); // Runes on ground - RenderingRegistry.registerEntityRenderingHandler(EntityHealAura.class, manager -> new RenderSigil(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/healing_aura.png"), 5.0f, false)); - RenderingRegistry.registerEntityRenderingHandler(EntityFireSigil.class, manager -> new RenderSigil(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/fire_sigil.png"), 2.0f, true)); - RenderingRegistry.registerEntityRenderingHandler(EntityFrostSigil.class, manager -> new RenderSigil(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/frost_sigil.png"), 2.0f, true)); - RenderingRegistry.registerEntityRenderingHandler(EntityLightningSigil.class, manager -> new RenderSigil(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_sigil.png"), 2.0f, true)); - RenderingRegistry.registerEntityRenderingHandler(EntityFireRing.class, manager -> new RenderFireRing(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/ring_of_fire.png"), 5.0f)); - RenderingRegistry.registerEntityRenderingHandler(EntityDecay.class, RenderDecay::new); - RenderingRegistry.registerEntityRenderingHandler(EntityLightningPulse.class, manager -> new RenderLightningPulse(manager, 8.0f)); + RenderingRegistry.registerEntityRenderingHandler(EntityHealAura.class, new RenderSigil(new ResourceLocation("wizardry:textures/entity/healing_aura.png"), 5.0f, false)); + RenderingRegistry.registerEntityRenderingHandler(EntityFireSigil.class, new RenderSigil(new ResourceLocation("wizardry:textures/entity/fire_sigil.png"), 2.0f, true)); + RenderingRegistry.registerEntityRenderingHandler(EntityFrostSigil.class, new RenderSigil(new ResourceLocation("wizardry:textures/entity/frost_sigil.png"), 2.0f, true)); + RenderingRegistry.registerEntityRenderingHandler(EntityLightningSigil.class, new RenderSigil(new ResourceLocation("wizardry:textures/entity/lightning_sigil.png"), 2.0f, true)); + RenderingRegistry.registerEntityRenderingHandler(EntityFireRing.class, new RenderFireRing(new ResourceLocation("wizardry:textures/entity/ring_of_fire.png"), 5.0f)); + RenderingRegistry.registerEntityRenderingHandler(EntityDecay.class, new RenderDecay()); + RenderingRegistry.registerEntityRenderingHandler(EntityLightningPulse.class, new RenderLightningPulse(8.0f)); + + //RenderingRegistry.registerBlockHandler(new RenderSigilBlock()); // TESRs ClientRegistry.bindTileEntitySpecialRenderer(TileEntityArcaneWorkbench.class, new RenderArcaneWorkbench()); - ClientRegistry.bindTileEntitySpecialRenderer(TileEntityStatue.class, renderStatue = new RenderStatue()); + ClientRegistry.bindTileEntitySpecialRenderer(TileEntityStatue.class, new RenderStatue()); ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMagicLight.class, new RenderMagicLight()); + // Items + MinecraftForgeClient.registerItemRenderer(Wizardry.spectralSword, new RenderTranslucentItem()); + MinecraftForgeClient.registerItemRenderer(Wizardry.spectralPickaxe, new RenderTranslucentItem()); + MinecraftForgeClient.registerItemRenderer(Wizardry.spectralBow, new RenderTranslucentItem()); + MinecraftForgeClient.registerItemRenderer(Wizardry.spectralHelmet, new RenderTranslucentItem()); + MinecraftForgeClient.registerItemRenderer(Wizardry.spectralChestplate, new RenderTranslucentItem()); + MinecraftForgeClient.registerItemRenderer(Wizardry.spectralLeggings, new RenderTranslucentItem()); + MinecraftForgeClient.registerItemRenderer(Wizardry.spectralBoots, new RenderTranslucentItem()); + } } \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/client/EntityNameEntry.java b/src/main/java/electroblob/wizardry/client/EntityNameEntry.java index 3221e189..e3c2b27c 100644 --- a/src/main/java/electroblob/wizardry/client/EntityNameEntry.java +++ b/src/main/java/electroblob/wizardry/client/EntityNameEntry.java @@ -1,20 +1,17 @@ package electroblob.wizardry.client; -import java.util.HashMap; -import java.util.Map; - +import cpw.mods.fml.client.config.GuiButtonExt; +import cpw.mods.fml.client.config.GuiEditArray; +import cpw.mods.fml.client.config.GuiEditArrayEntries; +import cpw.mods.fml.client.config.GuiSelectString; +import cpw.mods.fml.client.config.GuiUtils; +import cpw.mods.fml.client.config.GuiEditArrayEntries.StringEntry; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.resources.I18n; import net.minecraft.entity.EntityList; -import net.minecraftforge.fml.client.config.GuiButtonExt; -import net.minecraftforge.fml.client.config.GuiEditArray; -import net.minecraftforge.fml.client.config.GuiEditArrayEntries; -import net.minecraftforge.fml.client.config.GuiEditArrayEntries.StringEntry; -import net.minecraftforge.fml.client.config.GuiSelectString; -import net.minecraftforge.fml.client.config.IConfigElement; +import cpw.mods.fml.client.config.IConfigElement; -/** [NYI] Intended as a way of choosing entities by name from all those currently registered, within the config file, so - * that users don't have to look up the entity IDs. I can't get this to work correctly at the moment. */ public class EntityNameEntry extends StringEntry { protected final GuiButtonExt btnValue; @@ -26,9 +23,9 @@ public class EntityNameEntry extends StringEntry { this.btnValue = new GuiButtonExt(0, 0, 0, owningEntryList.controlWidth, 18, I18n.format(this.textFieldValue.getText())); //this.btnValue.enabled = owningScreen.enabled; } - + @Override - public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected) + public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, Tessellator tessellator, int mouseX, int mouseY, boolean isSelected) { //super.drawEntry(slotIndex, x, y, listWidth, slotHeight, tessellator, mouseX, mouseY, isSelected); this.btnValue.xPosition = listWidth / 4; @@ -41,18 +38,19 @@ public class EntityNameEntry extends StringEntry { this.btnValue.displayString = this.textFieldValue.getText(); //btnValue.packedFGColour = value ? GuiUtils.getColorCode('2', true) : GuiUtils.getColorCode('4', true); - this.btnValue.drawButton(owningEntryList.getMC(), mouseX, mouseY); + this.btnValue.drawButton(owningEntryList.mc, mouseX, mouseY); } + /** + * Returns true if the mouse has been pressed on this control. + */ @Override public boolean mousePressed(int index, int x, int y, int mouseEvent, int relativeX, int relativeY) { - if (this.btnValue.mousePressed(owningEntryList.getMC(), x, y)) + if (this.btnValue.mousePressed(owningEntryList.mc, x, y)) { - btnValue.playPressSound(owningEntryList.getMC().getSoundHandler()); - // Some sort of type incompatiblity meant that I had to do this first. - Map map = new HashMap(EntityList.CLASS_TO_NAME); - Minecraft.getMinecraft().displayGuiScreen(new GuiSelectString(this.owningScreen, configElement, index, map, this.getValue(), true)); + btnValue.func_146113_a(owningEntryList.mc.getSoundHandler()); + Minecraft.getMinecraft().displayGuiScreen(new GuiSelectString(this.owningScreen, configElement, index, EntityList.classToStringMapping, this.getValue(), true)); owningEntryList.recalculateState(); return true; } @@ -60,6 +58,9 @@ public class EntityNameEntry extends StringEntry { return super.mousePressed(index, x, y, mouseEvent, relativeX, relativeY); } + /** + * Fired when the mouse button is released. Arguments: index, x, y, mouseEvent, relativeX, relativeY + */ @Override public void mouseReleased(int index, int x, int y, int mouseEvent, int relativeX, int relativeY) { diff --git a/src/main/java/electroblob/wizardry/client/GuiArcaneWorkbench.java b/src/main/java/electroblob/wizardry/client/GuiArcaneWorkbench.java index 43f0470a..3c2ba523 100644 --- a/src/main/java/electroblob/wizardry/client/GuiArcaneWorkbench.java +++ b/src/main/java/electroblob/wizardry/client/GuiArcaneWorkbench.java @@ -1,31 +1,44 @@ package electroblob.wizardry.client; -import org.lwjgl.input.Keyboard; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.util.Iterator; +import java.util.List; +import java.util.Map.Entry; +import org.lwjgl.input.Keyboard; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.SpellGlyphData; -import electroblob.wizardry.WizardData; +import electroblob.wizardry.WandHelper; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; +import electroblob.wizardry.WizardryGuiHandler; import electroblob.wizardry.item.ItemWand; import electroblob.wizardry.packet.PacketControlInput; import electroblob.wizardry.packet.WizardryPacketHandler; import electroblob.wizardry.spell.Spell; import electroblob.wizardry.tileentity.ContainerArcaneWorkbench; +import electroblob.wizardry.tileentity.SlotWizardry; import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench; -import electroblob.wizardry.util.WandHelper; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.inventory.GuiContainer; -import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraft.util.StatCollector; public class GuiArcaneWorkbench extends GuiContainer { @@ -66,12 +79,69 @@ public class GuiArcaneWorkbench extends GuiContainer { super.drawScreen(p_73863_1_, p_73863_2_, p_73863_3_); } + /** + * Draw the foreground layer for the GuiContainer (everything in front of the items) + */ + protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY){ + + this.fontRendererObj.drawString(this.arcaneWorkbenchInventory.hasCustomInventoryName() ? this.arcaneWorkbenchInventory.getInventoryName() : I18n.format(this.arcaneWorkbenchInventory.getInventoryName()), 8, 6, 4210752); + this.fontRendererObj.drawString(this.playerInventory.hasCustomInventoryName() ? this.playerInventory.getInventoryName() : I18n.format(this.playerInventory.getInventoryName()), 8, this.ySize - 96 + 2, 4210752); + + if(this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getHasStack() && this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack().getItem() instanceof ItemWand){ + + ItemStack wand = this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack(); + + this.fontRendererObj.drawStringWithShadow("\u00A7f" + wand.getDisplayName(), xSize + 6, 6, 0); + this.fontRendererObj.drawStringWithShadow("\u00A77" + StatCollector.translateToLocal("container.arcaneWorkbench.mana") + " " + (wand.getMaxDamage() - wand.getItemDamage()) + "/" + wand.getMaxDamage(), xSize + 6, 20, 0); + + Spell[] spells = WandHelper.getSpells(wand); + + int y = 34; + + for(Spell spell : spells){ + + boolean discovered = true; + + if(!this.mc.thePlayer.capabilities.isCreativeMode && ExtendedPlayer.get(this.mc.thePlayer) != null){ + discovered = ExtendedPlayer.get(this.mc.thePlayer).hasSpellBeenDiscovered(spell); + } + + if(discovered){ + this.fontRendererObj.drawStringWithShadow(spell.getDisplayNameWithFormatting(), xSize + 16, y, 0); + }else{ + this.mc.standardGalacticFontRenderer.drawStringWithShadow("\u00A79" + SpellGlyphData.getGlyphName(spell, this.mc.theWorld), xSize + 16, y, 0); + } + y += 10; + } + + if(WandHelper.getTotalUpgrades(wand) > 0){ + + this.fontRendererObj.drawStringWithShadow("\u00A7f" + StatCollector.translateToLocal("container.arcaneWorkbench.upgrades"), xSize + 6, y + 6, 0); + + int x = 0; + y = guiTop + 50 + spells.length*10; + // Wand upgrade tooltips + for(Item item : WandHelper.getSpecialUpgrades()){ + + int level = WandHelper.getUpgradeLevel(wand, item); + + if(level > 0){ + // No idea why this is -16 instead of +6, but it works! + if(isPointInRegion(xSize -16 + x, y, 16, 16, mouseX + guiLeft, mouseY + guiTop)){ + ItemStack stack = new ItemStack(item, level); + this.drawItemStackTooltip(stack, mouseX - guiLeft, mouseY - guiTop); + } + x += 18; + } + } + } + } + } + @Override public void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY) { - GlStateManager.pushAttrib(); - - GlStateManager.color(1F, 1F, 1F, 1F); + GL11.glColor4f(1F, 1F, 1F, 1F); Minecraft.getMinecraft().renderEngine.bindTexture(texture); // Main inventory @@ -82,7 +152,7 @@ public class GuiArcaneWorkbench extends GuiContainer { Slot slot = this.inventorySlots.getSlot(i); if(slot.xDisplayPosition >=0 && slot.yDisplayPosition >= 0) this.drawTexturedModalRect(guiLeft + slot.xDisplayPosition - 10, guiTop + slot.yDisplayPosition - 10, - 0, 220, 36, 36); + 64, 220, 36, 36); } // Tooltip only drawn if there is a wand @@ -103,15 +173,12 @@ public class GuiArcaneWorkbench extends GuiContainer { boolean discovered = true; - if(!this.mc.thePlayer.capabilities.isCreativeMode && WizardData.get(this.mc.thePlayer) != null){ - discovered = WizardData.get(this.mc.thePlayer).hasSpellBeenDiscovered(spell); + if(!this.mc.thePlayer.capabilities.isCreativeMode && ExtendedPlayer.get(this.mc.thePlayer) != null){ + discovered = ExtendedPlayer.get(this.mc.thePlayer).hasSpellBeenDiscovered(spell); } - // As of Wizardry 1.2, the icons have been split off into their own texture files to allow for add-on - // mods to add their own. - Minecraft.getMinecraft().renderEngine.bindTexture(discovered ? spell.element.getIcon() : Element.MAGIC.getIcon()); - // Renders the little element icon - WizardryUtilities.drawTexturedRect(guiLeft + xSize + 5, guiTop + 34 + 10*i++, 8, 8); + // Renders the little element icon if there is an element + this.drawTexturedModalRect(guiLeft + xSize + 5, guiTop + 34 + 10*i++, discovered ? spell.element.ordinal()*8 : 0, 220, 8, 8); } int x = 0; @@ -124,84 +191,39 @@ public class GuiArcaneWorkbench extends GuiContainer { if(level > 0){ ItemStack stack = new ItemStack(item, level); - GlStateManager.enableDepth(); - this.itemRender.renderItemAndEffectIntoGUI(stack, guiLeft + xSize + 6 + x, y); - this.itemRender.renderItemOverlayIntoGUI(this.fontRendererObj, stack, guiLeft + xSize + 6 + x, y, null); + this.itemRender.renderItemAndEffectIntoGUI(this.fontRendererObj, this.mc.getTextureManager(), stack, guiLeft + xSize + 6 + x, y); + this.itemRender.renderItemOverlayIntoGUI(this.fontRendererObj, this.mc.getTextureManager(), stack, guiLeft + xSize + 6 + x, y); x += 18; - GlStateManager.disableDepth(); } } } Minecraft.getMinecraft().renderEngine.bindTexture(texture); - - // Fixes the bug that caused the slot hightlight to render opaque. I don't know why it works, it just works! - GlStateManager.disableBlend(); - GlStateManager.enableAlpha(); - - GlStateManager.popAttrib(); - } - @Override - protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY){ + for(Object object : this.inventorySlots.inventorySlots){ + if(object instanceof Slot){ - this.fontRendererObj.drawString(this.arcaneWorkbenchInventory.hasCustomName() ? this.arcaneWorkbenchInventory.getName() : I18n.format(this.arcaneWorkbenchInventory.getName()), 8, 6, 4210752); - this.fontRendererObj.drawString(this.playerInventory.hasCustomName() ? this.playerInventory.getName() : I18n.format(this.playerInventory.getName()), 8, this.ySize - 96 + 2, 4210752); + Slot slot = (Slot)object; - if(this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getHasStack() && this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack().getItem() instanceof ItemWand){ - - ItemStack wand = this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack(); - - this.fontRendererObj.drawStringWithShadow("\u00A7f" + wand.getDisplayName(), xSize + 6, 6, 0); - this.fontRendererObj.drawStringWithShadow("\u00A77" + I18n.format("container.wizardry:arcane_workbench.mana") + " " + (wand.getMaxDamage() - wand.getItemDamage()) + "/" + wand.getMaxDamage(), xSize + 6, 20, 0); - - Spell[] spells = WandHelper.getSpells(wand); - - int y = 34; - - for(Spell spell : spells){ - - boolean discovered = true; - - if(!this.mc.thePlayer.capabilities.isCreativeMode && WizardData.get(this.mc.thePlayer) != null){ - discovered = WizardData.get(this.mc.thePlayer).hasSpellBeenDiscovered(spell); - } - - if(discovered){ - this.fontRendererObj.drawStringWithShadow(spell.getDisplayNameWithFormatting(), xSize + 16, y, 0); - }else{ - this.mc.standardGalacticFontRenderer.drawStringWithShadow("\u00A79" + SpellGlyphData.getGlyphName(spell, this.mc.theWorld), xSize + 16, y, 0); - } - y += 10; - } - - if(WandHelper.getTotalUpgrades(wand) > 0){ - - this.fontRendererObj.drawStringWithShadow("\u00A7f" + I18n.format("container.wizardry:arcane_workbench.upgrades"), xSize + 6, y + 6, 0); - - int x = 0; - y = 50 + spells.length*10; - // Wand upgrade tooltips - for(Item item : WandHelper.getSpecialUpgrades()){ - - int level = WandHelper.getUpgradeLevel(wand, item); - - if(level > 0){ - // The javadoc for isPointInRegion is ambiguous; what it means is that the REGION is - // relative to the GUI but the POINT isn't. - if(isPointInRegion(xSize + 6 + x, y, 16, 16, mouseX, mouseY)){ - ItemStack stack = new ItemStack(item, level); - this.renderToolTip(stack, mouseX - guiLeft, mouseY - guiTop); - } - x += 18; - } + // Tests whether I have added a background texture and if so actually renders it + if(!slot.getHasStack() && slot instanceof SlotWizardry && ((SlotWizardry)slot).backgroundIndex > -1){ + // Taken directly from GuiContainer#func_146977_a, with a few changes. + this.zLevel = 100.0F; + itemRender.zLevel = 100.0F; + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_BLEND); + this.drawTexturedModalRect(guiLeft + slot.xDisplayPosition, guiTop + slot.yDisplayPosition, ((SlotWizardry)slot).backgroundIndex*16, 240, 16, 16); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); + itemRender.zLevel = 0.0F; + this.zLevel = 0.0F; } } } } - @Override - public void initGui(){ + public void initGui() + { this.mc.thePlayer.openContainer = this.inventorySlots; this.guiLeft = (this.width - this.xSize) / 2; this.guiTop = (this.height - this.ySize) / 2; @@ -210,21 +232,133 @@ public class GuiArcaneWorkbench extends GuiContainer { this.buttonList.add(this.applyBtn = new GuiButtonApply(0, this.width/2 + 48, this.height/2 + 3)); } - @Override - public void onGuiClosed(){ + public void onGuiClosed() + { super.onGuiClosed(); Keyboard.enableRepeatEvents(false); } - @Override - protected void actionPerformed(GuiButton button){ - if(button.enabled){ - if(button.id == 0){ + /** + * Fired when a control is clicked. This is the equivalent of ActionListener.actionPerformed(ActionEvent e). + */ + protected void actionPerformed(GuiButton par1GuiButton) + { + if (par1GuiButton.enabled) + { + if (par1GuiButton.id == 0) + { // Packet building - IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.APPLY_BUTTON); + IMessage msg = new PacketControlInput.Message(0); WizardryPacketHandler.net.sendToServer(msg); } } } + + protected boolean isPointInRegion(int par1, int par2, int par3, int par4, int par5, int par6) + { + int k1 = this.width/2 - xSize/2; + int l1 = this.height/2 - this.ySize/2; + par5 -= k1; + par6 -= l1; + return par5 >= par1 - 1 && par5 < par1 + par3 + 1 && par6 >= par2 - 1 && par6 < par2 + par4 + 1; + } + + protected void drawItemStackTooltip(ItemStack par1ItemStack, int par2, int par3) + { + List list = par1ItemStack.getTooltip(this.mc.thePlayer, this.mc.gameSettings.advancedItemTooltips); + + for (int k = 0; k < list.size(); ++k) + { + if (k == 0) + { + list.set(k, par1ItemStack.getRarity().rarityColor + (String)list.get(k)); + } + else + { + list.set(k, EnumChatFormatting.GRAY + (String)list.get(k)); + } + } + + FontRenderer font = par1ItemStack.getItem().getFontRenderer(par1ItemStack); + drawHoveringText(list, par2, par3, (font == null ? fontRendererObj : font)); + } + + protected void drawHoveringText(List par1List, int par2, int par3, FontRenderer font) + { + if (!par1List.isEmpty()) + { + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + RenderHelper.disableStandardItemLighting(); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_DEPTH_TEST); + int k = 0; + Iterator iterator = par1List.iterator(); + + while (iterator.hasNext()) + { + String s = (String)iterator.next(); + int l = font.getStringWidth(s); + + if (l > k) + { + k = l; + } + } + + int i1 = par2 + 12; + int j1 = par3 - 12; + int k1 = 8; + + if (par1List.size() > 1) + { + k1 += 2 + (par1List.size() - 1) * 10; + } + + if (i1 + k > this.width) + { + i1 -= 28 + k; + } + + if (j1 + k1 + 6 > this.height) + { + j1 = this.height - k1 - 6; + } + + this.zLevel = 300.0F; + itemRender.zLevel = 300.0F; + int l1 = -267386864; + this.drawGradientRect(i1 - 3, j1 - 4, i1 + k + 3, j1 - 3, l1, l1); + this.drawGradientRect(i1 - 3, j1 + k1 + 3, i1 + k + 3, j1 + k1 + 4, l1, l1); + this.drawGradientRect(i1 - 3, j1 - 3, i1 + k + 3, j1 + k1 + 3, l1, l1); + this.drawGradientRect(i1 - 4, j1 - 3, i1 - 3, j1 + k1 + 3, l1, l1); + this.drawGradientRect(i1 + k + 3, j1 - 3, i1 + k + 4, j1 + k1 + 3, l1, l1); + int i2 = 1347420415; + int j2 = (i2 & 16711422) >> 1 | i2 & -16777216; + this.drawGradientRect(i1 - 3, j1 - 3 + 1, i1 - 3 + 1, j1 + k1 + 3 - 1, i2, j2); + this.drawGradientRect(i1 + k + 2, j1 - 3 + 1, i1 + k + 3, j1 + k1 + 3 - 1, i2, j2); + this.drawGradientRect(i1 - 3, j1 - 3, i1 + k + 3, j1 - 3 + 1, i2, i2); + this.drawGradientRect(i1 - 3, j1 + k1 + 2, i1 + k + 3, j1 + k1 + 3, j2, j2); + + for(int k2 = 0; k2 < par1List.size(); ++k2){ + + String s1 = (String)par1List.get(k2); + font.drawStringWithShadow(s1, i1, j1, -1); + + if(k2 == 0){ + j1 += 2; + } + + j1 += 10; + } + + this.zLevel = 0.0F; + itemRender.zLevel = 0.0F; + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_DEPTH_TEST); + RenderHelper.enableStandardItemLighting(); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + } + } + +} -} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/client/GuiButtonApply.java b/src/main/java/electroblob/wizardry/client/GuiButtonApply.java index fd54d344..8b285336 100644 --- a/src/main/java/electroblob/wizardry/client/GuiButtonApply.java +++ b/src/main/java/electroblob/wizardry/client/GuiButtonApply.java @@ -1,32 +1,39 @@ package electroblob.wizardry.client; -import electroblob.wizardry.util.WizardryUtilities; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.resources.I18n; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.StatCollector; + +import org.lwjgl.opengl.GL11; @SideOnly(Side.CLIENT) class GuiButtonApply extends GuiButton { + + private static final ResourceLocation texture = new ResourceLocation("wizardry:textures/gui/handbook.png"); public GuiButtonApply(int id, int x, int y){ - super(id, x, y, 32, 16, I18n.format("container.wizardry:arcane_workbench.apply")); + super(id, x, y, 32, 16, StatCollector.translateToLocal("container.arcaneWorkbench.apply")); } - @Override - public void drawButton(Minecraft minecraft, int mouseX, int mouseY){ - + /** + * Draws this button to the screen. + */ + public void drawButton(Minecraft minecraft, int par2, int par3){ // Whether the button is highlighted - this.hovered = mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width && mouseY < this.yPosition + this.height; - - int k = 36; + this.field_146123_n = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height; + + int k = 100; int l = 220; int colour = 14737632; if(this.enabled){ - if(this.hovered){ + if(this.field_146123_n){ k += this.width*2; colour = 16777120; } @@ -35,7 +42,32 @@ class GuiButtonApply extends GuiButton { colour = 10526880; } - WizardryUtilities.drawTexturedRect(this.xPosition, this.yPosition, k, l, this.width, this.height, 256, 256); - this.drawCenteredString(minecraft.fontRendererObj, this.displayString, this.xPosition + this.width / 2, this.yPosition + (this.height - 8) / 2, colour); + this.drawTexturedRect(this.xPosition, this.yPosition, k, l, this.width, this.height, 256, 256); + this.drawCenteredString(minecraft.fontRenderer, this.displayString, this.xPosition + this.width / 2, this.yPosition + (this.height - 8) / 2, colour); + } -} \ No newline at end of file + + /** + * Draws a textured rectangle, taking the size of the image and the bit needed into account. + * @param x The x position of the rectangle + * @param y The y position of the rectangle + * @param u The x position of the top left corner of the section of the image wanted + * @param v The y position of the top left corner of the section of the image wanted + * @param width The width of the section + * @param height The height of the section + * @param textureWidth The width of the actual image. + * @param textureHeight The height of the actual image. + */ + public void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight) + { + float f = 1F / (float)textureWidth; + float f1 = 1F / (float)textureHeight; + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV((double)(x), (double)(y + height), 0, (double)((float)(u) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y + height), 0, (double)((float)(u + width) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y), 0, (double)((float)(u + width) * f), (double)((float)(v) * f1)); + tessellator.addVertexWithUV((double)(x), (double)(y), 0, (double)((float)(u) * f), (double)((float)(v) * f1)); + tessellator.draw(); + } +} diff --git a/src/main/java/electroblob/wizardry/client/GuiButtonInvisible.java b/src/main/java/electroblob/wizardry/client/GuiButtonInvisible.java index 3cc2f12e..c2b32055 100644 --- a/src/main/java/electroblob/wizardry/client/GuiButtonInvisible.java +++ b/src/main/java/electroblob/wizardry/client/GuiButtonInvisible.java @@ -1,9 +1,13 @@ package electroblob.wizardry.client; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.ResourceLocation; + +import org.lwjgl.opengl.GL11; @SideOnly(Side.CLIENT) class GuiButtonInvisible extends GuiButton { @@ -17,7 +21,7 @@ class GuiButtonInvisible extends GuiButton { * Draws this button to the screen. */ public void drawButton(Minecraft par1Minecraft, int par2, int par3){ - this.hovered = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height; + this.field_146123_n = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height; } } diff --git a/src/main/java/electroblob/wizardry/client/GuiButtonNextPage.java b/src/main/java/electroblob/wizardry/client/GuiButtonNextPage.java new file mode 100644 index 00000000..8960e641 --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/GuiButtonNextPage.java @@ -0,0 +1,78 @@ +package electroblob.wizardry.client; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.ResourceLocation; + +import org.lwjgl.opengl.GL11; + +@SideOnly(Side.CLIENT) +class GuiButtonNextPage extends GuiButton +{ + /** + * True for pointing right (next page), false for pointing left (previous page). + */ + private final boolean nextPage; + + private static final ResourceLocation texture = new ResourceLocation("wizardry:textures/gui/handbook.png"); + + public GuiButtonNextPage(int id, int x, int y, boolean par4) + { + super(id, x, y, 23, 13, ""); + this.nextPage = par4; + } + + /** + * Draws this button to the screen. + */ + public void drawButton(Minecraft par1Minecraft, int par2, int par3) + { + if (this.visible) + { + boolean flag = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height; + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + par1Minecraft.getTextureManager().bindTexture(texture); + int k = 0; + int l = 192; + + if (flag) + { + k += 23; + } + + if (!this.nextPage) + { + l += 13; + } + + this.drawTexturedRect(this.xPosition, this.yPosition, k, l, 23, 13, 288, 256); + } + } + + /** + * Draws a textured rectangle, taking the size of the image and the bit needed into account. + * @param x The x position of the rectangle + * @param y The y position of the rectangle + * @param u The x position of the top left corner of the section of the image wanted + * @param v The y position of the top left corner of the section of the image wanted + * @param width The width of the section + * @param height The height of the section + * @param textureWidth The width of the actual image. + * @param textureHeight The height of the actual image. + */ + public void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight) + { + float f = 1F / (float)textureWidth; + float f1 = 1F / (float)textureHeight; + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV((double)(x), (double)(y + height), 0, (double)((float)(u) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y + height), 0, (double)((float)(u + width) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y), 0, (double)((float)(u + width) * f), (double)((float)(v) * f1)); + tessellator.addVertexWithUV((double)(x), (double)(y), 0, (double)((float)(u) * f), (double)((float)(v) * f1)); + tessellator.draw(); + } +} diff --git a/src/main/java/electroblob/wizardry/client/GuiButtonTurnPage.java b/src/main/java/electroblob/wizardry/client/GuiButtonTurnPage.java deleted file mode 100644 index b4b7e68b..00000000 --- a/src/main/java/electroblob/wizardry/client/GuiButtonTurnPage.java +++ /dev/null @@ -1,52 +0,0 @@ -package electroblob.wizardry.client; - -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiButton; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -class GuiButtonTurnPage extends GuiButton { - - /** True for pointing right (next page), false for pointing left (previous page). */ - private final boolean nextPage; - - private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/gui/handbook.png"); - - public GuiButtonTurnPage(int id, int x, int y, boolean isNextPage) - { - super(id, x, y, 23, 13, ""); - this.nextPage = isNextPage; - } - - /** - * Draws this button to the screen. - */ - public void drawButton(Minecraft par1Minecraft, int par2, int par3) - { - if (this.visible) - { - boolean flag = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height; - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - par1Minecraft.getTextureManager().bindTexture(texture); - int k = 0; - int l = 192; - - if (flag) - { - k += 23; - } - - if (!this.nextPage) - { - l += 13; - } - - WizardryUtilities.drawTexturedRect(this.xPosition, this.yPosition, k, l, 23, 13, 288, 256); - } - } -} diff --git a/src/main/java/electroblob/wizardry/client/GuiConfigWizardry.java b/src/main/java/electroblob/wizardry/client/GuiConfigWizardry.java index 587a8603..dacdadf7 100644 --- a/src/main/java/electroblob/wizardry/client/GuiConfigWizardry.java +++ b/src/main/java/electroblob/wizardry/client/GuiConfigWizardry.java @@ -3,30 +3,30 @@ package electroblob.wizardry.client; import java.util.ArrayList; import java.util.List; -import electroblob.wizardry.Settings; +import cpw.mods.fml.client.config.DummyConfigElement.DummyCategoryElement; +import cpw.mods.fml.client.config.GuiConfig; +import cpw.mods.fml.client.config.GuiConfigEntries; +import cpw.mods.fml.client.config.GuiConfigEntries.CategoryEntry; +import cpw.mods.fml.client.config.IConfigElement; import electroblob.wizardry.Wizardry; import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.resources.I18n; +import net.minecraft.util.StatCollector; import net.minecraftforge.common.config.ConfigElement; import net.minecraftforge.common.config.Configuration; -import net.minecraftforge.fml.client.config.DummyConfigElement.DummyCategoryElement; -import net.minecraftforge.fml.client.config.GuiConfig; -import net.minecraftforge.fml.client.config.GuiConfigEntries; -import net.minecraftforge.fml.client.config.GuiConfigEntries.CategoryEntry; -import net.minecraftforge.fml.client.config.IConfigElement; public class GuiConfigWizardry extends GuiConfig { public GuiConfigWizardry(GuiScreen parent){ - super(parent, getConfigEntries(), Wizardry.MODID, false, false, Wizardry.NAME + " - " + I18n.format("config.wizardry.title.general")); + super(parent, getConfigEntries(), Wizardry.MODID, false, false, Wizardry.NAME + " - " + StatCollector.translateToLocal("config.title.general")); //this.titleLine2 = "File location: " + Wizardry.config.getConfigFile().getAbsolutePath(); } private static List getConfigEntries(){ List configList = new ArrayList(1); - configList.add(new DummyCategoryElement("spellsConfig", "config.wizardry.category." + Settings.SPELLS_CATEGORY, SpellsCategory.class)); - configList.add(new DummyCategoryElement("resistancesConfig", "config.wizardry.category." + Settings.RESISTANCES_CATEGORY, ResistancesCategory.class)); - configList.addAll(new ConfigElement(Wizardry.settings.getConfigCategory(Configuration.CATEGORY_GENERAL)).getChildElements()); + configList.add(new DummyCategoryElement("spellsConfig", "config.category.spells", SpellsCategory.class)); + configList.add(new DummyCategoryElement("resistancesConfig", "config.category.resistances", ResistancesCategory.class)); + configList.add(new DummyCategoryElement("idsConfig", "config.category.ids", IDsCategory.class)); + configList.addAll(new ConfigElement(Wizardry.config.getCategory(Configuration.CATEGORY_GENERAL)).getChildElements()); return configList; } @@ -44,11 +44,11 @@ public class GuiConfigWizardry extends GuiConfig { // This GuiConfig object specifies the configID of the object and as such will force-save when it is closed. // The parent GuiConfig object's entryList will also be refreshed to reflect the changes. GuiConfig spellsMenu = new GuiConfig(this.owningScreen, - (new ConfigElement(Wizardry.settings.getConfigCategory(Settings.SPELLS_CATEGORY))).getChildElements(), - this.owningScreen.modID, Settings.SPELLS_CATEGORY, false, false, - Wizardry.NAME + " - " + I18n.format("config.wizardry.title." + Settings.SPELLS_CATEGORY)); + (new ConfigElement(Wizardry.config.getCategory(Wizardry.SPELLS_CATEGORY))).getChildElements(), + this.owningScreen.modID, Wizardry.SPELLS_CATEGORY, false, false, + Wizardry.NAME + " - " + StatCollector.translateToLocal("config.title.spells")); - spellsMenu.titleLine2 = I18n.format("config.wizardry.subtitle." + Settings.SPELLS_CATEGORY); + spellsMenu.titleLine2 = StatCollector.translateToLocal("config.subtitle.spells"); return spellsMenu; } @@ -68,11 +68,35 @@ public class GuiConfigWizardry extends GuiConfig { // This GuiConfig object specifies the configID of the object and as such will force-save when it is closed. // The parent GuiConfig object's entryList will also be refreshed to reflect the changes. GuiConfig idsMenu = new GuiConfig(this.owningScreen, - (new ConfigElement(Wizardry.settings.getConfigCategory(Settings.RESISTANCES_CATEGORY))).getChildElements(), - this.owningScreen.modID, Settings.RESISTANCES_CATEGORY, false, false, - Wizardry.NAME + " - " + I18n.format("config.wizardry.title." + Settings.RESISTANCES_CATEGORY)); + (new ConfigElement(Wizardry.config.getCategory(Wizardry.RESISTANCES_CATEGORY))).getChildElements(), + this.owningScreen.modID, Wizardry.RESISTANCES_CATEGORY, false, false, + Wizardry.NAME + " - " + StatCollector.translateToLocal("config.title.resistances")); - idsMenu.titleLine2 = I18n.format("config.wizardry.subtitle." + Settings.RESISTANCES_CATEGORY); + idsMenu.titleLine2 = StatCollector.translateToLocal("config.subtitle.resistances"); + + return idsMenu; + } + } + + /** IDs category of the config gui. */ + public static class IDsCategory extends CategoryEntry + { + public IDsCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop) + { + super(owningScreen, owningEntryList, prop); + } + + @Override + protected GuiScreen buildChildScreen() + { + // This GuiConfig object specifies the configID of the object and as such will force-save when it is closed. + // The parent GuiConfig object's entryList will also be refreshed to reflect the changes. + GuiConfig idsMenu = new GuiConfig(this.owningScreen, + (new ConfigElement(Wizardry.config.getCategory(Wizardry.IDS_CATEGORY))).getChildElements(), + this.owningScreen.modID, Wizardry.IDS_CATEGORY, false, false, + Wizardry.NAME + " - " + StatCollector.translateToLocal("config.title.ids")); + + idsMenu.titleLine2 = StatCollector.translateToLocal("config.subtitle.ids"); return idsMenu; } diff --git a/src/main/java/electroblob/wizardry/client/GuiPortableCrafting.java b/src/main/java/electroblob/wizardry/client/GuiPortableCrafting.java index d4f8e225..0ff67b7d 100644 --- a/src/main/java/electroblob/wizardry/client/GuiPortableCrafting.java +++ b/src/main/java/electroblob/wizardry/client/GuiPortableCrafting.java @@ -1,12 +1,13 @@ package electroblob.wizardry.client; +import org.lwjgl.opengl.GL11; + +import electroblob.wizardry.WizardryGuiHandler; import net.minecraft.client.gui.inventory.GuiContainer; -import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.ContainerWorkbench; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; /** Crafting table GUI that doesn't require a crafting table container object. */ @@ -14,9 +15,9 @@ public class GuiPortableCrafting extends GuiContainer { private static final ResourceLocation craftingTableGuiTextures = new ResourceLocation("textures/gui/container/crafting_table.png"); - public GuiPortableCrafting(InventoryPlayer p_i1084_1_, World p_i1084_2_, BlockPos pos) + public GuiPortableCrafting(InventoryPlayer p_i1084_1_, World p_i1084_2_, int p_i1084_3_, int p_i1084_4_, int p_i1084_5_) { - super(new ContainerWorkbench(p_i1084_1_, p_i1084_2_, pos)); + super(new ContainerWorkbench(p_i1084_1_, p_i1084_2_, p_i1084_3_, p_i1084_4_, p_i1084_5_)); } /** @@ -30,7 +31,7 @@ public class GuiPortableCrafting extends GuiContainer { protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) { - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); this.mc.getTextureManager().bindTexture(craftingTableGuiTextures); int k = (this.width - this.xSize) / 2; int l = (this.height - this.ySize) / 2; diff --git a/src/main/java/electroblob/wizardry/client/GuiSpellBook.java b/src/main/java/electroblob/wizardry/client/GuiSpellBook.java index c7a90cb2..ea5370f7 100644 --- a/src/main/java/electroblob/wizardry/client/GuiSpellBook.java +++ b/src/main/java/electroblob/wizardry/client/GuiSpellBook.java @@ -2,16 +2,18 @@ package electroblob.wizardry.client; import org.lwjgl.input.Keyboard; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.SpellGlyphData; -import electroblob.wizardry.WizardData; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.Spells; +import electroblob.wizardry.WizardryGuiHandler; +import electroblob.wizardry.WizardryRegistry; import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; public class GuiSpellBook extends GuiScreen { @@ -39,17 +41,17 @@ public class GuiSpellBook extends GuiScreen { EntityPlayer player = Minecraft.getMinecraft().thePlayer; boolean discovered = true; - if(Wizardry.settings.discoveryMode && !player.capabilities.isCreativeMode && WizardData.get(player) != null - && !WizardData.get(player).hasSpellBeenDiscovered(spell)){ + if(Wizardry.discoveryMode && !player.capabilities.isCreativeMode && ExtendedPlayer.get(player) != null + && !ExtendedPlayer.get(player).hasSpellBeenDiscovered(spell)){ discovered = false; } // Draws spell illustration on opposite page, underneath the book so it shows through the hole. - Minecraft.getMinecraft().renderEngine.bindTexture(discovered ? spell.getIcon() : Spells.none.getIcon()); - WizardryUtilities.drawTexturedRect(xPos + 145, yPos + 20, 0, 0, 128, 128, 128, 128); + Minecraft.getMinecraft().renderEngine.bindTexture(discovered ? spell.icon : WizardryRegistry.none.icon); + this.drawTexturedRect(xPos + 145, yPos + 20, 0, 0, 128, 128, 128, 128); Minecraft.getMinecraft().renderEngine.bindTexture(texture); - WizardryUtilities.drawTexturedRect(xPos, yPos, 0, 0, xSize, ySize, xSize, 256); + this.drawTexturedRect(xPos, yPos, 0, 0, xSize, ySize, xSize, 256); super.drawScreen(par1, par2, par3); @@ -63,14 +65,14 @@ public class GuiSpellBook extends GuiScreen { this.fontRendererObj.drawString("-------------------", xPos+17, yPos+34, 0); - if(spell.tier == Tier.BASIC){ + if(spell.tier == EnumTier.BASIC){ // Basic is usually white but this doesn't show up. - this.fontRendererObj.drawString("Tier: \u00A77" + Tier.BASIC.getDisplayName(), xPos+17, yPos+44, 0); + this.fontRendererObj.drawString("Tier: \u00A77" + EnumTier.BASIC.getDisplayName(), xPos+17, yPos+44, 0); }else{ this.fontRendererObj.drawString("Tier: " + spell.tier.getDisplayNameWithFormatting(), xPos+17, yPos+44, 0); } - String element = "Element: " + spell.element.getFormattingCode() + spell.element.getDisplayName(); + String element = "Element: " + spell.element.colour + spell.element.getDisplayName(); if(!discovered) element = "Element: ?"; this.fontRendererObj.drawString(element, xPos+17, yPos+56, 0); @@ -123,5 +125,29 @@ public class GuiSpellBook extends GuiScreen { super.onGuiClosed(); Keyboard.enableRepeatEvents(false); } + + /** + * Draws a textured rectangle, taking the size of the image and the bit needed into account. Client side only, of course. + * @param x The x position of the rectangle + * @param y The y position of the rectangle + * @param u The x position of the top left corner of the section of the image wanted + * @param v The y position of the top left corner of the section of the image wanted + * @param width The width of the section + * @param height The height of the section + * @param textureWidth The width of the actual image. + * @param textureHeight The height of the actual image. + */ + public static void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight) + { + float f = 1F / (float)textureWidth; + float f1 = 1F / (float)textureHeight; + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV((double)(x), (double)(y + height), 0, (double)((float)(u) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y + height), 0, (double)((float)(u + width) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y), 0, (double)((float)(u + width) * f), (double)((float)(v) * f1)); + tessellator.addVertexWithUV((double)(x), (double)(y), 0, (double)((float)(u) * f), (double)((float)(v) * f1)); + tessellator.draw(); + } } diff --git a/src/main/java/electroblob/wizardry/client/GuiSpellDisplay.java b/src/main/java/electroblob/wizardry/client/GuiSpellDisplay.java index dc27a3eb..366e1712 100644 --- a/src/main/java/electroblob/wizardry/client/GuiSpellDisplay.java +++ b/src/main/java/electroblob/wizardry/client/GuiSpellDisplay.java @@ -2,29 +2,26 @@ package electroblob.wizardry.client; import java.util.List; -import electroblob.wizardry.Settings.GuiPosition; +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.SpellGlyphData; -import electroblob.wizardry.WizardData; +import electroblob.wizardry.WandHelper; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Constants; +import electroblob.wizardry.WizardryRegistry; import electroblob.wizardry.item.ItemWand; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; +import electroblob.wizardry.spell.None; import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.WandHelper; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.GlStateManager.DestFactor; -import net.minecraft.client.renderer.GlStateManager.SourceFactor; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagIntArray; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.RenderGameOverlayEvent; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; public class GuiSpellDisplay extends Gui { @@ -42,114 +39,131 @@ public class GuiSpellDisplay extends Gui { EntityPlayer player = this.mc.thePlayer; - // If the player has a wand in each hand, only displays for the one in the main hand. + if(player.getHeldItem() != null && player.getHeldItem().getItem() instanceof ItemWand){ - ItemStack wand = player.getHeldItemMainhand(); + int width = event.resolution.getScaledWidth(); + int height = event.resolution.getScaledHeight(); - if(wand == null || !(wand.getItem() instanceof ItemWand)){ - wand = player.getHeldItemOffhand(); - // If the player isn't holding a wand, then nothing else needs to be done. - if(wand == null || !(wand.getItem() instanceof ItemWand)) return; - } + Spell spell = WandHelper.getCurrentSpell(player.getHeldItem()); + int cooldown = WandHelper.getCurrentCooldown(player.getHeldItem()); - int width = event.getResolution().getScaledWidth(); - int height = event.getResolution().getScaledHeight(); + float cooldownMultiplier = 1.0f - WandHelper.getUpgradeLevel(player.getHeldItem(), Wizardry.cooldownUpgrade)*Wizardry.COOLDOWN_REDUCTION_PER_LEVEL; - Spell spell = WandHelper.getCurrentSpell(wand); - int cooldown = WandHelper.getCurrentCooldown(wand); + if(player.isPotionActive(Wizardry.fontOfMana)){ + // Dividing by this rather than setting it takes upgrades and font of mana into account simultaneously + cooldownMultiplier /= 2 + player.getActivePotionEffect(Wizardry.fontOfMana).getAmplifier(); + } - float cooldownMultiplier = 1.0f - WandHelper.getUpgradeLevel(wand, WizardryItems.cooldown_upgrade)*Constants.COOLDOWN_REDUCTION_PER_LEVEL; + // Coordinates of the top left corner of the HUD. + int left = 0; + int top = 0; + boolean mirror = false; - if(player.isPotionActive(WizardryPotions.font_of_mana)){ - // Dividing by this rather than setting it takes upgrades and font of mana into account simultaneously - cooldownMultiplier /= 2 + player.getActivePotionEffect(WizardryPotions.font_of_mana).getAmplifier(); - } + if(Wizardry.spellHUDPosition.equals("Bottom left")){ + left = 0; + top = height-36; + }else if(Wizardry.spellHUDPosition.equals("Top left")){ + left = 0; + top = 0; + }else if(Wizardry.spellHUDPosition.equals("Top right")){ + left = width-128; + top = 0; + mirror = true; + }else if(Wizardry.spellHUDPosition.equals("Bottom right")){ + left = width-128; + top = height-36; + mirror = true; + } - // Coordinates of the top left corner of the HUD. - int left = 0; - int top = 0; - boolean mirror = false; + boolean discovered = true; - if(Wizardry.settings.spellHUDPosition == GuiPosition.BOTTOM_LEFT){ - left = 0; - top = height-36; - }else if(Wizardry.settings.spellHUDPosition == GuiPosition.TOP_LEFT){ - left = 0; - top = 0; - }else if(Wizardry.settings.spellHUDPosition == GuiPosition.TOP_RIGHT){ - left = width-128; - top = 0; - mirror = true; - }else if(Wizardry.settings.spellHUDPosition == GuiPosition.BOTTOM_RIGHT){ - left = width-128; - top = height-36; - mirror = true; - } + if(!player.capabilities.isCreativeMode && ExtendedPlayer.get(player) != null){ + discovered = ExtendedPlayer.get(player).hasSpellBeenDiscovered(spell); + } - boolean discovered = true; + if(event.type == RenderGameOverlayEvent.ElementType.TEXT){ - if(!player.capabilities.isCreativeMode && WizardData.get(player) != null){ - discovered = WizardData.get(player).hasSpellBeenDiscovered(spell); - } + // Makes spells greyed out if they are in cooldown or if the player has the arcane jammer effect + String colour = cooldown > 0 || player.isPotionActive(Wizardry.arcaneJammer) ? "\u00A78" : spell.element.colour; + if(!discovered) colour = "\u00A79"; + String spellName = discovered ? spell.getDisplayName() : SpellGlyphData.getGlyphName(spell, player.worldObj); + FontRenderer font = discovered ? this.mc.fontRenderer : this.mc.standardGalacticFontRenderer; - if(event.getType() == RenderGameOverlayEvent.ElementType.TEXT){ + int maxWidth = 90; - // Makes spells greyed out if they are in cooldown or if the player has the arcane jammer effect - String colour = cooldown > 0 || player.isPotionActive(WizardryPotions.arcane_jammer) ? "\u00A78" : spell.element.getFormattingCode(); - if(!discovered) colour = "\u00A79"; - String spellName = discovered ? spell.getDisplayName() : SpellGlyphData.getGlyphName(spell, player.worldObj); - FontRenderer font = discovered ? this.mc.fontRendererObj : this.mc.standardGalacticFontRenderer; + if(font.getStringWidth(spellName) <= maxWidth){ + // Single line is rendered more centrally + font.drawStringWithShadow(colour + spellName, mirror ? left+5 : left+41, top+13, 0xffffffff); - int maxWidth = 90; + }else{ - if(font.getStringWidth(spellName) <= maxWidth){ - // Single line is rendered more centrally - font.drawStringWithShadow(colour + spellName, mirror ? left+5 : left+41, top+13, 0xffffffff); + int lineNumber = 0; - }else{ + List lines = font.listFormattedStringToWidth(spellName, maxWidth); - int lineNumber = 0; - - List lines = font.listFormattedStringToWidth(spellName, maxWidth); - - for(Object line : lines){ - if(line instanceof String){ - font.drawStringWithShadow(colour + (String)line, mirror ? left+5 : left+41, top+6 + 11*lineNumber, 0xffffffff); + for(Object line : lines){ + if(line instanceof String){ + font.drawStringWithShadow(colour + (String)line, mirror ? left+5 : left+41, top+6 + 11*lineNumber, 0xffffffff); + } + lineNumber++; } - lineNumber++; } + + }else if(event.type == RenderGameOverlayEvent.ElementType.HOTBAR){ + + GL11.glPushMatrix(); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + GL11.glColor3f(1.0f, 1.0f, 1.0f); + this.mc.renderEngine.bindTexture(hudTexture); + + // Background of spell hud + this.drawTexturedModalRect(left, top, 0, mirror ? 36 : 0, 128, 36); + + // Cooldown bar + if(cooldown > 0){ + this.drawTexturedModalRect(mirror ? left+5 : left+41, height-8, 128, 6, 82, 6); + + int l = (int)(((double)(spell.cooldown * cooldownMultiplier - cooldown) + / (double)(spell.cooldown * cooldownMultiplier)) * 82); + + this.drawTexturedModalRect(mirror ? left+5 : left+41, height-8, 128, 0, l, 6); + } + + // Spell illustration + this.mc.renderEngine.bindTexture(discovered ? spell.icon : WizardryRegistry.none.icon); + + this.drawTexturedRect(mirror ? left+94 : left+2, top+2, 0, 0, 32, 32, 32, 32); + + GL11.glDisable(GL11.GL_BLEND); + GL11.glPopMatrix(); } - - }else if(event.getType() == RenderGameOverlayEvent.ElementType.HOTBAR){ - - GlStateManager.pushAttrib(); - - GlStateManager.enableBlend(); - GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA); - GlStateManager.color(1, 1, 1); - - this.mc.renderEngine.bindTexture(hudTexture); - - // Background of spell hud - this.drawTexturedModalRect(left, top, 0, mirror ? 36 : 0, 128, 36); - - // Cooldown bar - if(cooldown > 0){ - this.drawTexturedModalRect(mirror ? left+5 : left+41, height-8, 128, 6, 82, 6); - - int l = (int)(((double)(spell.cooldown * cooldownMultiplier - cooldown) - / (double)(spell.cooldown * cooldownMultiplier)) * 82); - - this.drawTexturedModalRect(mirror ? left+5 : left+41, height-8, 128, 0, l, 6); - } - - // Spell illustration - this.mc.renderEngine.bindTexture(discovered ? spell.getIcon() : Spells.none.getIcon()); - - WizardryUtilities.drawTexturedRect(mirror ? left+94 : left+2, top+2, 0, 0, 32, 32, 32, 32); - - GlStateManager.popAttrib(); } } + /** + * Draws a textured rectangle, taking the size of the image and the bit needed into account. Client side only, of course. + * @param x The x position of the rectangle + * @param y The y position of the rectangle + * @param u The x position of the top left corner of the section of the image wanted + * @param v The y position of the top left corner of the section of the image wanted + * @param width The width of the section + * @param height The height of the section + * @param textureWidth The width of the actual image. + * @param textureHeight The height of the actual image. + */ + public static void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight) + { + float f = 1F / (float)textureWidth; + float f1 = 1F / (float)textureHeight; + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV((double)(x), (double)(y + height), 0, (double)((float)(u) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y + height), 0, (double)((float)(u + width) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y), 0, (double)((float)(u + width) * f), (double)((float)(v) * f1)); + tessellator.addVertexWithUV((double)(x), (double)(y), 0, (double)((float)(u) * f), (double)((float)(v) * f1)); + tessellator.draw(); + } + } diff --git a/src/main/java/electroblob/wizardry/client/GuiWizardHandbook.java b/src/main/java/electroblob/wizardry/client/GuiWizardHandbook.java index 5cb8ee9e..522134f2 100644 --- a/src/main/java/electroblob/wizardry/client/GuiWizardHandbook.java +++ b/src/main/java/electroblob/wizardry/client/GuiWizardHandbook.java @@ -4,42 +4,40 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import org.apache.commons.io.Charsets; import org.lwjgl.input.Keyboard; import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Constants; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryBlocks; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryGuiHandler; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.VertexBuffer; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.client.resources.LanguageManager; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; +import net.minecraft.util.StatCollector; public class GuiWizardHandbook extends GuiScreen { + private GuiButtonNextPage nextPageBtn, prevPageBtn; private int xSize, ySize; private int pageNumber = 0; - private static final int PAGE_WIDTH = 120; - /** The integer colour for black passed into the font renderer methods. This used to be 0 but that's now white - * for some reason, so I've made a it a constant in case it changes again. */ - // I think this is actually ever-so-slightly lighter than pure black, but the difference is unnoticeable. - private static final int BLACK = 1; + private static final int pageWidth = 120; public static final ResourceLocation regularHandbook = new ResourceLocation(Wizardry.MODID, "textures/gui/handbook.png"); public static final ResourceLocation ore = new ResourceLocation(Wizardry.MODID, "textures/gui/ore_picture.png"); @@ -58,7 +56,9 @@ public class GuiWizardHandbook extends GuiScreen { ySize = 180; } - @Override + /** + * Draws the screen and all the components in it. + */ public void drawScreen(int mouseX, int mouseY, float par3){ int xPos = this.width/2 - xSize/2; @@ -71,7 +71,7 @@ public class GuiWizardHandbook extends GuiScreen { Minecraft.getMinecraft().renderEngine.bindTexture(regularHandbook); } - WizardryUtilities.drawTexturedRect(xPos, yPos, 0, 0, xSize, ySize, xSize, 256); + drawTexturedRect(xPos, yPos, 0, 0, xSize, ySize, xSize, 256); // Arcane workbench gui picture if(pageNumber == (this.guiPage-1)/2){ @@ -83,13 +83,13 @@ public class GuiWizardHandbook extends GuiScreen { if(pageNumber == (this.imagePage-1)/2){ Minecraft.getMinecraft().renderEngine.bindTexture(ore); - WizardryUtilities.drawTexturedRect(this.imagePage % 2 == 1 ? xPos + 17 : this.width/2 + 7, yPos + 80, 0, 0, 64, 64, 64, 64); + drawTexturedRect(this.imagePage % 2 == 1 ? xPos + 17 : this.width/2 + 7, yPos + 80, 0, 0, 64, 64, 64, 64); Minecraft.getMinecraft().renderEngine.bindTexture(crystal); drawTexturedStretchedRect(this.imagePage % 2 == 1 ? xPos + 17 + 64 : this.width/2 + 7 + 62, yPos + 80, 0, 0, 64, 64, 1, 1); } - + this.fontRendererObj.drawString("" + (pageNumber*2 + 1), xPos + xSize/4 - 3, yPos + ySize - 20, 0); this.fontRendererObj.drawString("" + (pageNumber*2 + 2), xPos + 3*xSize/4 - 5, yPos + ySize - 20, 0); @@ -98,8 +98,10 @@ public class GuiWizardHandbook extends GuiScreen { int lineNumber = 0; if(pageNumber == 1){ + int row = 2; for(Section s : sections){ s.drawContents(); + row++; } }else{ for(Section s : sections){ @@ -109,9 +111,9 @@ public class GuiWizardHandbook extends GuiScreen { for(String paragraph : text.get(pageNumber*2)){ - this.fontRendererObj.drawSplitString(paragraph, xPos + 17, yPos + 14 + lineNumber*this.fontRendererObj.FONT_HEIGHT, PAGE_WIDTH, BLACK); + this.fontRendererObj.drawSplitString(paragraph, xPos + 17, yPos + 14 + lineNumber*this.fontRendererObj.FONT_HEIGHT, pageWidth, 0); - List list = new ArrayList(this.fontRendererObj.listFormattedStringToWidth(paragraph, GuiWizardHandbook.PAGE_WIDTH)); + ArrayList list = new ArrayList(this.fontRendererObj.listFormattedStringToWidth(paragraph, this.pageWidth)); lineNumber += list.size(); } @@ -124,18 +126,26 @@ public class GuiWizardHandbook extends GuiScreen { // First page is centred if(pageNumber == 0){ - int startX = this.width/2 + 7 + PAGE_WIDTH/2 - this.fontRendererObj.getStringWidth(paragraph)/2; - this.fontRendererObj.drawSplitString(paragraph, startX, yPos + 14 + lineNumber*this.fontRendererObj.FONT_HEIGHT, PAGE_WIDTH, BLACK); + int startX = this.width/2 + 7 + pageWidth/2 - this.fontRendererObj.getStringWidth(paragraph)/2; + this.fontRendererObj.drawSplitString(paragraph, startX, yPos + 14 + lineNumber*this.fontRendererObj.FONT_HEIGHT, pageWidth, 0); }else{ - this.fontRendererObj.drawSplitString(paragraph, this.width/2 + 7, yPos + 14 + lineNumber*this.fontRendererObj.FONT_HEIGHT, PAGE_WIDTH, BLACK); + this.fontRendererObj.drawSplitString(paragraph, this.width/2 + 7, yPos + 14 + lineNumber*this.fontRendererObj.FONT_HEIGHT, pageWidth, 0); } - List list = new ArrayList(this.fontRendererObj.listFormattedStringToWidth(paragraph, GuiWizardHandbook.PAGE_WIDTH)); + ArrayList list = new ArrayList(this.fontRendererObj.listFormattedStringToWidth(paragraph, this.pageWidth)); lineNumber += list.size(); } } + /* + for(int i=0;i<(Math.min(text[pageNumber].length, 14));i++){ + this.fontRendererObj.drawString(text[pageNumber][i], xPos + 16, yPos + 14 + i*10, 0); + } + for(int i=0;i<(Math.min(text[pageNumber].length - 14, 14));i++){ + this.fontRendererObj.drawString(text[pageNumber][i+14], this.width/2 + 5, yPos + 14 + i*10, 0); + } + */ ItemStack[][] craftingGrid; ItemStack craftingResult; @@ -143,164 +153,164 @@ public class GuiWizardHandbook extends GuiScreen { if(pageNumber == (sections.get(sections.size()-1).pageNumber-1)/2){ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(Items.GOLD_NUGGET); - craftingGrid[1][0] = new ItemStack(Blocks.CARPET, 1, 10); - craftingGrid[2][0] = new ItemStack(Items.GOLD_NUGGET); - craftingGrid[0][1] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][1] = new ItemStack(Blocks.LAPIS_BLOCK); - craftingGrid[2][1] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[0][2] = new ItemStack(Blocks.STONE); - craftingGrid[1][2] = new ItemStack(Blocks.STONE); - craftingGrid[2][2] = new ItemStack(Blocks.STONE); - craftingResult = new ItemStack(WizardryBlocks.arcane_workbench); + craftingGrid[0][0] = new ItemStack(Items.gold_nugget); + craftingGrid[1][0] = new ItemStack(Blocks.carpet, 1, 10); + craftingGrid[2][0] = new ItemStack(Items.gold_nugget); + craftingGrid[0][1] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][1] = new ItemStack(Blocks.lapis_block); + craftingGrid[2][1] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[0][2] = new ItemStack(Blocks.stone); + craftingGrid[1][2] = new ItemStack(Blocks.stone); + craftingGrid[2][2] = new ItemStack(Blocks.stone); + craftingResult = new ItemStack(Wizardry.arcaneWorkbench); this.renderCraftingRecipe(xPos + 23, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[2][0] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][1] = new ItemStack(Items.STICK); - craftingGrid[0][2] = new ItemStack(Items.GOLD_NUGGET); - craftingResult = new ItemStack(WizardryItems.magic_wand); + craftingGrid[2][0] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][1] = new ItemStack(Items.stick); + craftingGrid[0][2] = new ItemStack(Items.gold_nugget); + craftingResult = new ItemStack(Wizardry.magicWand); this.renderCraftingRecipe(xPos + 23, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[1][0] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[0][1] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][1] = new ItemStack(Items.BOOK); - craftingGrid[1][2] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[2][1] = new ItemStack(WizardryItems.magic_crystal); - craftingResult = new ItemStack(WizardryItems.spell_book, 1, 1); + craftingGrid[1][0] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[0][1] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][1] = new ItemStack(Items.book); + craftingGrid[1][2] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[2][1] = new ItemStack(Wizardry.magicCrystal); + craftingResult = new ItemStack(Wizardry.spellBook, 1, 1); this.renderCraftingRecipe(xPos + 156, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(Items.BOOK); - craftingGrid[1][0] = new ItemStack(WizardryItems.magic_crystal); - craftingResult = new ItemStack(WizardryItems.wizard_handbook); + craftingGrid[0][0] = new ItemStack(Items.book); + craftingGrid[1][0] = new ItemStack(Wizardry.magicCrystal); + craftingResult = new ItemStack(Wizardry.wizardHandbook); this.renderCraftingRecipe(xPos + 156, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); }else if(pageNumber == (sections.get(sections.size()-1).pageNumber-1)/2 + 1){ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(WizardryBlocks.crystal_flower); - craftingResult = new ItemStack(WizardryItems.magic_crystal, 2); + craftingGrid[0][0] = new ItemStack(Wizardry.crystalFlower); + craftingResult = new ItemStack(Wizardry.magicCrystal, 2); this.renderCraftingRecipe(xPos + 23, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][0] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[2][0] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[0][1] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][1] = new ItemStack(Items.GLASS_BOTTLE); - craftingGrid[2][1] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[0][2] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][2] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[2][2] = new ItemStack(WizardryItems.magic_crystal); - craftingResult = new ItemStack(WizardryItems.mana_flask); + craftingGrid[0][0] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][0] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[2][0] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[0][1] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][1] = new ItemStack(Items.glass_bottle); + craftingGrid[2][1] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[0][2] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][2] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[2][2] = new ItemStack(Wizardry.magicCrystal); + craftingResult = new ItemStack(Wizardry.manaFlask); this.renderCraftingRecipe(xPos + 23, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[1][0] = new ItemStack(Blocks.STONE); - craftingGrid[0][1] = new ItemStack(Blocks.STONE); - craftingGrid[1][1] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][2] = new ItemStack(Blocks.STONE); - craftingGrid[2][1] = new ItemStack(Blocks.STONE); - craftingResult = new ItemStack(WizardryBlocks.transportation_stone, 2); + craftingGrid[1][0] = new ItemStack(Blocks.stone); + craftingGrid[0][1] = new ItemStack(Blocks.stone); + craftingGrid[1][1] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][2] = new ItemStack(Blocks.stone); + craftingGrid[2][1] = new ItemStack(Blocks.stone); + craftingResult = new ItemStack(Wizardry.transportationStone, 2); this.renderCraftingRecipe(xPos + 156, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[1][0] = new ItemStack(Items.STRING); - craftingGrid[0][1] = new ItemStack(Items.STRING); - craftingGrid[1][1] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][2] = new ItemStack(Items.STRING); - craftingGrid[2][1] = new ItemStack(Items.STRING); - craftingResult = new ItemStack(WizardryItems.magic_silk, 2); + craftingGrid[1][0] = new ItemStack(Items.string); + craftingGrid[0][1] = new ItemStack(Items.string); + craftingGrid[1][1] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][2] = new ItemStack(Items.string); + craftingGrid[2][1] = new ItemStack(Items.string); + craftingResult = new ItemStack(Wizardry.magicSilk, 2); this.renderCraftingRecipe(xPos + 156, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); }else if(pageNumber == (sections.get(sections.size()-1).pageNumber-1)/2 + 2){ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[1][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[0][1] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][1] = new ItemStack(WizardryItems.magic_silk); - craftingResult = new ItemStack(WizardryItems.wizard_hat); + craftingGrid[0][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[1][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[0][1] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][1] = new ItemStack(Wizardry.magicSilk); + craftingResult = new ItemStack(Wizardry.wizardHat); this.renderCraftingRecipe(xPos + 23, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[0][1] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[1][1] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][1] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[0][2] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[1][2] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][2] = new ItemStack(WizardryItems.magic_silk); - craftingResult = new ItemStack(WizardryItems.wizard_robe); + craftingGrid[0][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[0][1] = new ItemStack(Wizardry.magicSilk); + craftingGrid[1][1] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][1] = new ItemStack(Wizardry.magicSilk); + craftingGrid[0][2] = new ItemStack(Wizardry.magicSilk); + craftingGrid[1][2] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][2] = new ItemStack(Wizardry.magicSilk); + craftingResult = new ItemStack(Wizardry.wizardRobe); this.renderCraftingRecipe(xPos + 23, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[1][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[0][1] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][1] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[0][2] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][2] = new ItemStack(WizardryItems.magic_silk); - craftingResult = new ItemStack(WizardryItems.wizard_leggings); + craftingGrid[0][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[1][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[0][1] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][1] = new ItemStack(Wizardry.magicSilk); + craftingGrid[0][2] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][2] = new ItemStack(Wizardry.magicSilk); + craftingResult = new ItemStack(Wizardry.wizardLeggings); this.renderCraftingRecipe(xPos + 156, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[0][1] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][1] = new ItemStack(WizardryItems.magic_silk); - craftingResult = new ItemStack(WizardryItems.wizard_boots); + craftingGrid[0][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[0][1] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][1] = new ItemStack(Wizardry.magicSilk); + craftingResult = new ItemStack(Wizardry.wizardBoots); this.renderCraftingRecipe(xPos + 156, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); }else if(pageNumber == (sections.get(sections.size()-1).pageNumber-1)/2 + 3){ - if(Wizardry.settings.useAlternateScrollRecipe){ + if(Wizardry.useAlternateScrollRecipe){ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(Items.PAPER); - craftingGrid[1][0] = new ItemStack(Items.STRING); - craftingGrid[2][0] = new ItemStack(WizardryItems.magic_crystal); - craftingResult = new ItemStack(WizardryItems.blank_scroll); + craftingGrid[0][0] = new ItemStack(Items.paper); + craftingGrid[1][0] = new ItemStack(Items.string); + craftingGrid[2][0] = new ItemStack(Wizardry.magicCrystal); + craftingResult = new ItemStack(Wizardry.blankScroll); this.renderCraftingRecipe(xPos + 23, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); }else{ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(Items.PAPER); - craftingGrid[1][0] = new ItemStack(Items.STRING); - craftingResult = new ItemStack(WizardryItems.blank_scroll); + craftingGrid[0][0] = new ItemStack(Items.paper); + craftingGrid[1][0] = new ItemStack(Items.string); + craftingResult = new ItemStack(Wizardry.blankScroll); this.renderCraftingRecipe(xPos + 23, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); } - if(Wizardry.settings.firebombIsCraftable){ + if(Wizardry.firebombIsCraftable){ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(Items.BLAZE_POWDER); - craftingGrid[1][0] = new ItemStack(Items.BLAZE_POWDER); - craftingGrid[0][1] = new ItemStack(Items.GLASS_BOTTLE); - craftingGrid[1][1] = new ItemStack(Items.GUNPOWDER); - craftingResult = new ItemStack(WizardryItems.firebomb, 3); + craftingGrid[0][0] = new ItemStack(Items.blaze_powder); + craftingGrid[1][0] = new ItemStack(Items.blaze_powder); + craftingGrid[0][1] = new ItemStack(Items.glass_bottle); + craftingGrid[1][1] = new ItemStack(Items.gunpowder); + craftingResult = new ItemStack(Wizardry.firebomb, 3); this.renderCraftingRecipe(xPos + 23, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); } - if(Wizardry.settings.poisonBombIsCraftable){ + if(Wizardry.poisonBombIsCraftable){ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(Items.SPIDER_EYE); - craftingGrid[1][0] = new ItemStack(Items.SPIDER_EYE); - craftingGrid[0][1] = new ItemStack(Items.GLASS_BOTTLE); - craftingGrid[1][1] = new ItemStack(Items.GUNPOWDER); - craftingResult = new ItemStack(WizardryItems.poison_bomb, 3); + craftingGrid[0][0] = new ItemStack(Items.spider_eye); + craftingGrid[1][0] = new ItemStack(Items.spider_eye); + craftingGrid[0][1] = new ItemStack(Items.glass_bottle); + craftingGrid[1][1] = new ItemStack(Items.gunpowder); + craftingResult = new ItemStack(Wizardry.poisonBomb, 3); this.renderCraftingRecipe(xPos + 156, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); } - if(Wizardry.settings.smokeBombIsCraftable){ + if(Wizardry.smokeBombIsCraftable){ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(Items.COAL); - craftingGrid[1][0] = new ItemStack(Items.COAL); - craftingGrid[0][1] = new ItemStack(Items.GLASS_BOTTLE); - craftingGrid[1][1] = new ItemStack(Items.GUNPOWDER); - craftingResult = new ItemStack(WizardryItems.smoke_bomb, 3); + craftingGrid[0][0] = new ItemStack(Items.coal); + craftingGrid[1][0] = new ItemStack(Items.coal); + craftingGrid[0][1] = new ItemStack(Items.glass_bottle); + craftingGrid[1][1] = new ItemStack(Items.gunpowder); + craftingResult = new ItemStack(Wizardry.smokeBomb, 3); this.renderCraftingRecipe(xPos + 156, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); } @@ -309,164 +319,164 @@ public class GuiWizardHandbook extends GuiScreen { if(pageNumber == (sections.get(sections.size()-1).pageNumber-1)/2){ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(Items.GOLD_NUGGET); - craftingGrid[1][0] = new ItemStack(Blocks.CARPET, 1, 10); - craftingGrid[2][0] = new ItemStack(Items.GOLD_NUGGET); - craftingGrid[0][1] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][1] = new ItemStack(Blocks.LAPIS_BLOCK); - craftingGrid[2][1] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[0][2] = new ItemStack(Blocks.STONE); - craftingGrid[1][2] = new ItemStack(Blocks.STONE); - craftingGrid[2][2] = new ItemStack(Blocks.STONE); - craftingResult = new ItemStack(WizardryBlocks.arcane_workbench); + craftingGrid[0][0] = new ItemStack(Items.gold_nugget); + craftingGrid[1][0] = new ItemStack(Blocks.carpet, 1, 10); + craftingGrid[2][0] = new ItemStack(Items.gold_nugget); + craftingGrid[0][1] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][1] = new ItemStack(Blocks.lapis_block); + craftingGrid[2][1] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[0][2] = new ItemStack(Blocks.stone); + craftingGrid[1][2] = new ItemStack(Blocks.stone); + craftingGrid[2][2] = new ItemStack(Blocks.stone); + craftingResult = new ItemStack(Wizardry.arcaneWorkbench); this.renderCraftingTooltips(xPos + 23, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[2][0] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][1] = new ItemStack(Items.STICK); - craftingGrid[0][2] = new ItemStack(Items.GOLD_NUGGET); - craftingResult = new ItemStack(WizardryItems.magic_wand); + craftingGrid[2][0] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][1] = new ItemStack(Items.stick); + craftingGrid[0][2] = new ItemStack(Items.gold_nugget); + craftingResult = new ItemStack(Wizardry.magicWand); this.renderCraftingTooltips(xPos + 23, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[1][0] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[0][1] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][1] = new ItemStack(Items.BOOK); - craftingGrid[1][2] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[2][1] = new ItemStack(WizardryItems.magic_crystal); - craftingResult = new ItemStack(WizardryItems.spell_book, 1, 1); + craftingGrid[1][0] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[0][1] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][1] = new ItemStack(Items.book); + craftingGrid[1][2] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[2][1] = new ItemStack(Wizardry.magicCrystal); + craftingResult = new ItemStack(Wizardry.spellBook, 1, 1); this.renderCraftingTooltips(xPos + 156, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(Items.BOOK); - craftingGrid[1][0] = new ItemStack(WizardryItems.magic_crystal); - craftingResult = new ItemStack(WizardryItems.wizard_handbook); + craftingGrid[0][0] = new ItemStack(Items.book); + craftingGrid[1][0] = new ItemStack(Wizardry.magicCrystal); + craftingResult = new ItemStack(Wizardry.wizardHandbook); this.renderCraftingTooltips(xPos + 156, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); }else if(pageNumber == (sections.get(sections.size()-1).pageNumber-1)/2 + 1){ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(WizardryBlocks.crystal_flower); - craftingResult = new ItemStack(WizardryItems.magic_crystal, 2); + craftingGrid[0][0] = new ItemStack(Wizardry.crystalFlower); + craftingResult = new ItemStack(Wizardry.magicCrystal, 2); this.renderCraftingTooltips(xPos + 23, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][0] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[2][0] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[0][1] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][1] = new ItemStack(Items.GLASS_BOTTLE); - craftingGrid[2][1] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[0][2] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][2] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[2][2] = new ItemStack(WizardryItems.magic_crystal); - craftingResult = new ItemStack(WizardryItems.mana_flask); + craftingGrid[0][0] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][0] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[2][0] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[0][1] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][1] = new ItemStack(Items.glass_bottle); + craftingGrid[2][1] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[0][2] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][2] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[2][2] = new ItemStack(Wizardry.magicCrystal); + craftingResult = new ItemStack(Wizardry.manaFlask); this.renderCraftingTooltips(xPos + 23, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[1][0] = new ItemStack(Blocks.STONE); - craftingGrid[0][1] = new ItemStack(Blocks.STONE); - craftingGrid[1][1] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][2] = new ItemStack(Blocks.STONE); - craftingGrid[2][1] = new ItemStack(Blocks.STONE); - craftingResult = new ItemStack(WizardryBlocks.transportation_stone, 2); + craftingGrid[1][0] = new ItemStack(Blocks.stone); + craftingGrid[0][1] = new ItemStack(Blocks.stone); + craftingGrid[1][1] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][2] = new ItemStack(Blocks.stone); + craftingGrid[2][1] = new ItemStack(Blocks.stone); + craftingResult = new ItemStack(Wizardry.transportationStone, 2); this.renderCraftingTooltips(xPos + 156, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[1][0] = new ItemStack(Items.STRING); - craftingGrid[0][1] = new ItemStack(Items.STRING); - craftingGrid[1][1] = new ItemStack(WizardryItems.magic_crystal); - craftingGrid[1][2] = new ItemStack(Items.STRING); - craftingGrid[2][1] = new ItemStack(Items.STRING); - craftingResult = new ItemStack(WizardryItems.magic_silk, 2); + craftingGrid[1][0] = new ItemStack(Items.string); + craftingGrid[0][1] = new ItemStack(Items.string); + craftingGrid[1][1] = new ItemStack(Wizardry.magicCrystal); + craftingGrid[1][2] = new ItemStack(Items.string); + craftingGrid[2][1] = new ItemStack(Items.string); + craftingResult = new ItemStack(Wizardry.magicSilk, 2); this.renderCraftingTooltips(xPos + 156, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); }else if(pageNumber == (sections.get(sections.size()-1).pageNumber-1)/2 + 2){ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[1][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[0][1] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][1] = new ItemStack(WizardryItems.magic_silk); - craftingResult = new ItemStack(WizardryItems.wizard_hat); + craftingGrid[0][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[1][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[0][1] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][1] = new ItemStack(Wizardry.magicSilk); + craftingResult = new ItemStack(Wizardry.wizardHat); this.renderCraftingTooltips(xPos + 23, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[0][1] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[1][1] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][1] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[0][2] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[1][2] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][2] = new ItemStack(WizardryItems.magic_silk); - craftingResult = new ItemStack(WizardryItems.wizard_robe); + craftingGrid[0][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[0][1] = new ItemStack(Wizardry.magicSilk); + craftingGrid[1][1] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][1] = new ItemStack(Wizardry.magicSilk); + craftingGrid[0][2] = new ItemStack(Wizardry.magicSilk); + craftingGrid[1][2] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][2] = new ItemStack(Wizardry.magicSilk); + craftingResult = new ItemStack(Wizardry.wizardRobe); this.renderCraftingTooltips(xPos + 23, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[1][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[0][1] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][1] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[0][2] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][2] = new ItemStack(WizardryItems.magic_silk); - craftingResult = new ItemStack(WizardryItems.wizard_leggings); + craftingGrid[0][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[1][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[0][1] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][1] = new ItemStack(Wizardry.magicSilk); + craftingGrid[0][2] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][2] = new ItemStack(Wizardry.magicSilk); + craftingResult = new ItemStack(Wizardry.wizardLeggings); this.renderCraftingTooltips(xPos + 156, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][0] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[0][1] = new ItemStack(WizardryItems.magic_silk); - craftingGrid[2][1] = new ItemStack(WizardryItems.magic_silk); - craftingResult = new ItemStack(WizardryItems.wizard_boots); + craftingGrid[0][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][0] = new ItemStack(Wizardry.magicSilk); + craftingGrid[0][1] = new ItemStack(Wizardry.magicSilk); + craftingGrid[2][1] = new ItemStack(Wizardry.magicSilk); + craftingResult = new ItemStack(Wizardry.wizardBoots); this.renderCraftingTooltips(xPos + 156, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); }else if(pageNumber == (sections.get(sections.size()-1).pageNumber-1)/2 + 3){ - if(Wizardry.settings.useAlternateScrollRecipe){ + if(Wizardry.useAlternateScrollRecipe){ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(Items.PAPER); - craftingGrid[1][0] = new ItemStack(Items.STRING); - craftingGrid[2][0] = new ItemStack(WizardryItems.magic_crystal); - craftingResult = new ItemStack(WizardryItems.blank_scroll); + craftingGrid[0][0] = new ItemStack(Items.paper); + craftingGrid[1][0] = new ItemStack(Items.string); + craftingGrid[2][0] = new ItemStack(Wizardry.magicCrystal); + craftingResult = new ItemStack(Wizardry.blankScroll); this.renderCraftingTooltips(xPos + 23, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); }else{ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(Items.PAPER); - craftingGrid[1][0] = new ItemStack(Items.STRING); - craftingResult = new ItemStack(WizardryItems.blank_scroll); + craftingGrid[0][0] = new ItemStack(Items.paper); + craftingGrid[1][0] = new ItemStack(Items.string); + craftingResult = new ItemStack(Wizardry.blankScroll); this.renderCraftingTooltips(xPos + 23, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); } - if(Wizardry.settings.firebombIsCraftable){ + if(Wizardry.firebombIsCraftable){ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(Items.BLAZE_POWDER); - craftingGrid[1][0] = new ItemStack(Items.BLAZE_POWDER); - craftingGrid[0][1] = new ItemStack(Items.GLASS_BOTTLE); - craftingGrid[1][1] = new ItemStack(Items.GUNPOWDER); - craftingResult = new ItemStack(WizardryItems.firebomb, 3); + craftingGrid[0][0] = new ItemStack(Items.blaze_powder); + craftingGrid[1][0] = new ItemStack(Items.blaze_powder); + craftingGrid[0][1] = new ItemStack(Items.glass_bottle); + craftingGrid[1][1] = new ItemStack(Items.gunpowder); + craftingResult = new ItemStack(Wizardry.firebomb, 3); this.renderCraftingTooltips(xPos + 23, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); } - if(Wizardry.settings.poisonBombIsCraftable){ + if(Wizardry.poisonBombIsCraftable){ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(Items.SPIDER_EYE); - craftingGrid[1][0] = new ItemStack(Items.SPIDER_EYE); - craftingGrid[0][1] = new ItemStack(Items.GLASS_BOTTLE); - craftingGrid[1][1] = new ItemStack(Items.GUNPOWDER); - craftingResult = new ItemStack(WizardryItems.poison_bomb, 3); + craftingGrid[0][0] = new ItemStack(Items.spider_eye); + craftingGrid[1][0] = new ItemStack(Items.spider_eye); + craftingGrid[0][1] = new ItemStack(Items.glass_bottle); + craftingGrid[1][1] = new ItemStack(Items.gunpowder); + craftingResult = new ItemStack(Wizardry.poisonBomb, 3); this.renderCraftingTooltips(xPos + 156, yPos + 39, mouseX, mouseY, craftingGrid, craftingResult); } - if(Wizardry.settings.smokeBombIsCraftable){ + if(Wizardry.smokeBombIsCraftable){ craftingGrid = new ItemStack[3][3]; - craftingGrid[0][0] = new ItemStack(Items.COAL); - craftingGrid[1][0] = new ItemStack(Items.COAL); - craftingGrid[0][1] = new ItemStack(Items.GLASS_BOTTLE); - craftingGrid[1][1] = new ItemStack(Items.GUNPOWDER); - craftingResult = new ItemStack(WizardryItems.smoke_bomb, 3); + craftingGrid[0][0] = new ItemStack(Items.coal); + craftingGrid[1][0] = new ItemStack(Items.coal); + craftingGrid[0][1] = new ItemStack(Items.glass_bottle); + craftingGrid[1][1] = new ItemStack(Items.gunpowder); + craftingResult = new ItemStack(Wizardry.smokeBomb, 3); this.renderCraftingTooltips(xPos + 156, yPos + 98, mouseX, mouseY, craftingGrid, craftingResult); } @@ -475,30 +485,33 @@ public class GuiWizardHandbook extends GuiScreen { private void renderCraftingRecipe(int xPos, int yPos, int mouseX, int mouseY, ItemStack[][] craftingGrid, ItemStack craftingResult) { - GlStateManager.pushMatrix(); + int guiLeft = this.width/2 - xSize/2; + int guiTop = this.height/2 - this.ySize/2; + + GL11.glPushMatrix(); RenderHelper.enableGUIStandardItemLighting(); - GlStateManager.disableLighting(); - GlStateManager.enableRescaleNormal(); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); GL11.glEnable(GL11.GL_COLOR_MATERIAL); - GlStateManager.enableLighting(); + GL11.glEnable(GL11.GL_LIGHTING); itemRender.zLevel = 100.0F; for(int i=0; i>(1); sections = new ArrayList

    (1); @@ -561,7 +574,7 @@ public class GuiWizardHandbook extends GuiScreen { } catch (IOException e){ - Wizardry.logger.info("Wizard handbook text file missing for the current language. Using default (English - US) instead."); + System.out.println("Warning: wizard handbook text file missing for the current language. Using default (English - US) instead."); textFilepath = "wizardry:texts/handbook_en_US.txt"; @@ -570,8 +583,8 @@ public class GuiWizardHandbook extends GuiScreen { bufferedreader = new BufferedReader(new InputStreamReader(this.mc.getResourceManager().getResource(new ResourceLocation(textFilepath)).getInputStream(), Charsets.UTF_8)); } catch (IOException x){ - Wizardry.logger.error("Couldn't find file: wizardry:assets/texts/handbook_en_US.txt. The file may be" - + "missing; please try re-downloading and reinstalling Wizardry.", x); + System.err.println("Couldn't find file: wizardry:assets/texts/handbook_en_US.txt. The file may be missing; please try re-downloading and reinstalling wizardry."); + x.printStackTrace(); } } @@ -626,29 +639,29 @@ public class GuiWizardHandbook extends GuiScreen { }else{ - paragraph = paragraph.replaceAll("NEXT_SPELL_KEY", Keyboard.getKeyName(ClientProxy.NEXT_SPELL.getKeyCode())); - paragraph = paragraph.replaceAll("PREVIOUS_SPELL_KEY", Keyboard.getKeyName(ClientProxy.PREVIOUS_SPELL.getKeyCode())); - paragraph = paragraph.replaceAll("MANA_PER_CRYSTAL_MINUS_30", "" + (Constants.MANA_PER_CRYSTAL - 30)); - paragraph = paragraph.replaceAll("MANA_PER_CRYSTAL", "" + Constants.MANA_PER_CRYSTAL); - paragraph = paragraph.replaceAll("BASIC_MAX_CHARGE", "" + Tier.BASIC.maxCharge); - paragraph = paragraph.replaceAll("APPRENTICE_MAX_CHARGE", "" + Tier.APPRENTICE.maxCharge); - paragraph = paragraph.replaceAll("ADVANCED_MAX_CHARGE", "" + Tier.ADVANCED.maxCharge); - paragraph = paragraph.replaceAll("MASTER_MAX_CHARGE", "" + Tier.MASTER.maxCharge); + paragraph = paragraph.replaceAll("NEXT_SPELL_KEY", Keyboard.getKeyName(ClientProxy.nextSpell.getKeyCode())); + paragraph = paragraph.replaceAll("PREVIOUS_SPELL_KEY", Keyboard.getKeyName(ClientProxy.previousSpell.getKeyCode())); + paragraph = paragraph.replaceAll("MANA_PER_CRYSTAL_MINUS_30", "" + (Wizardry.MANA_PER_CRYSTAL - 30)); + paragraph = paragraph.replaceAll("MANA_PER_CRYSTAL", "" + Wizardry.MANA_PER_CRYSTAL); + paragraph = paragraph.replaceAll("BASIC_MAX_CHARGE", "" + EnumTier.BASIC.maxCharge); + paragraph = paragraph.replaceAll("APPRENTICE_MAX_CHARGE", "" + EnumTier.APPRENTICE.maxCharge); + paragraph = paragraph.replaceAll("ADVANCED_MAX_CHARGE", "" + EnumTier.ADVANCED.maxCharge); + paragraph = paragraph.replaceAll("MASTER_MAX_CHARGE", "" + EnumTier.MASTER.maxCharge); paragraph = paragraph.replaceAll("BASIC_COLOUR", "\u00A77"); - paragraph = paragraph.replaceAll("APPRENTICE_COLOUR", Tier.APPRENTICE.getFormattingCode()); - paragraph = paragraph.replaceAll("ADVANCED_COLOUR", Tier.ADVANCED.getFormattingCode()); - paragraph = paragraph.replaceAll("MASTER_COLOUR", Tier.MASTER.getFormattingCode()); - paragraph = paragraph.replaceAll("FIRE_COLOUR", Element.FIRE.getFormattingCode()); - paragraph = paragraph.replaceAll("ICE_COLOUR", Element.ICE.getFormattingCode()); - paragraph = paragraph.replaceAll("LIGHTNING_COLOUR", Element.LIGHTNING.getFormattingCode()); - paragraph = paragraph.replaceAll("NECROMANCY_COLOUR", Element.NECROMANCY.getFormattingCode()); - paragraph = paragraph.replaceAll("EARTH_COLOUR", Element.EARTH.getFormattingCode()); - paragraph = paragraph.replaceAll("SORCERY_COLOUR", Element.SORCERY.getFormattingCode()); - paragraph = paragraph.replaceAll("HEALING_COLOUR", Element.HEALING.getFormattingCode()); + paragraph = paragraph.replaceAll("APPRENTICE_COLOUR", EnumTier.APPRENTICE.colour); + paragraph = paragraph.replaceAll("ADVANCED_COLOUR", EnumTier.ADVANCED.colour); + paragraph = paragraph.replaceAll("MASTER_COLOUR", EnumTier.MASTER.colour); + paragraph = paragraph.replaceAll("FIRE_COLOUR", EnumElement.FIRE.colour); + paragraph = paragraph.replaceAll("ICE_COLOUR", EnumElement.ICE.colour); + paragraph = paragraph.replaceAll("LIGHTNING_COLOUR", EnumElement.LIGHTNING.colour); + paragraph = paragraph.replaceAll("NECROMANCY_COLOUR", EnumElement.NECROMANCY.colour); + paragraph = paragraph.replaceAll("EARTH_COLOUR", EnumElement.EARTH.colour); + paragraph = paragraph.replaceAll("SORCERY_COLOUR", EnumElement.SORCERY.colour); + paragraph = paragraph.replaceAll("HEALING_COLOUR", EnumElement.HEALING.colour); paragraph = paragraph.replaceAll("RESET_COLOUR", "\u00A70"); paragraph = paragraph.replaceAll("VERSION", Wizardry.VERSION); - int linesInParagraph = this.fontRendererObj.listFormattedStringToWidth(paragraph, GuiWizardHandbook.PAGE_WIDTH).size(); + int linesInParagraph = this.fontRendererObj.listFormattedStringToWidth(paragraph, this.pageWidth).size(); // Ignores empty lines at the top of a page. if(paragraph.isEmpty() && lineNumber == 0){ @@ -674,7 +687,7 @@ public class GuiWizardHandbook extends GuiScreen { int i = 0; - List strings = this.fontRendererObj.listFormattedStringToWidth(paragraph, GuiWizardHandbook.PAGE_WIDTH); + List strings = this.fontRendererObj.listFormattedStringToWidth(paragraph, this.pageWidth); for(Object s : strings){ if(i < linesInFirstPart){ @@ -699,17 +712,21 @@ public class GuiWizardHandbook extends GuiScreen { text.add(page); } catch (IOException e){ - Wizardry.logger.error("Something went wrong reading file: " + textFilepath + ". The file may be damaged;" - + "please try re-downloading and reinstalling wizardry.", e); + System.err.println("Something went wrong reading file: " + textFilepath + ". The file may be damaged; please try re-downloading and reinstalling wizardry."); + e.printStackTrace(); } } + /* + for(ArrayList a : text){ + for(String s : a){ + System.out.println(s); + } + } + */ } private class Section { - /** The integer text colour used for the section when it is moused over. Currently orange. */ - private static final int HIGHLIGHT_COLOUR = 0xdd4c1d; - String name; int pageNumber; int x, y; @@ -721,32 +738,31 @@ public class GuiWizardHandbook extends GuiScreen { this.x = x; this.y = y; this.buttonId = id; - GuiWizardHandbook.this.buttonList.add(new GuiButtonInvisible(id, x, y, GuiWizardHandbook.PAGE_WIDTH, GuiWizardHandbook.this.fontRendererObj.FONT_HEIGHT)); + GuiWizardHandbook.this.buttonList.add(new GuiButtonInvisible(id, x, y, GuiWizardHandbook.this.pageWidth, GuiWizardHandbook.this.fontRendererObj.FONT_HEIGHT)); } void hideButton(){ - GuiWizardHandbook.this.buttonList.get(buttonId).visible = false; + ((GuiButton)GuiWizardHandbook.this.buttonList.get(buttonId)).visible = false; } void drawContents(){ - GuiWizardHandbook.this.buttonList.get(buttonId).visible = true; + ((GuiButton)GuiWizardHandbook.this.buttonList.get(buttonId)).visible = true; - GuiWizardHandbook.this.fontRendererObj.drawString(name, x, y, GuiWizardHandbook.this.buttonList.get(buttonId).isMouseOver() ? HIGHLIGHT_COLOUR : BLACK); + GuiWizardHandbook.this.fontRendererObj.drawString(name, x, y, ((GuiButton)GuiWizardHandbook.this.buttonList.get(buttonId)).func_146115_a() ? 0xdd4c1d : 0); int nameWidth = GuiWizardHandbook.this.fontRendererObj.getStringWidth(name); String dotsAndNumber = " " + this.pageNumber; - while(GuiWizardHandbook.this.fontRendererObj.getStringWidth(dotsAndNumber) < GuiWizardHandbook.PAGE_WIDTH - nameWidth - 2){ + while(GuiWizardHandbook.this.fontRendererObj.getStringWidth(dotsAndNumber) < GuiWizardHandbook.pageWidth - nameWidth - 2){ dotsAndNumber = "." + dotsAndNumber; } - GuiWizardHandbook.this.fontRendererObj.drawString(dotsAndNumber, x + GuiWizardHandbook.PAGE_WIDTH - GuiWizardHandbook.this.fontRendererObj.getStringWidth(dotsAndNumber), y, BLACK); + GuiWizardHandbook.this.fontRendererObj.drawString(dotsAndNumber, x + GuiWizardHandbook.pageWidth - GuiWizardHandbook.this.fontRendererObj.getStringWidth(dotsAndNumber), y, 0); } } - @Override public void onGuiClosed() { super.onGuiClosed(); @@ -756,7 +772,6 @@ public class GuiWizardHandbook extends GuiScreen { /** * Fired when a control is clicked. This is the equivalent of ActionListener.actionPerformed(ActionEvent e). */ - @Override protected void actionPerformed(GuiButton par1GuiButton){ if(par1GuiButton.enabled){ @@ -782,6 +797,127 @@ public class GuiWizardHandbook extends GuiScreen { par6 -= l1; return par5 >= par1 - 1 && par5 < par1 + par3 + 1 && par6 >= par2 - 1 && par6 < par2 + par4 + 1; } + + protected void drawItemStackTooltip(ItemStack par1ItemStack, int par2, int par3) + { + List list = par1ItemStack.getTooltip(this.mc.thePlayer, this.mc.gameSettings.advancedItemTooltips); + + for (int k = 0; k < list.size(); ++k) + { + if (k == 0) + { + list.set(k, par1ItemStack.getRarity().rarityColor + (String)list.get(k)); + } + else + { + list.set(k, EnumChatFormatting.GRAY + (String)list.get(k)); + } + } + + FontRenderer font = par1ItemStack.getItem().getFontRenderer(par1ItemStack); + drawHoveringText(list, par2, par3, (font == null ? fontRendererObj : font)); + } + + protected void drawHoveringText(List par1List, int par2, int par3, FontRenderer font) + { + if (!par1List.isEmpty()) + { + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + RenderHelper.disableStandardItemLighting(); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_DEPTH_TEST); + int k = 0; + Iterator iterator = par1List.iterator(); + + while (iterator.hasNext()) + { + String s = (String)iterator.next(); + int l = font.getStringWidth(s); + + if (l > k) + { + k = l; + } + } + + int i1 = par2 + 12; + int j1 = par3 - 12; + int k1 = 8; + + if (par1List.size() > 1) + { + k1 += 2 + (par1List.size() - 1) * 10; + } + + if (i1 + k > this.width) + { + i1 -= 28 + k; + } + + if (j1 + k1 + 6 > this.height) + { + j1 = this.height - k1 - 6; + } + + this.zLevel = 300.0F; + itemRender.zLevel = 300.0F; + int l1 = -267386864; + this.drawGradientRect(i1 - 3, j1 - 4, i1 + k + 3, j1 - 3, l1, l1); + this.drawGradientRect(i1 - 3, j1 + k1 + 3, i1 + k + 3, j1 + k1 + 4, l1, l1); + this.drawGradientRect(i1 - 3, j1 - 3, i1 + k + 3, j1 + k1 + 3, l1, l1); + this.drawGradientRect(i1 - 4, j1 - 3, i1 - 3, j1 + k1 + 3, l1, l1); + this.drawGradientRect(i1 + k + 3, j1 - 3, i1 + k + 4, j1 + k1 + 3, l1, l1); + int i2 = 1347420415; + int j2 = (i2 & 16711422) >> 1 | i2 & -16777216; + this.drawGradientRect(i1 - 3, j1 - 3 + 1, i1 - 3 + 1, j1 + k1 + 3 - 1, i2, j2); + this.drawGradientRect(i1 + k + 2, j1 - 3 + 1, i1 + k + 3, j1 + k1 + 3 - 1, i2, j2); + this.drawGradientRect(i1 - 3, j1 - 3, i1 + k + 3, j1 - 3 + 1, i2, i2); + this.drawGradientRect(i1 - 3, j1 + k1 + 2, i1 + k + 3, j1 + k1 + 3, j2, j2); + + for(int k2 = 0; k2 < par1List.size(); ++k2){ + + String s1 = (String)par1List.get(k2); + font.drawStringWithShadow(s1, i1, j1, -1); + + if(k2 == 0){ + j1 += 2; + } + + j1 += 10; + } + + this.zLevel = 0.0F; + itemRender.zLevel = 0.0F; + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_DEPTH_TEST); + RenderHelper.enableStandardItemLighting(); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + } + } + + /** + * Draws a textured rectangle, taking the size of the image and the bit needed into account. + * @param x The x position of the rectangle + * @param y The y position of the rectangle + * @param u The x position of the top left corner of the section of the image wanted + * @param v The y position of the top left corner of the section of the image wanted + * @param width The width of the section + * @param height The height of the section + * @param textureWidth The width of the actual image. + * @param textureHeight The height of the actual image. + */ + public void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight) + { + float f = 1F / (float)textureWidth; + float f1 = 1F / (float)textureHeight; + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV((double)(x), (double)(y + height), 0, (double)((float)(u) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y + height), 0, (double)((float)(u + width) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y), 0, (double)((float)(u + width) * f), (double)((float)(v) * f1)); + tessellator.addVertexWithUV((double)(x), (double)(y), 0, (double)((float)(u) * f), (double)((float)(v) * f1)); + tessellator.draw(); + } /** * Draws a textured rectangle, stretching the section of the image to fit the size given. @@ -794,16 +930,16 @@ public class GuiWizardHandbook extends GuiScreen { * @param width The width of the section, expressed as a fraction of the image width * @param height The height of the section, expressed as a fraction of the image width */ - public static void drawTexturedStretchedRect(int x, int y, int u, int v, int finalWidth, int finalHeight, int width, int height){ - - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - buffer.pos((x), y + finalHeight, 0).tex(u, v + height).endVertex(); - buffer.pos(x + finalWidth, y + finalHeight, 0).tex(u + width, v + height).endVertex(); - buffer.pos(x + finalWidth, (y), 0).tex(u + width, v).endVertex(); - buffer.pos((x), (y), 0).tex(u, v).endVertex(); - tessellator.draw(); + public void drawTexturedStretchedRect(int x, int y, int u, int v, int finalWidth, int finalHeight, int width, int height) + { + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV((double)(x), (double)(y + finalHeight), 0, u, v + height); + tessellator.addVertexWithUV((double)(x + finalWidth), (double)(y + finalHeight), 0, u + width, v + height); + tessellator.addVertexWithUV((double)(x + finalWidth), (double)(y), 0, u + width, v); + tessellator.addVertexWithUV((double)(x), (double)(y), 0, u, v); + tessellator.draw(); } -} \ No newline at end of file +} + diff --git a/src/main/java/electroblob/wizardry/client/MixedFontRenderer.java b/src/main/java/electroblob/wizardry/client/MixedFontRenderer.java index 43b51f8b..4124cc49 100644 --- a/src/main/java/electroblob/wizardry/client/MixedFontRenderer.java +++ b/src/main/java/electroblob/wizardry/client/MixedFontRenderer.java @@ -1,12 +1,15 @@ package electroblob.wizardry.client; +import java.util.ArrayList; +import java.util.List; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.settings.GameSettings; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; /** Font renderer that renders parts of strings surrounded by '#' (without quotes) in the SGA instead of normal text. * @since Wizardry 1.1 */ @@ -19,7 +22,7 @@ public class MixedFontRenderer extends FontRenderer { } @Override - public int drawString(String string, float x, float y, int colour, boolean shadow){ + public int drawString(String string, int x, int y, int colour, boolean shadow){ int l = 0; @@ -33,8 +36,8 @@ public class MixedFontRenderer extends FontRenderer { l += Minecraft.getMinecraft().standardGalacticFontRenderer.drawString(section, x, y, colour, shadow); x += Minecraft.getMinecraft().standardGalacticFontRenderer.getStringWidth(section); }else{ - l += Minecraft.getMinecraft().fontRendererObj.drawString(section, x, y, colour, shadow); - x += Minecraft.getMinecraft().fontRendererObj.getStringWidth(section); + l += Minecraft.getMinecraft().fontRenderer.drawString(section, x, y, colour, shadow); + x += Minecraft.getMinecraft().fontRenderer.getStringWidth(section); } string = string.substring(string.indexOf('#') + 1); @@ -44,7 +47,7 @@ public class MixedFontRenderer extends FontRenderer { if(sga){ l += Minecraft.getMinecraft().standardGalacticFontRenderer.drawString(string, x, y, colour, shadow); }else{ - l += Minecraft.getMinecraft().fontRendererObj.drawString(string, x, y, colour, shadow); + l += Minecraft.getMinecraft().fontRenderer.drawString(string, x, y, colour, shadow); } return l; @@ -64,7 +67,7 @@ public class MixedFontRenderer extends FontRenderer { if(sga){ l += Minecraft.getMinecraft().standardGalacticFontRenderer.getStringWidth(section); }else{ - l += Minecraft.getMinecraft().fontRendererObj.getStringWidth(section); + l += Minecraft.getMinecraft().fontRenderer.getStringWidth(section); } string = string.substring(string.indexOf('#') + 1); @@ -74,7 +77,7 @@ public class MixedFontRenderer extends FontRenderer { if(sga){ l += Minecraft.getMinecraft().standardGalacticFontRenderer.getStringWidth(string); }else{ - l += Minecraft.getMinecraft().fontRendererObj.getStringWidth(string); + l += Minecraft.getMinecraft().fontRenderer.getStringWidth(string); } return l; @@ -87,7 +90,7 @@ public class MixedFontRenderer extends FontRenderer { if(string.contains("#")){ Minecraft.getMinecraft().standardGalacticFontRenderer.drawSplitString(string.substring(1), x, y, width, colour); }else{ - Minecraft.getMinecraft().fontRendererObj.drawSplitString(string, x, y, width, colour); + Minecraft.getMinecraft().fontRenderer.drawSplitString(string, x, y, width, colour); } } diff --git a/src/main/java/electroblob/wizardry/client/MovingSoundEntity.java b/src/main/java/electroblob/wizardry/client/MovingSoundEntity.java index 3696e866..d10388e9 100644 --- a/src/main/java/electroblob/wizardry/client/MovingSoundEntity.java +++ b/src/main/java/electroblob/wizardry/client/MovingSoundEntity.java @@ -1,35 +1,31 @@ package electroblob.wizardry.client; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.audio.MovingSound; import net.minecraft.entity.Entity; -import net.minecraft.util.SoundCategory; -import net.minecraft.util.SoundEvent; -import net.minecraft.util.math.MathHelper; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; -// Copied from MovingSoundMinecart; if it ever breaks between updates take a look at that. @SideOnly(Side.CLIENT) public class MovingSoundEntity extends MovingSound { private final Entity source; - private float distance = 0.0F; + private float pitch = 0.0F; - public MovingSoundEntity(Entity entity, SoundEvent sound, float volume, float pitch, boolean repeat) + public MovingSoundEntity(Entity entity, String soundName, float volume, float pitch, boolean repeat) { - // Uses BLOCKS because that's the closest thing to inanimate entities. Could use NEUTRAL like MovingSoundMinecart. - super(sound, SoundCategory.BLOCKS); + super(new ResourceLocation(soundName)); this.source = entity; this.repeat = repeat; this.volume = volume; - this.pitch = pitch; - this.repeatDelay = 0; + this.field_147663_c = pitch; + this.field_147665_h = 0; } /** * Updates the JList with a new model. */ - @Override public void update() { if (this.source.isDead && repeat) @@ -46,7 +42,7 @@ public class MovingSoundEntity extends MovingSound // Is this something to do with the Doppler effect? if ((double)f >= 0.01D) { - this.distance = MathHelper.clamp_float(this.distance + 0.0025F, 0.0F, 1.0F); + this.pitch = MathHelper.clamp_float(this.pitch + 0.0025F, 0.0F, 1.0F); this.volume = 0.0F + MathHelper.clamp_float(f, 0.0F, 0.5F) * 0.7F; } else diff --git a/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java b/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java index 84b0d552..5a117bd6 100644 --- a/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java +++ b/src/main/java/electroblob/wizardry/client/WizardryClientEventHandler.java @@ -2,130 +2,116 @@ package electroblob.wizardry.client; import org.lwjgl.opengl.GL11; -import electroblob.wizardry.WizardData; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.WandHelper; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Constants; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.entity.EntityShield; +import electroblob.wizardry.item.ItemSpectralArmour; import electroblob.wizardry.item.ItemSpectralBow; import electroblob.wizardry.item.ItemWand; import electroblob.wizardry.packet.PacketControlInput; import electroblob.wizardry.packet.WizardryPacketHandler; -import electroblob.wizardry.registry.WizardryPotions; import electroblob.wizardry.spell.Flight; import electroblob.wizardry.spell.ShadowWard; import electroblob.wizardry.spell.Shield; -import electroblob.wizardry.tileentity.ContainerArcaneWorkbench; -import electroblob.wizardry.util.WandHelper; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.spell.Spell; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.RayTraceResult; import net.minecraftforge.client.event.FOVUpdateEvent; import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderLivingEvent; import net.minecraftforge.client.event.RenderPlayerEvent; import net.minecraftforge.client.event.RenderWorldLastEvent; -import net.minecraftforge.client.event.TextureStitchEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.relauncher.Side; -/** - * Event handler responsible for all client-side only events, mostly rendering. - * @author Electroblob - * @since Wizardry 1.0 - */ -@Mod.EventBusSubscriber(Side.CLIENT) -public final class WizardryClientEventHandler { +/** Event handler responsible for all client-side only events, mostly rendering. + * @since Wizardry 1.0 */ +public class WizardryClientEventHandler { - private static final ResourceLocation shieldTexture = new ResourceLocation(Wizardry.MODID, "textures/entity/shield.png"); - private static final ResourceLocation wingTexture = new ResourceLocation(Wizardry.MODID, "textures/entity/wing.png"); - private static final ResourceLocation shadowWardTexture = new ResourceLocation(Wizardry.MODID, "textures/entity/shadow_ward.png"); - private static final ResourceLocation sixthSenseTexture = new ResourceLocation(Wizardry.MODID, "textures/entity/sixth_sense.png"); - private static final ResourceLocation sixthSenseOverlayTexture = new ResourceLocation(Wizardry.MODID, "textures/gui/sixth_sense_overlay.png"); - private static final ResourceLocation frostOverlayTexture = new ResourceLocation(Wizardry.MODID, "textures/gui/frost_overlay.png"); - private static final ResourceLocation pointerTexture = new ResourceLocation(Wizardry.MODID, "textures/entity/pointer.png"); - private static final ResourceLocation targetPointerTexture = new ResourceLocation(Wizardry.MODID, "textures/entity/target_pointer.png"); + private static final ResourceLocation shieldTexture = new ResourceLocation("wizardry:textures/entity/shield.png"); + private static final ResourceLocation wingTexture = new ResourceLocation("wizardry:textures/entity/wing.png"); + private static final ResourceLocation shadowWardTexture = new ResourceLocation("wizardry:textures/entity/shadow_ward.png"); + private static final ResourceLocation sixthSenseTexture = new ResourceLocation("wizardry:textures/entity/sixth_sense.png"); + private static final ResourceLocation sixthSenseOverlayTexture = new ResourceLocation("wizardry:textures/gui/sixth_sense_overlay.png"); + private static final ResourceLocation frostOverlayTexture = new ResourceLocation("wizardry:textures/gui/frost_overlay.png"); + private static final ResourceLocation pointerTexture = new ResourceLocation("wizardry:textures/entity/pointer.png"); + private static final ResourceLocation targetPointerTexture = new ResourceLocation("wizardry:textures/entity/target_pointer.png"); @SubscribeEvent - public static void onTextureStitchEvent(TextureStitchEvent.Pre event){ - event.getMap().registerSprite(ContainerArcaneWorkbench.EMPTY_SLOT_CRYSTAL); - event.getMap().registerSprite(ContainerArcaneWorkbench.EMPTY_SLOT_UPGRADE); + public void onRenderPlayerArmourEvent(RenderPlayerEvent.SetArmorModel event){ + + ItemStack stack = event.entityPlayer.inventory.armorInventory[event.slot]; + + if(stack != null && stack.getItem() instanceof ItemSpectralArmour){ + GL11.glEnable(GL11.GL_BLEND); + } } // Shift-scrolling to change spells @SubscribeEvent - public static void onMouseEvent(MouseEvent event){ - - EntityPlayer player = Minecraft.getMinecraft().thePlayer; - ItemStack wand = player.getHeldItemMainhand(); - - if(wand == null || !(wand.getItem() instanceof ItemWand)){ - wand = player.getHeldItemOffhand(); - // If the player isn't holding a wand, then nothing else needs to be done. - if(wand == null || !(wand.getItem() instanceof ItemWand)) return; - } - - if(Minecraft.getMinecraft().inGameHasFocus && wand != null && event.getDwheel() != 0 && player.isSneaking() - && Wizardry.settings.enableShiftScrolling){ + public void onMouseEvent(MouseEvent event){ + if(Minecraft.getMinecraft().inGameHasFocus && Minecraft.getMinecraft().thePlayer.getHeldItem() != null + && Minecraft.getMinecraft().thePlayer.getHeldItem().getItem() instanceof ItemWand && event.dwheel != 0 + && Minecraft.getMinecraft().thePlayer.isSneaking() && Wizardry.enableShiftScrolling){ event.setCanceled(true); - if(event.getDwheel() > 0){ + if(event.dwheel > 0){ // Packet building - IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.PREVIOUS_SPELL_KEY); + IMessage msg = new PacketControlInput.Message(2); WizardryPacketHandler.net.sendToServer(msg); - }else if(event.getDwheel() < 0){ + }else if(event.dwheel < 0){ // Packet building - IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.NEXT_SPELL_KEY); + IMessage msg = new PacketControlInput.Message(1); WizardryPacketHandler.net.sendToServer(msg); } } } @SubscribeEvent - public static void onFOVUpdateEvent(FOVUpdateEvent event){ + public void onFOVUpdateEvent(FOVUpdateEvent event){ - // Bow zoom. Taken directly from AbstractClientPlayer so it works exactly like vanilla. - if(event.getEntity().isHandActive() && event.getEntity().getActiveItemStack() != null - && event.getEntity().getActiveItemStack().getItem() instanceof ItemSpectralBow){ - - int maxUseTicks = event.getEntity().getItemInUseMaxCount(); - - float maxUseSeconds = (float)maxUseTicks / 20.0F; + // Bow zoom. Taken directly from EntityPlayerSP so it works exactly like vanilla. + if (event.entity.isUsingItem() && event.entity.getItemInUse().getItem() instanceof ItemSpectralBow) + { + int i = event.entity.getItemInUseDuration(); + float f1 = (float)i / 20.0F; - if(maxUseSeconds > 1.0F){ - maxUseSeconds = 1.0F; - }else{ - maxUseSeconds = maxUseSeconds * maxUseSeconds; - } + if (f1 > 1.0F) + { + f1 = 1.0F; + } + else + { + f1 *= f1; + } - event.setNewfov(event.getFov() * 1.0F - maxUseSeconds * 0.15F); - } + event.newfov *= 1.0F - f1 * 0.15F; + } } // Third person @SubscribeEvent - public static void onRenderPlayerEvent(RenderPlayerEvent.Post event){ - renderShieldIfActive(event.getEntityPlayer()); - renderWingsIfActive(event.getEntityPlayer(), event.getPartialRenderTick()); - renderShadowWardIfActive(event.getEntityPlayer()); + public void onRenderPlayerEvent(RenderPlayerEvent.Specials.Post event){ + renderShieldIfActive(event.entityPlayer); + renderWingsIfActive(event.entityPlayer, event.partialRenderTick); + renderShadowWardIfActive(event.entityPlayer); } // First person @SubscribeEvent - public static void onRenderWorldLastEvent(RenderWorldLastEvent event){ + public void onRenderWorldLastEvent(RenderWorldLastEvent event){ // Now only fires in first person. if(Minecraft.getMinecraft().gameSettings.thirdPersonView == 0){ renderShieldFirstPerson(Minecraft.getMinecraft().thePlayer); @@ -134,15 +120,15 @@ public final class WizardryClientEventHandler { } @SubscribeEvent - public static void onRenderLivingEvent(RenderLivingEvent.Post event){ + public void onRenderLivingEvent(RenderLivingEvent.Post event){ /* // Frost effect if(event.entity.isPotionActive(Wizardry.frost)){ - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); GL11.glDisable(GL11.GL_TEXTURE_2D); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); float someScalingFactor = 0.0625f; @@ -153,16 +139,16 @@ public final class WizardryClientEventHandler { //int j = brightness % 65536; //int k = brightness / 65536; //OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)j / 1.0F, (float)k / 1.0F); - //GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + //GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - GlStateManager.translate(event.x, event.y, event.z); + GL11.glTranslated(event.x, event.y, event.z); - GlStateManager.rotate(-yaw + 180, 0F, 1F, 0F); + GL11.glRotatef(-yaw + 180, 0F, 1F, 0F); - Render render = renderManager.getEntityRenderObject(event.entity); + Render render = RenderManager.instance.getEntityRenderObject(event.entity); - RenderLiving renderliving = event.renderer; + RendererLivingEntity renderliving = event.renderer; // Reflection @@ -180,20 +166,20 @@ public final class WizardryClientEventHandler { // Turns out that java automatically infers the type parameter T in this method from the type // I am assigning the returned value to. Neat! - ModelBase mainModel = ReflectionHelper.getPrivateValue(RenderLiving.class, renderliving, "mainModel"); + ModelBase mainModel = ReflectionHelper.getPrivateValue(RendererLivingEntity.class, renderliving, "mainModel"); mainModel.isRiding = event.entity.isRiding(); mainModel.isChild = event.entity.isChild(); - GlStateManager.enableRescaleNormal(); - GlStateManager.scale(-1.0F, -1.0F, 1.0F); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + GL11.glScalef(-1.0F, -1.0F, 1.0F); // The second argument is never used... - ReflectionHelper.findMethod(RenderLiving.class, renderliving, new String[]{"preRenderCallback"}, EntityLivingBase.class, float.class) + ReflectionHelper.findMethod(RendererLivingEntity.class, renderliving, new String[]{"preRenderCallback"}, EntityLivingBase.class, float.class) .invoke(renderliving, event.entity, someScalingFactor); // Why is this -1.5f? No idea! - GlStateManager.translate(0, -1.5f, 0); + GL11.glTranslatef(0, -1.5f, 0); float f6 = event.entity.prevLimbSwingAmount + (event.entity.limbSwingAmount - event.entity.prevLimbSwingAmount) * timer.renderPartialTicks; float f7 = event.entity.limbSwing - event.entity.limbSwingAmount * (1.0F - timer.renderPartialTicks); @@ -210,8 +196,8 @@ public final class WizardryClientEventHandler { mainModel.setLivingAnimations(event.entity, f7, f6, timer.renderPartialTicks); - GlStateManager.enableAlpha(); - GlStateManager.color(0.5f, 0.7f, 1, 0.5f); + GL11.glEnable(GL11.GL_ALPHA_TEST); + GL11.glColor4f(0.5f, 0.7f, 1, 0.5f); mainModel.render(event.entity, f7, f6, 0, 0, 0, someScalingFactor); @@ -223,488 +209,510 @@ public final class WizardryClientEventHandler { e.printStackTrace(); } - GlStateManager.disableAlpha(); - GlStateManager.disableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - GlStateManager.disableRescaleNormal(); + GL11.glDisable(GL11.GL_ALPHA_TEST); + GL11.glDisable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); GL11.glEnable(GL11.GL_TEXTURE_2D); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); } */ Minecraft mc = Minecraft.getMinecraft(); - WizardData properties = WizardData.get(mc.thePlayer); - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(mc.theWorld, mc.thePlayer, 16); - RenderManager renderManager = event.getRenderer().getRenderManager(); - - ItemStack wand = mc.thePlayer.getHeldItemMainhand(); - - if(wand == null || !(wand.getItem() instanceof ItemWand)){ - wand = mc.thePlayer.getHeldItemOffhand(); - } + ExtendedPlayer properties = ExtendedPlayer.get(mc.thePlayer); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(mc.theWorld, mc.thePlayer, 16); // Target selection pointer - if(mc.thePlayer.isSneaking() && wand != null && wand.getItem() instanceof ItemWand && rayTrace != null - && rayTrace.entityHit instanceof EntityLivingBase && rayTrace.entityHit == event.getEntity() + if(mc.thePlayer.isSneaking() && mc.thePlayer.getHeldItem() != null + && mc.thePlayer.getHeldItem().getItem() instanceof ItemWand && rayTrace != null + && rayTrace.entityHit instanceof EntityLivingBase && rayTrace.entityHit == event.entity && properties != null && properties.selectedMinion != null){ - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); + Tessellator tessellator = Tessellator.instance; - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); - GlStateManager.disableCull(); - GlStateManager.disableLighting(); + GL11.glDisable(GL11.GL_CULL_FACE); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); // Disabling depth test allows it to be seen through everything. GL11.glDisable(GL11.GL_DEPTH_TEST); - GlStateManager.color(1, 1, 1, 1); + GL11.glColor4f(1, 1, 1, 1); - GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height + 0.5, event.getZ()); + GL11.glTranslated(event.x, event.y + event.entity.height + 0.5, event.z); // This counteracts the reverse rotation behaviour when in front f5 view. // Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example. - float yaw = mc.gameSettings.thirdPersonView == 2 ? renderManager.playerViewX : -renderManager.playerViewX; - GlStateManager.rotate(180 - renderManager.playerViewY, 0.0F, 1.0F, 0.0F); - GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F); + float yaw = mc.gameSettings.thirdPersonView == 2 ? RenderManager.instance.playerViewX : -RenderManager.instance.playerViewX; + GL11.glRotatef(180 - RenderManager.instance.playerViewY, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(yaw, 1.0F, 0.0F, 0.0F); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + tessellator.startDrawingQuads(); mc.renderEngine.bindTexture(targetPointerTexture); - buffer.pos(-0.2, 0.24, 0).tex(0, 0).endVertex(); - buffer.pos(0.2, 0.24, 0).tex(9f/16f, 0).endVertex(); - buffer.pos(0.2, -0.24, 0).tex(9f/16f, 11f/16f).endVertex(); - buffer.pos(-0.2, -0.24, 0).tex(0, 11f/16f).endVertex(); + tessellator.addVertexWithUV(-0.2, 0.24, 0, 0, 0); + tessellator.addVertexWithUV(0.2, 0.24, 0, 9f/16f, 0); + tessellator.addVertexWithUV(0.2, -0.24, 0, 9f/16f, 11f/16f); + tessellator.addVertexWithUV(-0.2, -0.24, 0, 0, 11f/16f); tessellator.draw(); - GlStateManager.enableCull(); - GlStateManager.enableLighting(); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glEnable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_DEPTH_TEST); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); } // Summoned creature selection pointer - if(properties != null && properties.selectedMinion != null && properties.selectedMinion.get() == event.getEntity()){ + if(properties != null && properties.selectedMinion != null && properties.selectedMinion.get() == event.entity){ - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); + Tessellator tessellator = Tessellator.instance; - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); - GlStateManager.disableCull(); - GlStateManager.disableLighting(); + GL11.glDisable(GL11.GL_CULL_FACE); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); // Disabling depth test allows it to be seen through everything. GL11.glDisable(GL11.GL_DEPTH_TEST); - GlStateManager.color(1, 1, 1, 1); + GL11.glColor4f(1, 1, 1, 1); - GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height + 0.5, event.getZ()); + GL11.glTranslated(event.x, event.y + event.entity.height + 0.5, event.z); // This counteracts the reverse rotation behaviour when in front f5 view. // Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example. - float yaw = mc.gameSettings.thirdPersonView == 2 ? renderManager.playerViewX : -renderManager.playerViewX; - GlStateManager.rotate(180 - renderManager.playerViewY, 0.0F, 1.0F, 0.0F); - GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F); + float yaw = mc.gameSettings.thirdPersonView == 2 ? RenderManager.instance.playerViewX : -RenderManager.instance.playerViewX; + GL11.glRotatef(180 - RenderManager.instance.playerViewY, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(yaw, 1.0F, 0.0F, 0.0F); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + tessellator.startDrawingQuads(); mc.renderEngine.bindTexture(pointerTexture); - buffer.pos(-0.2, 0.24, 0).tex(0, 0).endVertex(); - buffer.pos(0.2, 0.24, 0).tex(9f/16f, 0).endVertex(); - buffer.pos(0.2, -0.24, 0).tex(9f/16f, 11f/16f).endVertex(); - buffer.pos(-0.2, -0.24, 0).tex(0, 11f/16f).endVertex(); + tessellator.addVertexWithUV(-0.2, 0.24, 0, 0, 0); + tessellator.addVertexWithUV(0.2, 0.24, 0, 9f/16f, 0); + tessellator.addVertexWithUV(0.2, -0.24, 0, 9f/16f, 11f/16f); + tessellator.addVertexWithUV(-0.2, -0.24, 0, 0, 11f/16f); tessellator.draw(); - GlStateManager.enableCull(); - GlStateManager.enableLighting(); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glEnable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_DEPTH_TEST); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); } // Sixth sense - if(mc.thePlayer.isPotionActive(WizardryPotions.sixth_sense) && event.getEntity() != mc.thePlayer - && mc.thePlayer.getActivePotionEffect(WizardryPotions.sixth_sense) != null - && event.getEntity().getDistanceToEntity(mc.thePlayer) < 20*(1+mc.thePlayer.getActivePotionEffect(WizardryPotions.sixth_sense).getAmplifier()*Constants.RANGE_INCREASE_PER_LEVEL)){ + if(mc.thePlayer.isPotionActive(Wizardry.sixthSense) && event.entity != mc.thePlayer + && mc.thePlayer.getActivePotionEffect(Wizardry.sixthSense) != null + && event.entity.getDistanceToEntity(mc.thePlayer) < 20*(1+mc.thePlayer.getActivePotionEffect(Wizardry.sixthSense).getAmplifier()*Wizardry.RANGE_INCREASE_PER_LEVEL)){ - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); + Tessellator tessellator = Tessellator.instance; - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); - GlStateManager.disableCull(); - GlStateManager.enableBlend(); - GlStateManager.disableLighting(); + GL11.glDisable(GL11.GL_CULL_FACE); + GL11.glEnable(GL11.GL_BLEND); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); // Disabling depth test allows it to be seen through everything. GL11.glDisable(GL11.GL_DEPTH_TEST); - GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height * 0.6, event.getZ()); + GL11.glTranslated(event.x, event.y + event.entity.height * 0.6, event.z); // This counteracts the reverse rotation behaviour when in front f5 view. // Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example. - float yaw = mc.gameSettings.thirdPersonView == 2 ? renderManager.playerViewX : -renderManager.playerViewX; - GlStateManager.rotate(180 - renderManager.playerViewY, 0.0F, 1.0F, 0.0F); - GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F); + float yaw = mc.gameSettings.thirdPersonView == 2 ? RenderManager.instance.playerViewX : -RenderManager.instance.playerViewX; + GL11.glRotatef(180 - RenderManager.instance.playerViewY, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(yaw, 1.0F, 0.0F, 0.0F); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + tessellator.startDrawingQuads(); mc.renderEngine.bindTexture(sixthSenseTexture); - buffer.pos(-0.6, 0.6, 0).tex(0, 0).endVertex(); - buffer.pos(0.6, 0.6, 0).tex(1, 0).endVertex(); - buffer.pos(0.6, -0.6, 0).tex(1, 1).endVertex(); - buffer.pos(-0.6, -0.6, 0).tex(0, 1).endVertex(); + tessellator.addVertexWithUV(-0.6, 0.6, 0, 0, 0); + tessellator.addVertexWithUV(0.6, 0.6, 0, 1, 0); + tessellator.addVertexWithUV(0.6, -0.6, 0, 1, 1); + tessellator.addVertexWithUV(-0.6, -0.6, 0, 0, 1); tessellator.draw(); - GlStateManager.enableCull(); - GlStateManager.disableBlend(); - GlStateManager.enableLighting(); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_DEPTH_TEST); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); } } @SubscribeEvent - public static void onRenderGameOverlayEvent(RenderGameOverlayEvent.Post event){ - - if(event.getType() == RenderGameOverlayEvent.ElementType.HELMET - && Minecraft.getMinecraft().thePlayer.isPotionActive(WizardryPotions.sixth_sense)){ + public void onRenderGameOverlayEvent(RenderGameOverlayEvent.Post event){ + if(event.type == RenderGameOverlayEvent.ElementType.HELMET + && Minecraft.getMinecraft().thePlayer.isPotionActive(Wizardry.sixthSense)){ - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); GL11.glDisable(GL11.GL_DEPTH_TEST); GL11.glDepthMask(false); OpenGlHelper.glBlendFunc(770, 771, 1, 0); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - GlStateManager.disableAlpha(); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(GL11.GL_ALPHA_TEST); Minecraft.getMinecraft().renderEngine.bindTexture(sixthSenseOverlayTexture); - - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); - - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - buffer.pos(0.0D, (double)event.getResolution().getScaledHeight(), -90.0D).tex(0.0D, 1.0D).endVertex(); - buffer.pos((double)event.getResolution().getScaledWidth(), (double)event.getResolution().getScaledHeight(), -90.0D).tex(1.0D, 1.0D).endVertex(); - buffer.pos((double)event.getResolution().getScaledWidth(), 0.0D, -90.0D).tex(1.0D, 0.0D).endVertex(); - buffer.pos(0.0D, 0.0D, -90.0D).tex(0.0D, 0.0D).endVertex(); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(0.0D, (double)event.resolution.getScaledHeight(), -90.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV((double)event.resolution.getScaledWidth(), (double)event.resolution.getScaledHeight(), -90.0D, 1.0D, 1.0D); + tessellator.addVertexWithUV((double)event.resolution.getScaledWidth(), 0.0D, -90.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(0.0D, 0.0D, -90.0D, 0.0D, 0.0D); tessellator.draw(); - GL11.glDepthMask(true); GL11.glEnable(GL11.GL_DEPTH_TEST); - GlStateManager.enableAlpha(); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glEnable(GL11.GL_ALPHA_TEST); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); } - if(event.getType() == RenderGameOverlayEvent.ElementType.HELMET - && Minecraft.getMinecraft().thePlayer.isPotionActive(WizardryPotions.frost)){ + if(event.type == RenderGameOverlayEvent.ElementType.HELMET + && Minecraft.getMinecraft().thePlayer.isPotionActive(Wizardry.frost)){ - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); GL11.glDisable(GL11.GL_DEPTH_TEST); GL11.glDepthMask(false); OpenGlHelper.glBlendFunc(770, 771, 1, 0); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - GlStateManager.disableAlpha(); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glDisable(GL11.GL_ALPHA_TEST); Minecraft.getMinecraft().renderEngine.bindTexture(frostOverlayTexture); - - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); - - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - buffer.pos(0.0D, (double)event.getResolution().getScaledHeight(), -90.0D).tex(0.0D, 1.0D).endVertex(); - buffer.pos((double)event.getResolution().getScaledWidth(), (double)event.getResolution().getScaledHeight(), -90.0D).tex(1.0D, 1.0D).endVertex(); - buffer.pos((double)event.getResolution().getScaledWidth(), 0.0D, -90.0D).tex(1.0D, 0.0D).endVertex(); - buffer.pos(0.0D, 0.0D, -90.0D).tex(0.0D, 0.0D).endVertex(); - + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(0.0D, (double)event.resolution.getScaledHeight(), -90.0D, 0.0D, 1.0D); + tessellator.addVertexWithUV((double)event.resolution.getScaledWidth(), (double)event.resolution.getScaledHeight(), -90.0D, 1.0D, 1.0D); + tessellator.addVertexWithUV((double)event.resolution.getScaledWidth(), 0.0D, -90.0D, 1.0D, 0.0D); + tessellator.addVertexWithUV(0.0D, 0.0D, -90.0D, 0.0D, 0.0D); tessellator.draw(); GL11.glDepthMask(true); GL11.glEnable(GL11.GL_DEPTH_TEST); - GlStateManager.enableAlpha(); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glEnable(GL11.GL_ALPHA_TEST); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); } } - // FIXME: Something in here is making the first person shadow ward rather translucent. private static void renderShadowWardFirstPerson(EntityPlayer entityplayer){ - ItemStack wand = entityplayer.getActiveItemStack(); - if(WizardData.get(entityplayer) != null && WizardData.get(entityplayer).currentlyCasting() instanceof ShadowWard || (entityplayer.isHandActive() && wand != null && wand.getItemDamage() < wand.getMaxDamage() + ItemStack wand = entityplayer.getHeldItem(); + if(ExtendedPlayer.get(entityplayer).currentlyCasting() instanceof ShadowWard || (entityplayer.isUsingItem() && wand != null && wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand && WandHelper.getCurrentSpell(wand) instanceof ShadowWard)){ - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - GlStateManager.shadeModel(GL11.GL_SMOOTH); - GlStateManager.disableLighting(); - GlStateManager.disableAlpha(); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); - GlStateManager.translate(0, 1.2, 0); - GlStateManager.rotate(-entityplayer.rotationYaw, 0, 1, 0); - GlStateManager.rotate(entityplayer.rotationPitch, 1, 0, 0); - + GL11.glRotatef(-1*entityplayer.rotationYaw, 0, 1, 0); + GL11.glRotatef(entityplayer.rotationPitch, 1, 0, 0); Minecraft.getMinecraft().renderEngine.bindTexture(shadowWardTexture); + Tessellator tessellator = Tessellator.instance; - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); - GlStateManager.translate(0, 0, 1.2); - GlStateManager.rotate(entityplayer.worldObj.getWorldTime()*-2, 0, 0, 1); - GlStateManager.scale(1.1, 1.1, 1.1); + GL11.glTranslated(0, -0.3, 1.2); + GL11.glRotated(entityplayer.worldObj.getWorldTime()*-2, 0, 0, 1); + GL11.glScaled(1.1, 1.1, 1.1); - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); - - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + tessellator.startDrawingQuads(); - buffer.pos(-0.5, 0.5, -0.5).tex(0, 0).endVertex(); - buffer.pos(0.5, 0.5, -0.5).tex(1, 0).endVertex(); - buffer.pos(0.5, -0.5, -0.5).tex(1, 1).endVertex(); - buffer.pos(-0.5, -0.5, -0.5).tex(0, 1).endVertex(); + tessellator.addVertexWithUV(-0.5, 0.5, -0.5, 0, 0); + tessellator.addVertexWithUV(0.5, 0.5, -0.5, 1, 0); + tessellator.addVertexWithUV(0.5, -0.5, -0.5, 1, 1); + tessellator.addVertexWithUV(-0.5, -0.5, -0.5, 0, 1); tessellator.draw(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + tessellator.startDrawingQuads(); - buffer.pos(-0.5, 0.5, -0.5).tex(0, 0).endVertex(); - buffer.pos(-0.5, -0.5, -0.5).tex(0, 1).endVertex(); - buffer.pos(0.5, -0.5, -0.5).tex(1, 1).endVertex(); - buffer.pos(0.5, 0.5, -0.5).tex(1, 0).endVertex(); + tessellator.addVertexWithUV(-0.5, 0.5, -0.5, 0, 0); + tessellator.addVertexWithUV(-0.5, -0.5, -0.5, 0, 1); + tessellator.addVertexWithUV(0.5, -0.5, -0.5, 1, 1); + tessellator.addVertexWithUV(0.5, 0.5, -0.5, 1, 0); tessellator.draw(); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); - GlStateManager.shadeModel(GL11.GL_FLAT); - GlStateManager.enableLighting(); - GlStateManager.disableBlend(); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_BLEND); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); } } private static void renderShadowWardIfActive(EntityPlayer entityplayer){ - ItemStack wand = entityplayer.getActiveItemStack(); - if(WizardData.get(entityplayer).currentlyCasting() instanceof ShadowWard || (entityplayer.isHandActive() && wand != null + ItemStack wand = entityplayer.getHeldItem(); + if(ExtendedPlayer.get(entityplayer).currentlyCasting() instanceof ShadowWard || (entityplayer.isUsingItem() && wand != null && wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand && WandHelper.getCurrentSpell(wand) instanceof ShadowWard)){ - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - GlStateManager.disableLighting(); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); - GlStateManager.rotate(180, 0, 1, 0); - GlStateManager.rotate(-entityplayer.renderYawOffset, 0, 1, 0); - + GL11.glRotatef(180, 0, 1, 0); + //GL11.glRotatef(entityplayer.rotationYaw, 0, 1, 0); + //GL11.glRotatef(-entityplayer.rotationPitch, 1, 0, 0); Minecraft.getMinecraft().renderEngine.bindTexture(shadowWardTexture); - - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); + Tessellator tessellator = Tessellator.instance; - GlStateManager.translate(0, 1.2, 0); - GlStateManager.rotate(entityplayer.worldObj.getWorldTime()*-2, 0, 0, 1); - GlStateManager.scale(1.1, 1.1, 1.1); + GL11.glPushMatrix(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + // was 0, -0.3, 1.2 + GL11.glTranslated(0, 0, 1.2); + GL11.glRotated(entityplayer.worldObj.getWorldTime()*-2, 0, 0, 1); + GL11.glScaled(1.1, 1.1, 1.1); - buffer.pos(-0.5, 0.5, -0.5).tex(0, 0).endVertex(); - buffer.pos(0.5, 0.5, -0.5).tex(1, 0).endVertex(); - buffer.pos(0.5, -0.5, -0.5).tex(1, 1).endVertex(); - buffer.pos(-0.5, -0.5, -0.5).tex(0, 1).endVertex(); + tessellator.startDrawingQuads(); + + tessellator.addVertexWithUV(-0.5, 0.5, -0.5, 0, 0); + tessellator.addVertexWithUV(0.5, 0.5, -0.5, 1, 0); + tessellator.addVertexWithUV(0.5, -0.5, -0.5, 1, 1); + tessellator.addVertexWithUV(-0.5, -0.5, -0.5, 0, 1); tessellator.draw(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + tessellator.startDrawingQuads(); - buffer.pos(-0.5, 0.5, -0.5).tex(0, 0).endVertex(); - buffer.pos(-0.5, -0.5, -0.5).tex(0, 1).endVertex(); - buffer.pos(0.5, -0.5, -0.5).tex(1, 1).endVertex(); - buffer.pos(0.5, 0.5, -0.5).tex(1, 0).endVertex(); + tessellator.addVertexWithUV(-0.5, 0.5, -0.5, 0, 0); + tessellator.addVertexWithUV(-0.5, -0.5, -0.5, 0, 1); + tessellator.addVertexWithUV(0.5, -0.5, -0.5, 1, 1); + tessellator.addVertexWithUV(0.5, 0.5, -0.5, 1, 0); tessellator.draw(); - GlStateManager.enableLighting(); - GlStateManager.disableBlend(); + GL11.glPopMatrix(); - GlStateManager.popMatrix(); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_BLEND); + + GL11.glPopMatrix(); } } private static void renderWingsIfActive(EntityPlayer entityplayer, float partialTickTime){ - ItemStack wand = entityplayer.getActiveItemStack(); - if(WizardData.get(entityplayer).currentlyCasting() instanceof Flight || (entityplayer.isHandActive() && wand != null + ItemStack wand = entityplayer.getHeldItem(); + if(ExtendedPlayer.get(entityplayer).currentlyCasting() instanceof Flight || (entityplayer.isUsingItem() && wand != null && wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand && WandHelper.getCurrentSpell(wand) instanceof Flight)){ - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - GlStateManager.disableLighting(); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); - //GlStateManager.rotate(-entityplayer.rotationYawHead, 0, 1, 0); - GlStateManager.rotate(-entityplayer.renderYawOffset, 0, 1, 0); - //GlStateManager.rotate(180, 1, 0, 0); + GL11.glRotatef(-entityplayer.rotationYawHead, 0, 1, 0); + GL11.glRotatef(entityplayer.rotationYaw, 0, 1, 0); + GL11.glRotatef(180, 1, 0, 0); Minecraft.getMinecraft().renderEngine.bindTexture(wingTexture); - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); + Tessellator tessellator = Tessellator.instance; - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); - GlStateManager.translate(0.1, 0.4, -0.15); - GlStateManager.rotate(20 + 20*(float)Math.sin(entityplayer.worldObj.getWorldTime()*0.3), 0, 1, 0); + GL11.glTranslated(0.1, -1.0, -0.15); + GL11.glRotatef(20 + 20*(float)Math.sin(entityplayer.worldObj.getWorldTime()*0.3), 0, 1, 0); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + tessellator.startDrawingQuads(); - buffer.pos(0, 2, 0).tex(0, 0).endVertex(); - buffer.pos(2, 2, 0).tex(1, 0).endVertex(); - buffer.pos(2, 0, 0).tex(1, 1).endVertex(); - buffer.pos(0, 0, 0).tex(0, 1).endVertex(); + tessellator.addVertexWithUV(0, 2, 0, 0, 0); + tessellator.addVertexWithUV(2, 2, 0, 1, 0); + tessellator.addVertexWithUV(2, 0, 0, 1, 1); + tessellator.addVertexWithUV(0, 0, 0, 0, 1); tessellator.draw(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + tessellator.startDrawingQuads(); - buffer.pos(0, 2, 0).tex(0, 0).endVertex(); - buffer.pos(0, 0, 0).tex(0, 1).endVertex(); - buffer.pos(2, 0, 0).tex(1, 1).endVertex(); - buffer.pos(2, 2, 0).tex(1, 0).endVertex(); + tessellator.addVertexWithUV(0, 2, 0, 0, 0); + tessellator.addVertexWithUV(0, 0, 0, 0, 1); + tessellator.addVertexWithUV(2, 0, 0, 1, 1); + tessellator.addVertexWithUV(2, 2, 0, 1, 0); tessellator.draw(); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); - GlStateManager.translate(-0.1, 0.4, -0.15); - GlStateManager.rotate(-200 - 20*(float)Math.sin(entityplayer.worldObj.getWorldTime()*0.3), 0, 1, 0); + GL11.glTranslated(-0.1, -1.0, -0.15); + GL11.glRotatef(-200 - 20*(float)Math.sin(entityplayer.worldObj.getWorldTime()*0.3), 0, 1, 0); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + tessellator.startDrawingQuads(); - buffer.pos(0, 2, 0).tex(0, 0).endVertex(); - buffer.pos(2, 2, 0).tex(1, 0).endVertex(); - buffer.pos(2, 0, 0).tex(1, 1).endVertex(); - buffer.pos(0, 0, 0).tex(0, 1).endVertex(); + tessellator.addVertexWithUV(0, 2, 0, 0, 0); + tessellator.addVertexWithUV(2, 2, 0, 1, 0); + tessellator.addVertexWithUV(2, 0, 0, 1, 1); + tessellator.addVertexWithUV(0, 0, 0, 0, 1); tessellator.draw(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + tessellator.startDrawingQuads(); - buffer.pos(0, 2, 0).tex(0, 0).endVertex(); - buffer.pos(0, 0, 0).tex(0, 1).endVertex(); - buffer.pos(2, 0, 0).tex(1, 1).endVertex(); - buffer.pos(2, 2, 0).tex(1, 0).endVertex(); + tessellator.addVertexWithUV(0, 2, 0, 0, 0); + tessellator.addVertexWithUV(0, 0, 0, 0, 1); + tessellator.addVertexWithUV(2, 0, 0, 1, 1); + tessellator.addVertexWithUV(2, 2, 0, 1, 0); tessellator.draw(); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); - GlStateManager.enableLighting(); - GlStateManager.disableBlend(); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_BLEND); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); } } private static void renderShieldFirstPerson(EntityPlayer entityplayer){ - ItemStack wand = entityplayer.getActiveItemStack(); - if(WizardData.get(entityplayer) != null && WizardData.get(entityplayer).shield != null && (WizardData.get(entityplayer).currentlyCasting() instanceof Shield || (entityplayer.isHandActive() && wand != null + ItemStack wand = entityplayer.getHeldItem(); + if(ExtendedPlayer.get(entityplayer).shield != null && (ExtendedPlayer.get(entityplayer).currentlyCasting() instanceof Shield || (entityplayer.isUsingItem() && wand != null && wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand && WandHelper.getCurrentSpell(wand) instanceof Shield))){ - GlStateManager.pushMatrix(); + double x = entityplayer.posX; + double y = entityplayer.posY; + double z = entityplayer.posZ; - GlStateManager.disableCull(); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_ONE, GL11.GL_SRC_ALPHA); - GlStateManager.shadeModel(GL11.GL_SMOOTH); - GlStateManager.disableLighting(); + EntityShield shield = (EntityShield)ExtendedPlayer.get(entityplayer).shield; + + GL11.glPushMatrix(); + + GL11.glDisable(GL11.GL_CULL_FACE); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_SRC_ALPHA); + GL11.glShadeModel(GL11.GL_SMOOTH); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); - GlStateManager.translate(0, 1.4, 0); + GL11.glTranslated(0, -0.3, 0); - GlStateManager.rotate(-entityplayer.rotationYaw, 0, 1, 0); - GlStateManager.rotate(entityplayer.rotationPitch, 1, 0, 0); + GL11.glRotatef(-1*entityplayer.rotationYaw, 0, 1, 0); + GL11.glRotatef(entityplayer.rotationPitch, 1, 0, 0); - GlStateManager.translate(0, 0, 0.8); + GL11.glTranslated(0, 0, 0.8); - Tessellator tessellator = Tessellator.getInstance(); + Tessellator tessellator = Tessellator.instance; Minecraft.getMinecraft().renderEngine.bindTexture(shieldTexture); - renderShield(tessellator); - - GlStateManager.enableLighting(); + renderShield(tessellator, -1); - GlStateManager.shadeModel(GL11.GL_FLAT); - GlStateManager.enableCull(); - GlStateManager.disableBlend(); + // Enchantment effect + /* + GL11.glPushMatrix(); + + GL11.glDisable(GL11.GL_LIGHTING); + //this.bindTexture(RES_ITEM_GLINT); + GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); + float f7 = 0.76F; + GL11.glColor4f(0.5F * f7, 0.25F * f7, 0.8F * f7, 1.0F); + float f8 = 0.125F; + //GL11.glScalef(f8, f8, f8); + float f9 = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F * 0.8f; + //GL11.glTranslatef(f9, 0.0F, 0.0F); + //GL11.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F); + + //this.renderShield(tessellator, f9); + + GL11.glPopMatrix(); + */ + GL11.glEnable(GL11.GL_LIGHTING); + + GL11.glShadeModel(GL11.GL_FLAT); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glDisable(GL11.GL_BLEND); //RenderHelper.enableStandardItemLighting(); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); } } private static void renderShieldIfActive(EntityPlayer entityplayer){ - ItemStack wand = entityplayer.getActiveItemStack(); - if(WizardData.get(entityplayer).shield != null && (WizardData.get(entityplayer).currentlyCasting() instanceof Shield || (entityplayer.isHandActive() && wand != null + ItemStack wand = entityplayer.getHeldItem(); + if(ExtendedPlayer.get(entityplayer).shield != null && (ExtendedPlayer.get(entityplayer).currentlyCasting() instanceof Shield || (entityplayer.isUsingItem() && wand != null && wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand && WandHelper.getCurrentSpell(wand) instanceof Shield))){ - GlStateManager.pushMatrix(); + double x = entityplayer.posX; + double y = entityplayer.posY; + double z = entityplayer.posZ; - GlStateManager.disableCull(); - GlStateManager.enableBlend(); - // For some reason, the old blend function (GL11.GL_SRC_ALPHA, GL11.GL_SRC_ALPHA) caused the inner - // edges to appear black, so I have changed it to this, which looks very slightly different. - GlStateManager.blendFunc(GL11.GL_ONE, GL11.GL_SRC_ALPHA); - GlStateManager.shadeModel(GL11.GL_SMOOTH); - GlStateManager.disableLighting(); + EntityShield shield = (EntityShield)ExtendedPlayer.get(entityplayer).shield; + + GL11.glPushMatrix(); + + GL11.glDisable(GL11.GL_CULL_FACE); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_SRC_ALPHA); + GL11.glShadeModel(GL11.GL_SMOOTH); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); - GlStateManager.translate(0, 1.3, 0); + GL11.glTranslated(0, 0, 0); - //GlStateManager.rotate(180, 0, 1, 0); - GlStateManager.rotate(-entityplayer.renderYawOffset, 0, 1, 0); - //GlStateManager.rotate(-entityplayer.rotationPitch, 1, 0, 0); + GL11.glRotatef(180, 0, 1, 0); + //GL11.glRotatef(entityplayer.rotationYaw, 0, 1, 0); + //GL11.glRotatef(-entityplayer.rotationPitch, 1, 0, 0); - GlStateManager.translate(0, 0, 0.8); + GL11.glTranslated(0, 0, 0.8); - Tessellator tessellator = Tessellator.getInstance(); + Tessellator tessellator = Tessellator.instance; Minecraft.getMinecraft().renderEngine.bindTexture(shieldTexture); - renderShield(tessellator); + renderShield(tessellator, -1); - GlStateManager.enableLighting(); + // Enchantment effect + /* + GL11.glPushMatrix(); - GlStateManager.shadeModel(GL11.GL_FLAT); - GlStateManager.enableCull(); - GlStateManager.disableBlend(); + GL11.glDisable(GL11.GL_LIGHTING); + //this.bindTexture(RES_ITEM_GLINT); + GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); + float f7 = 0.76F; + GL11.glColor4f(0.5F * f7, 0.25F * f7, 0.8F * f7, 1.0F); + float f8 = 0.125F; + //GL11.glScalef(f8, f8, f8); + float f9 = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F * 0.8f; + //GL11.glTranslatef(f9, 0.0F, 0.0F); + //GL11.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F); + + //this.renderShield(tessellator, f9); + + GL11.glPopMatrix(); + */ + GL11.glEnable(GL11.GL_LIGHTING); + + GL11.glShadeModel(GL11.GL_FLAT); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glDisable(GL11.GL_BLEND); //RenderHelper.enableStandardItemLighting(); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); } } - private static void renderShield(Tessellator tessellator){ - - VertexBuffer buffer = tessellator.getBuffer(); + private static void renderShield(Tessellator tessellator, float textureOffset){ double widthOuter = 0.6d; double heightOuter = 0.7d; @@ -712,39 +720,72 @@ public final class WizardryClientEventHandler { double heightInner = 0.4d; double depth = 0.2d; - buffer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_TEX_COLOR); + double textureSection = 1.0d; + double textureU = 0.0d; - buffer.pos(-widthOuter, heightInner, -depth).tex(0, 0.2).color(0, 0, 0, 255).endVertex(); - buffer.pos(-widthInner, heightInner, 0).tex(0.2, 0.2).color(200, 200, 255, 255).endVertex(); - buffer.pos(-widthInner, heightOuter, -depth).tex(0.2, 0).color(0, 0, 0, 255).endVertex(); - buffer.pos(-widthInner, heightInner, 0).tex(0.2, 0.2).color(200, 200, 255, 255).endVertex(); + if(textureOffset != -1){ + textureSection = 0.2d; + textureU = textureOffset; + } - buffer.pos(widthInner, heightOuter, -depth).tex(0.8, 0).color(0, 0, 0, 255).endVertex(); - buffer.pos(widthInner, heightInner, 0).tex(0.8, 0.2).color(200, 200, 255, 255).endVertex(); - buffer.pos(widthOuter, heightInner, -depth).tex(1, 0.2).color(0, 0, 0, 255).endVertex(); - buffer.pos(widthInner, heightInner, 0).tex(0.8, 0.2).color(200, 200, 255, 255).endVertex(); + tessellator.startDrawing(5); - buffer.pos(widthOuter, -heightInner, -depth).tex(1, 0.8).color(0, 0, 0, 255).endVertex(); - buffer.pos(widthInner, -heightInner, 0).tex(0.8, 0.8).color(200, 200, 255, 255).endVertex(); - buffer.pos(widthInner, -heightOuter, -depth).tex(0.8, 1).color(0, 0, 0, 255).endVertex(); - buffer.pos(widthInner, -heightInner, 0).tex(0.8, 0.8).color(200, 200, 255, 255).endVertex(); + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(-widthOuter, heightOuter - 0.3, -depth, 0, 0); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(-widthInner, heightInner, 0, textureU, 0.2); + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(-widthOuter + 0.3, heightOuter, -depth, 0, 0); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(-widthInner, heightInner, 0, textureU, 0.2); - buffer.pos(-widthInner, -heightOuter, -depth).tex(0.2, 1).color(0, 0, 0, 255).endVertex(); - buffer.pos(-widthInner, -heightInner, 0).tex(0.2, 0.8).color(200, 200, 255, 255).endVertex(); - buffer.pos(-widthOuter, -heightInner, -depth).tex(0, 0.8).color(0, 0, 0, 255).endVertex(); - buffer.pos(-widthInner, -heightInner, 0).tex(0.2, 0.8).color(200, 200, 255, 255).endVertex(); + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(widthOuter - 0.3, heightOuter, -depth, 1, 0); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(widthInner, heightInner, 0, textureU + textureSection, 0.2); + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(widthOuter, heightOuter - 0.3, -depth, 1, 0); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(widthInner, heightInner, 0, textureU + textureSection, 0.2); - buffer.pos(-widthOuter, heightInner, -depth).tex(0, 0.2).color(0, 0, 0, 255).endVertex(); - buffer.pos(-widthInner, heightInner, 0).tex(0.2, 0.2).color(200, 200, 255, 255).endVertex(); + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(widthOuter, -heightOuter + 0.3, -depth, 1, 1); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(widthInner, -heightInner, 0, textureU + textureSection, 0.8); + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(widthOuter - 0.3, -heightOuter, -depth, 1, 1); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(widthInner, -heightInner, 0, textureU + textureSection, 0.8); + + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(-widthOuter + 0.3, -heightOuter, -depth, 0, 1); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(-widthInner, -heightInner, 0, textureU, 0.8); + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(-widthOuter, -heightOuter + 0.3, -depth, 0, 1); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(-widthInner, -heightInner, 0, textureU, 0.8); + + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(-widthOuter, heightOuter - 0.3, -depth, 0, 0); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(-widthInner, heightInner, 0, textureU, 0.2); tessellator.draw(); - buffer.begin(GL11.GL_TRIANGLE_STRIP, DefaultVertexFormats.POSITION_TEX_COLOR); + tessellator.startDrawing(5); - buffer.pos(-widthInner, heightInner, 0).tex(0.2, 0.2).color(200, 200, 255, 255).endVertex(); - buffer.pos(widthInner, heightInner, 0).tex(0.8, 0.2).color(200, 200, 255, 255).endVertex(); - buffer.pos(-widthInner, -heightInner, 0).tex(0.2, 0.8).color(200, 200, 255, 255).endVertex(); - buffer.pos(widthInner, -heightInner, 0).tex(0.8, 0.8).color(200, 200, 255, 255).endVertex(); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(-widthInner, heightInner, 0, textureU, 0.2); + + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(widthInner, heightInner, 0, textureU + textureSection, 0.2); + + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(-widthInner, -heightInner, 0, textureU, 0.8); + + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(widthInner, -heightInner, 0, textureU + textureSection, 0.8); tessellator.draw(); } diff --git a/src/main/java/electroblob/wizardry/client/model/ModelIceGiant.java b/src/main/java/electroblob/wizardry/client/model/ModelIceGiant.java index 4a8591d7..d77809c5 100644 --- a/src/main/java/electroblob/wizardry/client/model/ModelIceGiant.java +++ b/src/main/java/electroblob/wizardry/client/model/ModelIceGiant.java @@ -3,14 +3,14 @@ package electroblob.wizardry.client.model; import javax.vecmath.Matrix4f; import javax.vecmath.Vector3f; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import electroblob.wizardry.entity.living.EntityIceGiant; import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelRenderer; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.math.MathHelper; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraft.util.MathHelper; @SideOnly(Side.CLIENT) public class ModelIceGiant extends ModelBase diff --git a/src/main/java/electroblob/wizardry/client/model/ModelPhoenix.java b/src/main/java/electroblob/wizardry/client/model/ModelPhoenix.java index 568b580c..ac472271 100644 --- a/src/main/java/electroblob/wizardry/client/model/ModelPhoenix.java +++ b/src/main/java/electroblob/wizardry/client/model/ModelPhoenix.java @@ -3,7 +3,7 @@ package electroblob.wizardry.client.model; import net.minecraft.client.model.ModelBase; import net.minecraft.client.model.ModelRenderer; import net.minecraft.entity.Entity; -import net.minecraft.util.math.MathHelper; +import net.minecraft.util.MathHelper; public class ModelPhoenix extends ModelBase { @@ -109,7 +109,7 @@ public class ModelPhoenix extends ModelBase { super.render(entity, f, f1, f2, f3, f4, f5); setRotationAngles(f, f1, f2, f3, f4, f5, entity); - //float f6 = (180F / (float)Math.PI); + float f6 = (180F / (float)Math.PI); this.neck.rotateAngleX = f4 / (180F / (float)Math.PI); this.neck.rotateAngleY = f3 / (180F / (float)Math.PI); this.neck.rotateAngleZ = 0.0F; diff --git a/src/main/java/electroblob/wizardry/client/model/ModelSkeletonMinion.java b/src/main/java/electroblob/wizardry/client/model/ModelSkeletonMinion.java new file mode 100644 index 00000000..65ee1b01 --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/model/ModelSkeletonMinion.java @@ -0,0 +1,58 @@ +package electroblob.wizardry.client.model; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.entity.living.EntitySkeletonMinion; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.client.model.ModelZombie; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntitySkeleton; + +@SideOnly(Side.CLIENT) +public class ModelSkeletonMinion extends ModelZombie +{ + public ModelSkeletonMinion() + { + this(0.0F); + } + + public ModelSkeletonMinion(float par1) + { + super(par1, 0.0F, 64, 32); + this.bipedRightArm = new ModelRenderer(this, 40, 16); + this.bipedRightArm.addBox(-1.0F, -2.0F, -1.0F, 2, 12, 2, par1); + this.bipedRightArm.setRotationPoint(-5.0F, 2.0F, 0.0F); + this.bipedLeftArm = new ModelRenderer(this, 40, 16); + this.bipedLeftArm.mirror = true; + this.bipedLeftArm.addBox(-1.0F, -2.0F, -1.0F, 2, 12, 2, par1); + this.bipedLeftArm.setRotationPoint(5.0F, 2.0F, 0.0F); + this.bipedRightLeg = new ModelRenderer(this, 0, 16); + this.bipedRightLeg.addBox(-1.0F, 0.0F, -1.0F, 2, 12, 2, par1); + this.bipedRightLeg.setRotationPoint(-2.0F, 12.0F, 0.0F); + this.bipedLeftLeg = new ModelRenderer(this, 0, 16); + this.bipedLeftLeg.mirror = true; + this.bipedLeftLeg.addBox(-1.0F, 0.0F, -1.0F, 2, 12, 2, par1); + this.bipedLeftLeg.setRotationPoint(2.0F, 12.0F, 0.0F); + } + + /** + * Used for easily adding entity-dependent animations. The second and third float params here are the same second + * and third as in the setRotationAngles method. + */ + public void setLivingAnimations(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4) + { + this.aimedBow = ((EntitySkeletonMinion)par1EntityLivingBase).getSkeletonType() == 1; + super.setLivingAnimations(par1EntityLivingBase, par2, par3, par4); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms + * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) + { + super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); + } +} diff --git a/src/main/java/electroblob/wizardry/client/model/ModelSpiritHorse.java b/src/main/java/electroblob/wizardry/client/model/ModelSpiritHorse.java new file mode 100644 index 00000000..07c08c7d --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/model/ModelSpiritHorse.java @@ -0,0 +1,559 @@ +package electroblob.wizardry.client.model; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.entity.living.EntitySpiritHorse; +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.MathHelper; + +@SideOnly(Side.CLIENT) +public class ModelSpiritHorse extends ModelBase +{ + private ModelRenderer head; + private ModelRenderer mouthTop; + private ModelRenderer mouthBottom; + private ModelRenderer horseLeftEar; + private ModelRenderer horseRightEar; + private ModelRenderer field_110703_f; + private ModelRenderer field_110704_g; + private ModelRenderer neck; + private ModelRenderer field_110717_i; + private ModelRenderer mane; + private ModelRenderer body; + private ModelRenderer tailBase; + private ModelRenderer tailMiddle; + private ModelRenderer tailTip; + private ModelRenderer backLeftLeg; + private ModelRenderer backLeftShin; + private ModelRenderer backLeftHoof; + private ModelRenderer backRightLeg; + private ModelRenderer backRightShin; + private ModelRenderer backRightHoof; + private ModelRenderer frontRightLeg; + private ModelRenderer frontLeftShin; + private ModelRenderer frontLeftHoof; + private ModelRenderer field_110684_D; + private ModelRenderer frontRightShin; + private ModelRenderer frontRightHoof; + private ModelRenderer field_110687_G; + private ModelRenderer field_110695_H; + private ModelRenderer field_110696_I; + private ModelRenderer field_110697_J; + private ModelRenderer field_110698_K; + private ModelRenderer field_110691_L; + private ModelRenderer field_110692_M; + private ModelRenderer field_110693_N; + private ModelRenderer field_110694_O; + private ModelRenderer field_110700_P; + private ModelRenderer field_110699_Q; + private ModelRenderer field_110702_R; + private ModelRenderer field_110701_S; + + public ModelSpiritHorse() + { + this.textureWidth = 128; + this.textureHeight = 128; + this.body = new ModelRenderer(this, 0, 34); + this.body.addBox(-5.0F, -8.0F, -19.0F, 10, 10, 24); + this.body.setRotationPoint(0.0F, 11.0F, 9.0F); + this.tailBase = new ModelRenderer(this, 44, 0); + this.tailBase.addBox(-1.0F, -1.0F, 0.0F, 2, 2, 3); + this.tailBase.setRotationPoint(0.0F, 3.0F, 14.0F); + this.func_110682_a(this.tailBase, -1.134464F, 0.0F, 0.0F); + this.tailMiddle = new ModelRenderer(this, 38, 7); + this.tailMiddle.addBox(-1.5F, -2.0F, 3.0F, 3, 4, 7); + this.tailMiddle.setRotationPoint(0.0F, 3.0F, 14.0F); + this.func_110682_a(this.tailMiddle, -1.134464F, 0.0F, 0.0F); + this.tailTip = new ModelRenderer(this, 24, 3); + this.tailTip.addBox(-1.5F, -4.5F, 9.0F, 3, 4, 7); + this.tailTip.setRotationPoint(0.0F, 3.0F, 14.0F); + this.func_110682_a(this.tailTip, -1.40215F, 0.0F, 0.0F); + this.backLeftLeg = new ModelRenderer(this, 78, 29); + this.backLeftLeg.addBox(-2.5F, -2.0F, -2.5F, 4, 9, 5); + this.backLeftLeg.setRotationPoint(4.0F, 9.0F, 11.0F); + this.backLeftShin = new ModelRenderer(this, 78, 43); + this.backLeftShin.addBox(-2.0F, 0.0F, -1.5F, 3, 5, 3); + this.backLeftShin.setRotationPoint(4.0F, 16.0F, 11.0F); + this.backLeftHoof = new ModelRenderer(this, 78, 51); + this.backLeftHoof.addBox(-2.5F, 5.1F, -2.0F, 4, 3, 4); + this.backLeftHoof.setRotationPoint(4.0F, 16.0F, 11.0F); + this.backRightLeg = new ModelRenderer(this, 96, 29); + this.backRightLeg.addBox(-1.5F, -2.0F, -2.5F, 4, 9, 5); + this.backRightLeg.setRotationPoint(-4.0F, 9.0F, 11.0F); + this.backRightShin = new ModelRenderer(this, 96, 43); + this.backRightShin.addBox(-1.0F, 0.0F, -1.5F, 3, 5, 3); + this.backRightShin.setRotationPoint(-4.0F, 16.0F, 11.0F); + this.backRightHoof = new ModelRenderer(this, 96, 51); + this.backRightHoof.addBox(-1.5F, 5.1F, -2.0F, 4, 3, 4); + this.backRightHoof.setRotationPoint(-4.0F, 16.0F, 11.0F); + this.frontRightLeg = new ModelRenderer(this, 44, 29); + this.frontRightLeg.addBox(-1.9F, -1.0F, -2.1F, 3, 8, 4); + this.frontRightLeg.setRotationPoint(4.0F, 9.0F, -8.0F); + this.frontLeftShin = new ModelRenderer(this, 44, 41); + this.frontLeftShin.addBox(-1.9F, 0.0F, -1.6F, 3, 5, 3); + this.frontLeftShin.setRotationPoint(4.0F, 16.0F, -8.0F); + this.frontLeftHoof = new ModelRenderer(this, 44, 51); + this.frontLeftHoof.addBox(-2.4F, 5.1F, -2.1F, 4, 3, 4); + this.frontLeftHoof.setRotationPoint(4.0F, 16.0F, -8.0F); + this.field_110684_D = new ModelRenderer(this, 60, 29); + this.field_110684_D.addBox(-1.1F, -1.0F, -2.1F, 3, 8, 4); + this.field_110684_D.setRotationPoint(-4.0F, 9.0F, -8.0F); + this.frontRightShin = new ModelRenderer(this, 60, 41); + this.frontRightShin.addBox(-1.1F, 0.0F, -1.6F, 3, 5, 3); + this.frontRightShin.setRotationPoint(-4.0F, 16.0F, -8.0F); + this.frontRightHoof = new ModelRenderer(this, 60, 51); + this.frontRightHoof.addBox(-1.6F, 5.1F, -2.1F, 4, 3, 4); + this.frontRightHoof.setRotationPoint(-4.0F, 16.0F, -8.0F); + this.head = new ModelRenderer(this, 0, 0); + this.head.addBox(-2.5F, -10.0F, -1.5F, 5, 5, 7); + this.head.setRotationPoint(0.0F, 4.0F, -10.0F); + this.func_110682_a(this.head, 0.5235988F, 0.0F, 0.0F); + this.mouthTop = new ModelRenderer(this, 24, 18); + this.mouthTop.addBox(-2.0F, -10.0F, -7.0F, 4, 3, 6); + this.mouthTop.setRotationPoint(0.0F, 3.95F, -10.0F); + this.func_110682_a(this.mouthTop, 0.5235988F, 0.0F, 0.0F); + this.mouthBottom = new ModelRenderer(this, 24, 27); + this.mouthBottom.addBox(-2.0F, -7.0F, -6.5F, 4, 2, 5); + this.mouthBottom.setRotationPoint(0.0F, 4.0F, -10.0F); + this.func_110682_a(this.mouthBottom, 0.5235988F, 0.0F, 0.0F); + this.head.addChild(this.mouthTop); + this.head.addChild(this.mouthBottom); + this.horseLeftEar = new ModelRenderer(this, 0, 0); + this.horseLeftEar.addBox(0.45F, -12.0F, 4.0F, 2, 3, 1); + this.horseLeftEar.setRotationPoint(0.0F, 4.0F, -10.0F); + this.func_110682_a(this.horseLeftEar, 0.5235988F, 0.0F, 0.0F); + this.horseRightEar = new ModelRenderer(this, 0, 0); + this.horseRightEar.addBox(-2.45F, -12.0F, 4.0F, 2, 3, 1); + this.horseRightEar.setRotationPoint(0.0F, 4.0F, -10.0F); + this.func_110682_a(this.horseRightEar, 0.5235988F, 0.0F, 0.0F); + this.field_110703_f = new ModelRenderer(this, 0, 12); + this.field_110703_f.addBox(-2.0F, -16.0F, 4.0F, 2, 7, 1); + this.field_110703_f.setRotationPoint(0.0F, 4.0F, -10.0F); + this.func_110682_a(this.field_110703_f, 0.5235988F, 0.0F, 0.2617994F); + this.field_110704_g = new ModelRenderer(this, 0, 12); + this.field_110704_g.addBox(0.0F, -16.0F, 4.0F, 2, 7, 1); + this.field_110704_g.setRotationPoint(0.0F, 4.0F, -10.0F); + this.func_110682_a(this.field_110704_g, 0.5235988F, 0.0F, -0.2617994F); + this.neck = new ModelRenderer(this, 0, 12); + this.neck.addBox(-2.05F, -9.8F, -2.0F, 4, 14, 8); + this.neck.setRotationPoint(0.0F, 4.0F, -10.0F); + this.func_110682_a(this.neck, 0.5235988F, 0.0F, 0.0F); + this.field_110687_G = new ModelRenderer(this, 0, 34); + this.field_110687_G.addBox(-3.0F, 0.0F, 0.0F, 8, 8, 3); + this.field_110687_G.setRotationPoint(-7.5F, 3.0F, 10.0F); + this.func_110682_a(this.field_110687_G, 0.0F, ((float)Math.PI / 2F), 0.0F); + this.field_110695_H = new ModelRenderer(this, 0, 47); + this.field_110695_H.addBox(-3.0F, 0.0F, 0.0F, 8, 8, 3); + this.field_110695_H.setRotationPoint(4.5F, 3.0F, 10.0F); + this.func_110682_a(this.field_110695_H, 0.0F, ((float)Math.PI / 2F), 0.0F); + this.field_110696_I = new ModelRenderer(this, 80, 0); + this.field_110696_I.addBox(-5.0F, 0.0F, -3.0F, 10, 1, 8); + this.field_110696_I.setRotationPoint(0.0F, 2.0F, 2.0F); + this.field_110697_J = new ModelRenderer(this, 106, 9); + this.field_110697_J.addBox(-1.5F, -1.0F, -3.0F, 3, 1, 2); + this.field_110697_J.setRotationPoint(0.0F, 2.0F, 2.0F); + this.field_110698_K = new ModelRenderer(this, 80, 9); + this.field_110698_K.addBox(-4.0F, -1.0F, 3.0F, 8, 1, 2); + this.field_110698_K.setRotationPoint(0.0F, 2.0F, 2.0F); + this.field_110692_M = new ModelRenderer(this, 74, 0); + this.field_110692_M.addBox(-0.5F, 6.0F, -1.0F, 1, 2, 2); + this.field_110692_M.setRotationPoint(5.0F, 3.0F, 2.0F); + this.field_110691_L = new ModelRenderer(this, 70, 0); + this.field_110691_L.addBox(-0.5F, 0.0F, -0.5F, 1, 6, 1); + this.field_110691_L.setRotationPoint(5.0F, 3.0F, 2.0F); + this.field_110694_O = new ModelRenderer(this, 74, 4); + this.field_110694_O.addBox(-0.5F, 6.0F, -1.0F, 1, 2, 2); + this.field_110694_O.setRotationPoint(-5.0F, 3.0F, 2.0F); + this.field_110693_N = new ModelRenderer(this, 80, 0); + this.field_110693_N.addBox(-0.5F, 0.0F, -0.5F, 1, 6, 1); + this.field_110693_N.setRotationPoint(-5.0F, 3.0F, 2.0F); + this.field_110700_P = new ModelRenderer(this, 74, 13); + this.field_110700_P.addBox(1.5F, -8.0F, -4.0F, 1, 2, 2); + this.field_110700_P.setRotationPoint(0.0F, 4.0F, -10.0F); + this.func_110682_a(this.field_110700_P, 0.5235988F, 0.0F, 0.0F); + this.field_110699_Q = new ModelRenderer(this, 74, 13); + this.field_110699_Q.addBox(-2.5F, -8.0F, -4.0F, 1, 2, 2); + this.field_110699_Q.setRotationPoint(0.0F, 4.0F, -10.0F); + this.func_110682_a(this.field_110699_Q, 0.5235988F, 0.0F, 0.0F); + this.field_110702_R = new ModelRenderer(this, 44, 10); + this.field_110702_R.addBox(2.6F, -6.0F, -6.0F, 0, 3, 16); + this.field_110702_R.setRotationPoint(0.0F, 4.0F, -10.0F); + this.field_110701_S = new ModelRenderer(this, 44, 5); + this.field_110701_S.addBox(-2.6F, -6.0F, -6.0F, 0, 3, 16); + this.field_110701_S.setRotationPoint(0.0F, 4.0F, -10.0F); + this.mane = new ModelRenderer(this, 58, 0); + this.mane.addBox(-1.0F, -11.5F, 5.0F, 2, 16, 4); + this.mane.setRotationPoint(0.0F, 4.0F, -10.0F); + this.func_110682_a(this.mane, 0.5235988F, 0.0F, 0.0F); + this.field_110717_i = new ModelRenderer(this, 80, 12); + this.field_110717_i.addBox(-2.5F, -10.1F, -7.0F, 5, 5, 12, 0.2F); + this.field_110717_i.setRotationPoint(0.0F, 4.0F, -10.0F); + this.func_110682_a(this.field_110717_i, 0.5235988F, 0.0F, 0.0F); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) + { + EntitySpiritHorse entityhorse = (EntitySpiritHorse)par1Entity; + int i = entityhorse.getHorseType(); + float f6 = entityhorse.getGrassEatingAmount(0.0F); + boolean flag = entityhorse.isAdultHorse(); + boolean flag1 = flag && entityhorse.isHorseSaddled(); + boolean flag2 = flag && entityhorse.isChested(); + boolean flag3 = i == 1 || i == 2; + float f7 = entityhorse.getHorseSize(); + boolean flag4 = entityhorse.riddenByEntity != null; + + if (flag1) + { + this.field_110717_i.render(par7); + this.field_110696_I.render(par7); + this.field_110697_J.render(par7); + this.field_110698_K.render(par7); + this.field_110691_L.render(par7); + this.field_110692_M.render(par7); + this.field_110693_N.render(par7); + this.field_110694_O.render(par7); + this.field_110700_P.render(par7); + this.field_110699_Q.render(par7); + + if (flag4) + { + this.field_110702_R.render(par7); + this.field_110701_S.render(par7); + } + } + + if (!flag) + { + GL11.glPushMatrix(); + GL11.glScalef(f7, 0.5F + f7 * 0.5F, f7); + GL11.glTranslatef(0.0F, 0.95F * (1.0F - f7), 0.0F); + } + + this.backLeftLeg.render(par7); + this.backLeftShin.render(par7); + this.backLeftHoof.render(par7); + this.backRightLeg.render(par7); + this.backRightShin.render(par7); + this.backRightHoof.render(par7); + this.frontRightLeg.render(par7); + this.frontLeftShin.render(par7); + this.frontLeftHoof.render(par7); + this.field_110684_D.render(par7); + this.frontRightShin.render(par7); + this.frontRightHoof.render(par7); + + if (!flag) + { + GL11.glPopMatrix(); + GL11.glPushMatrix(); + GL11.glScalef(f7, f7, f7); + GL11.glTranslatef(0.0F, 1.35F * (1.0F - f7), 0.0F); + } + + this.body.render(par7); + this.tailBase.render(par7); + this.tailMiddle.render(par7); + this.tailTip.render(par7); + this.neck.render(par7); + this.mane.render(par7); + + if (!flag) + { + GL11.glPopMatrix(); + GL11.glPushMatrix(); + float f8 = 0.5F + f7 * f7 * 0.5F; + GL11.glScalef(f8, f8, f8); + + if (f6 <= 0.0F) + { + GL11.glTranslatef(0.0F, 1.35F * (1.0F - f7), 0.0F); + } + else + { + GL11.glTranslatef(0.0F, 0.9F * (1.0F - f7) * f6 + 1.35F * (1.0F - f7) * (1.0F - f6), 0.15F * (1.0F - f7) * f6); + } + } + + if (flag3) + { + this.field_110703_f.render(par7); + this.field_110704_g.render(par7); + } + else + { + this.horseLeftEar.render(par7); + this.horseRightEar.render(par7); + } + + this.head.render(par7); + + if (!flag) + { + GL11.glPopMatrix(); + } + + if (flag2) + { + this.field_110687_G.render(par7); + this.field_110695_H.render(par7); + } + } + + private void func_110682_a(ModelRenderer par1ModelRenderer, float par2, float par3, float par4) + { + par1ModelRenderer.rotateAngleX = par2; + par1ModelRenderer.rotateAngleY = par3; + par1ModelRenderer.rotateAngleZ = par4; + } + + private float func_110683_a(float par1, float par2, float par3) + { + float f3; + + for (f3 = par2 - par1; f3 < -180.0F; f3 += 360.0F) + { + ; + } + + while (f3 >= 180.0F) + { + f3 -= 360.0F; + } + + return par1 + par3 * f3; + } + + /** + * Used for easily adding entity-dependent animations. The second and third float params here are the same second + * and third as in the setRotationAngles method. + */ + public void setLivingAnimations(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4) + { + super.setLivingAnimations(par1EntityLivingBase, par2, par3, par4); + float f3 = this.func_110683_a(par1EntityLivingBase.prevRenderYawOffset, par1EntityLivingBase.renderYawOffset, par4); + float f4 = this.func_110683_a(par1EntityLivingBase.prevRotationYawHead, par1EntityLivingBase.rotationYawHead, par4); + float f5 = par1EntityLivingBase.prevRotationPitch + (par1EntityLivingBase.rotationPitch - par1EntityLivingBase.prevRotationPitch) * par4; + float f6 = f4 - f3; + float f7 = f5 / (180F / (float)Math.PI); + + if (f6 > 20.0F) + { + f6 = 20.0F; + } + + if (f6 < -20.0F) + { + f6 = -20.0F; + } + + if (par3 > 0.2F) + { + f7 += MathHelper.cos(par2 * 0.4F) * 0.15F * par3; + } + + EntitySpiritHorse entityhorse = (EntitySpiritHorse)par1EntityLivingBase; + float f8 = entityhorse.getGrassEatingAmount(par4); + float f9 = entityhorse.getRearingAmount(par4); + float f10 = 1.0F - f9; + float f11 = entityhorse.func_110201_q(par4); + boolean flag = entityhorse.field_110278_bp != 0; + boolean flag1 = entityhorse.isHorseSaddled(); + boolean flag2 = entityhorse.riddenByEntity != null; + float f12 = (float)par1EntityLivingBase.ticksExisted + par4; + float f13 = MathHelper.cos(par2 * 0.6662F + (float)Math.PI); + float f14 = f13 * 0.8F * par3; + this.head.rotationPointY = 4.0F; + this.head.rotationPointZ = -10.0F; + this.tailBase.rotationPointY = 3.0F; + this.tailMiddle.rotationPointZ = 14.0F; + this.field_110695_H.rotationPointY = 3.0F; + this.field_110695_H.rotationPointZ = 10.0F; + this.body.rotateAngleX = 0.0F; + this.head.rotateAngleX = 0.5235988F + f7; + this.head.rotateAngleY = f6 / (180F / (float)Math.PI); + this.head.rotateAngleX = f9 * (0.2617994F + f7) + f8 * 2.18166F + (1.0F - Math.max(f9, f8)) * this.head.rotateAngleX; + this.head.rotateAngleY = f9 * (f6 / (180F / (float)Math.PI)) + (1.0F - Math.max(f9, f8)) * this.head.rotateAngleY; + this.head.rotationPointY = f9 * -6.0F + f8 * 11.0F + (1.0F - Math.max(f9, f8)) * this.head.rotationPointY; + this.head.rotationPointZ = f9 * -1.0F + f8 * -10.0F + (1.0F - Math.max(f9, f8)) * this.head.rotationPointZ; + this.tailBase.rotationPointY = f9 * 9.0F + f10 * this.tailBase.rotationPointY; + this.tailMiddle.rotationPointZ = f9 * 18.0F + f10 * this.tailMiddle.rotationPointZ; + this.field_110695_H.rotationPointY = f9 * 5.5F + f10 * this.field_110695_H.rotationPointY; + this.field_110695_H.rotationPointZ = f9 * 15.0F + f10 * this.field_110695_H.rotationPointZ; + this.body.rotateAngleX = f9 * -((float)Math.PI / 4F) + f10 * this.body.rotateAngleX; + this.horseLeftEar.rotationPointY = this.head.rotationPointY; + this.horseRightEar.rotationPointY = this.head.rotationPointY; + this.field_110703_f.rotationPointY = this.head.rotationPointY; + this.field_110704_g.rotationPointY = this.head.rotationPointY; + this.neck.rotationPointY = this.head.rotationPointY; + this.mouthTop.rotationPointY = 0.02F; + this.mouthBottom.rotationPointY = 0.0F; + this.mane.rotationPointY = this.head.rotationPointY; + this.horseLeftEar.rotationPointZ = this.head.rotationPointZ; + this.horseRightEar.rotationPointZ = this.head.rotationPointZ; + this.field_110703_f.rotationPointZ = this.head.rotationPointZ; + this.field_110704_g.rotationPointZ = this.head.rotationPointZ; + this.neck.rotationPointZ = this.head.rotationPointZ; + this.mouthTop.rotationPointZ = 0.02F - f11 * 1.0F; + this.mouthBottom.rotationPointZ = 0.0F + f11 * 1.0F; + this.mane.rotationPointZ = this.head.rotationPointZ; + this.horseLeftEar.rotateAngleX = this.head.rotateAngleX; + this.horseRightEar.rotateAngleX = this.head.rotateAngleX; + this.field_110703_f.rotateAngleX = this.head.rotateAngleX; + this.field_110704_g.rotateAngleX = this.head.rotateAngleX; + this.neck.rotateAngleX = this.head.rotateAngleX; + this.mouthTop.rotateAngleX = 0.0F - 0.09424778F * f11; + this.mouthBottom.rotateAngleX = 0.0F + 0.15707964F * f11; + this.mane.rotateAngleX = this.head.rotateAngleX; + this.horseLeftEar.rotateAngleY = this.head.rotateAngleY; + this.horseRightEar.rotateAngleY = this.head.rotateAngleY; + this.field_110703_f.rotateAngleY = this.head.rotateAngleY; + this.field_110704_g.rotateAngleY = this.head.rotateAngleY; + this.neck.rotateAngleY = this.head.rotateAngleY; + this.mouthTop.rotateAngleY = 0.0F; + this.mouthBottom.rotateAngleY = 0.0F; + this.mane.rotateAngleY = this.head.rotateAngleY; + this.field_110687_G.rotateAngleX = f14 / 5.0F; + this.field_110695_H.rotateAngleX = -f14 / 5.0F; + float f15 = ((float)Math.PI / 2F); + float f16 = ((float)Math.PI * 3F / 2F); + float f17 = -1.0471976F; + float f18 = 0.2617994F * f9; + float f19 = MathHelper.cos(f12 * 0.6F + (float)Math.PI); + this.frontRightLeg.rotationPointY = -2.0F * f9 + 9.0F * f10; + this.frontRightLeg.rotationPointZ = -2.0F * f9 + -8.0F * f10; + this.field_110684_D.rotationPointY = this.frontRightLeg.rotationPointY; + this.field_110684_D.rotationPointZ = this.frontRightLeg.rotationPointZ; + this.backLeftShin.rotationPointY = this.backLeftLeg.rotationPointY + MathHelper.sin(((float)Math.PI / 2F) + f18 + f10 * -f13 * 0.5F * par3) * 7.0F; + this.backLeftShin.rotationPointZ = this.backLeftLeg.rotationPointZ + MathHelper.cos(((float)Math.PI * 3F / 2F) + f18 + f10 * -f13 * 0.5F * par3) * 7.0F; + this.backRightShin.rotationPointY = this.backRightLeg.rotationPointY + MathHelper.sin(((float)Math.PI / 2F) + f18 + f10 * f13 * 0.5F * par3) * 7.0F; + this.backRightShin.rotationPointZ = this.backRightLeg.rotationPointZ + MathHelper.cos(((float)Math.PI * 3F / 2F) + f18 + f10 * f13 * 0.5F * par3) * 7.0F; + float f20 = (-1.0471976F + f19) * f9 + f14 * f10; + float f21 = (-1.0471976F + -f19) * f9 + -f14 * f10; + this.frontLeftShin.rotationPointY = this.frontRightLeg.rotationPointY + MathHelper.sin(((float)Math.PI / 2F) + f20) * 7.0F; + this.frontLeftShin.rotationPointZ = this.frontRightLeg.rotationPointZ + MathHelper.cos(((float)Math.PI * 3F / 2F) + f20) * 7.0F; + this.frontRightShin.rotationPointY = this.field_110684_D.rotationPointY + MathHelper.sin(((float)Math.PI / 2F) + f21) * 7.0F; + this.frontRightShin.rotationPointZ = this.field_110684_D.rotationPointZ + MathHelper.cos(((float)Math.PI * 3F / 2F) + f21) * 7.0F; + this.backLeftLeg.rotateAngleX = f18 + -f13 * 0.5F * par3 * f10; + this.backLeftShin.rotateAngleX = -0.08726646F * f9 + (-f13 * 0.5F * par3 - Math.max(0.0F, f13 * 0.5F * par3)) * f10; + this.backLeftHoof.rotateAngleX = this.backLeftShin.rotateAngleX; + this.backRightLeg.rotateAngleX = f18 + f13 * 0.5F * par3 * f10; + this.backRightShin.rotateAngleX = -0.08726646F * f9 + (f13 * 0.5F * par3 - Math.max(0.0F, -f13 * 0.5F * par3)) * f10; + this.backRightHoof.rotateAngleX = this.backRightShin.rotateAngleX; + this.frontRightLeg.rotateAngleX = f20; + this.frontLeftShin.rotateAngleX = (this.frontRightLeg.rotateAngleX + (float)Math.PI * Math.max(0.0F, 0.2F + f19 * 0.2F)) * f9 + (f14 + Math.max(0.0F, f13 * 0.5F * par3)) * f10; + this.frontLeftHoof.rotateAngleX = this.frontLeftShin.rotateAngleX; + this.field_110684_D.rotateAngleX = f21; + this.frontRightShin.rotateAngleX = (this.field_110684_D.rotateAngleX + (float)Math.PI * Math.max(0.0F, 0.2F - f19 * 0.2F)) * f9 + (-f14 + Math.max(0.0F, -f13 * 0.5F * par3)) * f10; + this.frontRightHoof.rotateAngleX = this.frontRightShin.rotateAngleX; + this.backLeftHoof.rotationPointY = this.backLeftShin.rotationPointY; + this.backLeftHoof.rotationPointZ = this.backLeftShin.rotationPointZ; + this.backRightHoof.rotationPointY = this.backRightShin.rotationPointY; + this.backRightHoof.rotationPointZ = this.backRightShin.rotationPointZ; + this.frontLeftHoof.rotationPointY = this.frontLeftShin.rotationPointY; + this.frontLeftHoof.rotationPointZ = this.frontLeftShin.rotationPointZ; + this.frontRightHoof.rotationPointY = this.frontRightShin.rotationPointY; + this.frontRightHoof.rotationPointZ = this.frontRightShin.rotationPointZ; + + if (flag1) + { + this.field_110696_I.rotationPointY = f9 * 0.5F + f10 * 2.0F; + this.field_110696_I.rotationPointZ = f9 * 11.0F + f10 * 2.0F; + this.field_110697_J.rotationPointY = this.field_110696_I.rotationPointY; + this.field_110698_K.rotationPointY = this.field_110696_I.rotationPointY; + this.field_110691_L.rotationPointY = this.field_110696_I.rotationPointY; + this.field_110693_N.rotationPointY = this.field_110696_I.rotationPointY; + this.field_110692_M.rotationPointY = this.field_110696_I.rotationPointY; + this.field_110694_O.rotationPointY = this.field_110696_I.rotationPointY; + this.field_110687_G.rotationPointY = this.field_110695_H.rotationPointY; + this.field_110697_J.rotationPointZ = this.field_110696_I.rotationPointZ; + this.field_110698_K.rotationPointZ = this.field_110696_I.rotationPointZ; + this.field_110691_L.rotationPointZ = this.field_110696_I.rotationPointZ; + this.field_110693_N.rotationPointZ = this.field_110696_I.rotationPointZ; + this.field_110692_M.rotationPointZ = this.field_110696_I.rotationPointZ; + this.field_110694_O.rotationPointZ = this.field_110696_I.rotationPointZ; + this.field_110687_G.rotationPointZ = this.field_110695_H.rotationPointZ; + this.field_110696_I.rotateAngleX = this.body.rotateAngleX; + this.field_110697_J.rotateAngleX = this.body.rotateAngleX; + this.field_110698_K.rotateAngleX = this.body.rotateAngleX; + this.field_110702_R.rotationPointY = this.head.rotationPointY; + this.field_110701_S.rotationPointY = this.head.rotationPointY; + this.field_110717_i.rotationPointY = this.head.rotationPointY; + this.field_110700_P.rotationPointY = this.head.rotationPointY; + this.field_110699_Q.rotationPointY = this.head.rotationPointY; + this.field_110702_R.rotationPointZ = this.head.rotationPointZ; + this.field_110701_S.rotationPointZ = this.head.rotationPointZ; + this.field_110717_i.rotationPointZ = this.head.rotationPointZ; + this.field_110700_P.rotationPointZ = this.head.rotationPointZ; + this.field_110699_Q.rotationPointZ = this.head.rotationPointZ; + this.field_110702_R.rotateAngleX = f7; + this.field_110701_S.rotateAngleX = f7; + this.field_110717_i.rotateAngleX = this.head.rotateAngleX; + this.field_110700_P.rotateAngleX = this.head.rotateAngleX; + this.field_110699_Q.rotateAngleX = this.head.rotateAngleX; + this.field_110717_i.rotateAngleY = this.head.rotateAngleY; + this.field_110700_P.rotateAngleY = this.head.rotateAngleY; + this.field_110702_R.rotateAngleY = this.head.rotateAngleY; + this.field_110699_Q.rotateAngleY = this.head.rotateAngleY; + this.field_110701_S.rotateAngleY = this.head.rotateAngleY; + + if (flag2) + { + this.field_110691_L.rotateAngleX = -1.0471976F; + this.field_110692_M.rotateAngleX = -1.0471976F; + this.field_110693_N.rotateAngleX = -1.0471976F; + this.field_110694_O.rotateAngleX = -1.0471976F; + this.field_110691_L.rotateAngleZ = 0.0F; + this.field_110692_M.rotateAngleZ = 0.0F; + this.field_110693_N.rotateAngleZ = 0.0F; + this.field_110694_O.rotateAngleZ = 0.0F; + } + else + { + this.field_110691_L.rotateAngleX = f14 / 3.0F; + this.field_110692_M.rotateAngleX = f14 / 3.0F; + this.field_110693_N.rotateAngleX = f14 / 3.0F; + this.field_110694_O.rotateAngleX = f14 / 3.0F; + this.field_110691_L.rotateAngleZ = f14 / 5.0F; + this.field_110692_M.rotateAngleZ = f14 / 5.0F; + this.field_110693_N.rotateAngleZ = -f14 / 5.0F; + this.field_110694_O.rotateAngleZ = -f14 / 5.0F; + } + } + + f15 = -1.3089F + par3 * 1.5F; + + if (f15 > 0.0F) + { + f15 = 0.0F; + } + + if (flag) + { + this.tailBase.rotateAngleY = MathHelper.cos(f12 * 0.7F); + f15 = 0.0F; + } + else + { + this.tailBase.rotateAngleY = 0.0F; + } + + this.tailMiddle.rotateAngleY = this.tailBase.rotateAngleY; + this.tailTip.rotateAngleY = this.tailBase.rotateAngleY; + this.tailMiddle.rotationPointY = this.tailBase.rotationPointY; + this.tailTip.rotationPointY = this.tailBase.rotationPointY; + this.tailMiddle.rotationPointZ = this.tailBase.rotationPointZ; + this.tailTip.rotationPointZ = this.tailBase.rotationPointZ; + this.tailBase.rotateAngleX = f15; + this.tailMiddle.rotateAngleX = f15; + this.tailTip.rotateAngleX = -0.2618F + f15; + } +} diff --git a/src/main/java/electroblob/wizardry/client/model/ModelSpiritWolf.java b/src/main/java/electroblob/wizardry/client/model/ModelSpiritWolf.java new file mode 100644 index 00000000..8032e03e --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/model/ModelSpiritWolf.java @@ -0,0 +1,190 @@ +package electroblob.wizardry.client.model; + +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.MathHelper; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.entity.living.EntitySpiritWolf; + +@SideOnly(Side.CLIENT) +public class ModelSpiritWolf extends ModelBase +{ + /** main box for the wolf head */ + public ModelRenderer wolfHeadMain; + + /** The wolf's body */ + public ModelRenderer wolfBody; + + /** Wolf'se first leg */ + public ModelRenderer wolfLeg1; + + /** Wolf's second leg */ + public ModelRenderer wolfLeg2; + + /** Wolf's third leg */ + public ModelRenderer wolfLeg3; + + /** Wolf's fourth leg */ + public ModelRenderer wolfLeg4; + + /** The wolf's tail */ + ModelRenderer wolfTail; + + /** The wolf's mane */ + ModelRenderer wolfMane; + + public ModelSpiritWolf() + { + float f = 0.0F; + float f1 = 13.5F; + this.wolfHeadMain = new ModelRenderer(this, 0, 0); + this.wolfHeadMain.addBox(-3.0F, -3.0F, -2.0F, 6, 6, 4, f); + this.wolfHeadMain.setRotationPoint(-1.0F, f1, -7.0F); + this.wolfBody = new ModelRenderer(this, 18, 14); + this.wolfBody.addBox(-4.0F, -2.0F, -3.0F, 6, 9, 6, f); + this.wolfBody.setRotationPoint(0.0F, 14.0F, 2.0F); + this.wolfMane = new ModelRenderer(this, 21, 0); + this.wolfMane.addBox(-4.0F, -3.0F, -3.0F, 8, 6, 7, f); + this.wolfMane.setRotationPoint(-1.0F, 14.0F, 2.0F); + this.wolfLeg1 = new ModelRenderer(this, 0, 18); + this.wolfLeg1.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, f); + this.wolfLeg1.setRotationPoint(-2.5F, 16.0F, 7.0F); + this.wolfLeg2 = new ModelRenderer(this, 0, 18); + this.wolfLeg2.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, f); + this.wolfLeg2.setRotationPoint(0.5F, 16.0F, 7.0F); + this.wolfLeg3 = new ModelRenderer(this, 0, 18); + this.wolfLeg3.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, f); + this.wolfLeg3.setRotationPoint(-2.5F, 16.0F, -4.0F); + this.wolfLeg4 = new ModelRenderer(this, 0, 18); + this.wolfLeg4.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, f); + this.wolfLeg4.setRotationPoint(0.5F, 16.0F, -4.0F); + this.wolfTail = new ModelRenderer(this, 9, 18); + this.wolfTail.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, f); + this.wolfTail.setRotationPoint(-1.0F, 12.0F, 8.0F); + this.wolfHeadMain.setTextureOffset(16, 14).addBox(-3.0F, -5.0F, 0.0F, 2, 2, 1, f); + this.wolfHeadMain.setTextureOffset(16, 14).addBox(1.0F, -5.0F, 0.0F, 2, 2, 1, f); + this.wolfHeadMain.setTextureOffset(0, 10).addBox(-1.5F, 0.0F, -5.0F, 3, 3, 4, f); + } + + /** + * Sets the models various rotation angles then renders the model. + */ + public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7) + { + super.render(par1Entity, par2, par3, par4, par5, par6, par7); + this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity); + + if (this.isChild) + { + float f6 = 2.0F; + GL11.glPushMatrix(); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glTranslatef(0.0F, 5.0F * par7, 2.0F * par7); + this.wolfHeadMain.renderWithRotation(par7); + GL11.glDisable(GL11.GL_BLEND); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glScalef(1.0F / f6, 1.0F / f6, 1.0F / f6); + GL11.glTranslatef(0.0F, 24.0F * par7, 0.0F); + this.wolfBody.render(par7); + this.wolfLeg1.render(par7); + this.wolfLeg2.render(par7); + this.wolfLeg3.render(par7); + this.wolfLeg4.render(par7); + this.wolfTail.renderWithRotation(par7); + this.wolfMane.render(par7); + GL11.glDisable(GL11.GL_BLEND); + GL11.glPopMatrix(); + } + else + { + this.wolfHeadMain.renderWithRotation(par7); + this.wolfBody.render(par7); + this.wolfLeg1.render(par7); + this.wolfLeg2.render(par7); + this.wolfLeg3.render(par7); + this.wolfLeg4.render(par7); + this.wolfTail.renderWithRotation(par7); + this.wolfMane.render(par7); + } + } + + /** + * Used for easily adding entity-dependent animations. The second and third float params here are the same second + * and third as in the setRotationAngles method. + */ + public void setLivingAnimations(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4) + { + EntitySpiritWolf EntitySpiritWolf = (EntitySpiritWolf)par1EntityLivingBase; + + if (EntitySpiritWolf.isAngry()) + { + this.wolfTail.rotateAngleY = 0.0F; + } + else + { + this.wolfTail.rotateAngleY = MathHelper.cos(par2 * 0.6662F) * 1.4F * par3; + } + + if (EntitySpiritWolf.isSitting()) + { + this.wolfMane.setRotationPoint(-1.0F, 16.0F, -3.0F); + this.wolfMane.rotateAngleX = ((float)Math.PI * 2F / 5F); + this.wolfMane.rotateAngleY = 0.0F; + this.wolfBody.setRotationPoint(0.0F, 18.0F, 0.0F); + this.wolfBody.rotateAngleX = ((float)Math.PI / 4F); + this.wolfTail.setRotationPoint(-1.0F, 21.0F, 6.0F); + this.wolfLeg1.setRotationPoint(-2.5F, 22.0F, 2.0F); + this.wolfLeg1.rotateAngleX = ((float)Math.PI * 3F / 2F); + this.wolfLeg2.setRotationPoint(0.5F, 22.0F, 2.0F); + this.wolfLeg2.rotateAngleX = ((float)Math.PI * 3F / 2F); + this.wolfLeg3.rotateAngleX = 5.811947F; + this.wolfLeg3.setRotationPoint(-2.49F, 17.0F, -4.0F); + this.wolfLeg4.rotateAngleX = 5.811947F; + this.wolfLeg4.setRotationPoint(0.51F, 17.0F, -4.0F); + } + else + { + this.wolfBody.setRotationPoint(0.0F, 14.0F, 2.0F); + this.wolfBody.rotateAngleX = ((float)Math.PI / 2F); + this.wolfMane.setRotationPoint(-1.0F, 14.0F, -3.0F); + this.wolfMane.rotateAngleX = this.wolfBody.rotateAngleX; + this.wolfTail.setRotationPoint(-1.0F, 12.0F, 8.0F); + this.wolfLeg1.setRotationPoint(-2.5F, 16.0F, 7.0F); + this.wolfLeg2.setRotationPoint(0.5F, 16.0F, 7.0F); + this.wolfLeg3.setRotationPoint(-2.5F, 16.0F, -4.0F); + this.wolfLeg4.setRotationPoint(0.5F, 16.0F, -4.0F); + this.wolfLeg1.rotateAngleX = MathHelper.cos(par2 * 0.6662F) * 1.4F * par3; + this.wolfLeg2.rotateAngleX = MathHelper.cos(par2 * 0.6662F + (float)Math.PI) * 1.4F * par3; + this.wolfLeg3.rotateAngleX = MathHelper.cos(par2 * 0.6662F + (float)Math.PI) * 1.4F * par3; + this.wolfLeg4.rotateAngleX = MathHelper.cos(par2 * 0.6662F) * 1.4F * par3; + } + + this.wolfHeadMain.rotateAngleZ = EntitySpiritWolf.getInterestedAngle(par4) + EntitySpiritWolf.getShakeAngle(par4, 0.0F); + this.wolfMane.rotateAngleZ = EntitySpiritWolf.getShakeAngle(par4, -0.08F); + this.wolfBody.rotateAngleZ = EntitySpiritWolf.getShakeAngle(par4, -0.16F); + this.wolfTail.rotateAngleZ = EntitySpiritWolf.getShakeAngle(par4, -0.2F); + } + + /** + * Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms + * and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how + * "far" arms and legs can swing at most. + */ + public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity) + { + super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity); + this.wolfHeadMain.rotateAngleX = par5 / (180F / (float)Math.PI); + this.wolfHeadMain.rotateAngleY = par4 / (180F / (float)Math.PI); + this.wolfTail.rotateAngleX = par3; + } +} diff --git a/src/main/java/electroblob/wizardry/client/model/ModelWizard.java b/src/main/java/electroblob/wizardry/client/model/ModelWizard.java index e10cf45e..cc6c2c90 100644 --- a/src/main/java/electroblob/wizardry/client/model/ModelWizard.java +++ b/src/main/java/electroblob/wizardry/client/model/ModelWizard.java @@ -2,6 +2,7 @@ package electroblob.wizardry.client.model; import net.minecraft.client.model.ModelBiped; import net.minecraft.client.model.ModelRenderer; +import net.minecraft.entity.Entity; public class ModelWizard extends ModelBiped { diff --git a/src/main/java/electroblob/wizardry/client/model/ModelWizardArmour.java b/src/main/java/electroblob/wizardry/client/model/ModelWizardArmour.java index 3829f103..cde60300 100644 --- a/src/main/java/electroblob/wizardry/client/model/ModelWizardArmour.java +++ b/src/main/java/electroblob/wizardry/client/model/ModelWizardArmour.java @@ -6,106 +6,108 @@ import net.minecraft.entity.Entity; public class ModelWizardArmour extends ModelBiped { - ModelRenderer Shape1; - ModelRenderer Shape2; - ModelRenderer Shape3; - ModelRenderer Shape4; - ModelRenderer Shape5; - ModelRenderer Shape6; - ModelRenderer Shape7; - ModelRenderer robe; - - public ModelWizardArmour(float scale){ - - super(scale, 0, 64, 64); - - // This is necessary to stop the head from scaling. - this.bipedHead = new ModelRenderer(this, 0, 0); - this.bipedHead.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.1f); - this.bipedHead.setRotationPoint(0.0F, 0.0F + 0, 0.0F); - - Shape1 = new ModelRenderer(this, -16, 32); - Shape1.addBox(-8F, -7F, -8F, 16, 0, 16); - Shape1.setRotationPoint(0F, 0F, 0F); - Shape1.setTextureSize(64, 64); - Shape1.mirror = true; - setRotation(Shape1, 0F, 0F, 0F); - - Shape2 = new ModelRenderer(this, 0, 48); - Shape2.addBox(0F, 0F, 0F, 6, 2, 6); - Shape2.setRotationPoint(-3F, -10F, -3F); - Shape2.setTextureSize(64, 64); - Shape2.mirror = true; - setRotation(Shape2, -0.1396263F, 0F, 0F); - - Shape3 = new ModelRenderer(this, 0, 56); - Shape3.addBox(0F, 0F, 0F, 5, 2, 5); - Shape3.setRotationPoint(-2.5F, -11.53333F, -2F); - Shape3.setTextureSize(64, 64); - Shape3.mirror = true; - setRotation(Shape3, -0.2443461F, 0F, 0F); - - Shape4 = new ModelRenderer(this, 24, 48); - Shape4.addBox(0F, 0F, 0F, 4, 2, 4); - Shape4.setRotationPoint(-2F, -13F, -1F); - Shape4.setTextureSize(64, 64); - Shape4.mirror = true; - setRotation(Shape4, -0.4014257F, 0F, 0F); - - Shape5 = new ModelRenderer(this, 24, 54); - Shape5.addBox(0F, 0F, 0F, 3, 2, 3); - Shape5.setRotationPoint(-1.5F, -14F, 0F); - Shape5.setTextureSize(64, 64); - Shape5.mirror = true; - setRotation(Shape5, -0.5759587F, 0F, 0F); - - Shape6 = new ModelRenderer(this, 20, 59); - Shape6.addBox(0F, 0F, 0F, 2, 2, 2); - Shape6.setRotationPoint(-1F, -14F, 0F); - Shape6.setTextureSize(64, 64); - Shape6.mirror = true; - setRotation(Shape6, 0.3316126F, 0F, 0F); - - Shape7 = new ModelRenderer(this, 28, 59); - Shape7.addBox(0F, 0F, 0F, 1, 1, 3); - Shape7.setRotationPoint(-0.5F, -14.5F, 2F); - Shape7.setTextureSize(64, 64); - Shape7.mirror = true; - setRotation(Shape7, -0.5585054F, 0F, 0F); - - // The robe is now the body - bipedBody = new ModelRenderer(this, 40, 42); - bipedBody.addBox(-4F, 0F, -2F, 8, 18, 4, scale); - bipedBody.setRotationPoint(0F, 0F, 0F); - bipedBody.setTextureSize(64, 64); - bipedBody.mirror = true; - setRotation(bipedBody, 0F, 0F, 0F); - - // Makes the hat rotate with the head. - bipedHead.addChild(Shape1); - bipedHead.addChild(Shape2); - bipedHead.addChild(Shape3); - bipedHead.addChild(Shape4); - bipedHead.addChild(Shape5); - bipedHead.addChild(Shape6); - bipedHead.addChild(Shape7); - // Makes the robe move with the body - //bipedBody.addChild(robe); - } - - public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5){ - super.render(entity, f, f1, f2, f3, f4, f5); - setRotationAngles(f, f1, f2, f3, f4, f5, entity); - } - - private void setRotation(ModelRenderer model, float x, float y, float z){ - model.rotateAngleX = x; - model.rotateAngleY = y; - model.rotateAngleZ = z; - } - - public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity){ - super.setRotationAngles(f, f1, f2, f3, f4, f5, entity); - } + ModelRenderer Shape1; + ModelRenderer Shape2; + ModelRenderer Shape3; + ModelRenderer Shape4; + ModelRenderer Shape5; + ModelRenderer Shape6; + ModelRenderer Shape7; + ModelRenderer robe; + + public ModelWizardArmour(float scale){ + + super(scale, 0, 64, 64); + + // This is necessary to stop the head from scaling. + this.bipedHead = new ModelRenderer(this, 0, 0); + this.bipedHead.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.1f); + this.bipedHead.setRotationPoint(0.0F, 0.0F + 0, 0.0F); + + Shape1 = new ModelRenderer(this, -16, 32); + Shape1.addBox(-8F, -7F, -8F, 16, 0, 16); + Shape1.setRotationPoint(0F, 0F, 0F); + Shape1.setTextureSize(64, 64); + Shape1.mirror = true; + setRotation(Shape1, 0F, 0F, 0F); + + Shape2 = new ModelRenderer(this, 0, 48); + Shape2.addBox(0F, 0F, 0F, 6, 2, 6); + Shape2.setRotationPoint(-3F, -10F, -3F); + Shape2.setTextureSize(64, 64); + Shape2.mirror = true; + setRotation(Shape2, -0.1396263F, 0F, 0F); + + Shape3 = new ModelRenderer(this, 0, 56); + Shape3.addBox(0F, 0F, 0F, 5, 2, 5); + Shape3.setRotationPoint(-2.5F, -11.53333F, -2F); + Shape3.setTextureSize(64, 64); + Shape3.mirror = true; + setRotation(Shape3, -0.2443461F, 0F, 0F); + + Shape4 = new ModelRenderer(this, 24, 48); + Shape4.addBox(0F, 0F, 0F, 4, 2, 4); + Shape4.setRotationPoint(-2F, -13F, -1F); + Shape4.setTextureSize(64, 64); + Shape4.mirror = true; + setRotation(Shape4, -0.4014257F, 0F, 0F); + + Shape5 = new ModelRenderer(this, 24, 54); + Shape5.addBox(0F, 0F, 0F, 3, 2, 3); + Shape5.setRotationPoint(-1.5F, -14F, 0F); + Shape5.setTextureSize(64, 64); + Shape5.mirror = true; + setRotation(Shape5, -0.5759587F, 0F, 0F); + + Shape6 = new ModelRenderer(this, 20, 59); + Shape6.addBox(0F, 0F, 0F, 2, 2, 2); + Shape6.setRotationPoint(-1F, -14F, 0F); + Shape6.setTextureSize(64, 64); + Shape6.mirror = true; + setRotation(Shape6, 0.3316126F, 0F, 0F); + + Shape7 = new ModelRenderer(this, 28, 59); + Shape7.addBox(0F, 0F, 0F, 1, 1, 3); + Shape7.setRotationPoint(-0.5F, -14.5F, 2F); + Shape7.setTextureSize(64, 64); + Shape7.mirror = true; + setRotation(Shape7, -0.5585054F, 0F, 0F); + + robe = new ModelRenderer(this, 40, 42); + robe.addBox(-4F, 0F, -2F, 8, 18, 4, scale); + robe.setRotationPoint(0F, 0F, 0F); + robe.setTextureSize(64, 64); + robe.mirror = true; + setRotation(robe, 0F, 0F, 0F); + + // Makes the hat rotate with the head. + bipedHead.addChild(Shape1); + bipedHead.addChild(Shape2); + bipedHead.addChild(Shape3); + bipedHead.addChild(Shape4); + bipedHead.addChild(Shape5); + bipedHead.addChild(Shape6); + bipedHead.addChild(Shape7); + // Makes the robe move with the body + bipedBody.addChild(robe); + } + + public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) + { + super.render(entity, f, f1, f2, f3, f4, f5); + setRotationAngles(f, f1, f2, f3, f4, f5, entity); + } + + private void setRotation(ModelRenderer model, float x, float y, float z) + { + model.rotateAngleX = x; + model.rotateAngleY = y; + model.rotateAngleZ = z; + } + + public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity) + { + super.setRotationAngles(f, f1, f2, f3, f4, f5, entity); + } } diff --git a/src/main/java/electroblob/wizardry/client/model/WizardryItemModels.java b/src/main/java/electroblob/wizardry/client/model/WizardryItemModels.java deleted file mode 100644 index a1d678ab..00000000 --- a/src/main/java/electroblob/wizardry/client/model/WizardryItemModels.java +++ /dev/null @@ -1,192 +0,0 @@ -package electroblob.wizardry.client.model; - -import java.util.ArrayList; -import java.util.List; - -import electroblob.wizardry.registry.WizardryBlocks; -import electroblob.wizardry.registry.WizardryItems; -import net.minecraft.client.renderer.block.model.ModelResourceLocation; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraftforge.client.event.ModelRegistryEvent; -import net.minecraftforge.client.model.ModelLoader; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -import net.minecraftforge.oredict.OreDictionary; - -/** - * Class responsible for registering all of wizardry's item (and itemblock) models. - * @author Electroblob - * @since Wizardry 2.1 - */ -@SideOnly(Side.CLIENT) -@Mod.EventBusSubscriber(Side.CLIENT) -public final class WizardryItemModels { - - @SubscribeEvent - public static void register(ModelRegistryEvent event){ - - // ItemBlocks - - registerItemModel(Item.getItemFromBlock(WizardryBlocks.arcane_workbench)); - registerItemModel(Item.getItemFromBlock(WizardryBlocks.crystal_ore)); - registerItemModel(Item.getItemFromBlock(WizardryBlocks.crystal_flower)); - registerItemModel(Item.getItemFromBlock(WizardryBlocks.transportation_stone)); - registerItemModel(Item.getItemFromBlock(WizardryBlocks.crystal_block)); - - // Items - - registerItemModel(WizardryItems.magic_crystal); - - registerItemModel(WizardryItems.magic_wand); - registerItemModel(WizardryItems.apprentice_wand); - registerItemModel(WizardryItems.advanced_wand); - registerItemModel(WizardryItems.master_wand); - - registerItemModel(WizardryItems.spell_book); - // Wildcard registered for wizard trades. - registerItemModel(WizardryItems.spell_book, OreDictionary.WILDCARD_VALUE, "normal"); - registerItemModel(WizardryItems.arcane_tome); - registerItemModel(WizardryItems.wizard_handbook); - - registerItemModel(WizardryItems.basic_fire_wand); - registerItemModel(WizardryItems.basic_ice_wand); - registerItemModel(WizardryItems.basic_lightning_wand); - registerItemModel(WizardryItems.basic_necromancy_wand); - registerItemModel(WizardryItems.basic_earth_wand); - registerItemModel(WizardryItems.basic_sorcery_wand); - registerItemModel(WizardryItems.basic_healing_wand); - - registerItemModel(WizardryItems.apprentice_fire_wand); - registerItemModel(WizardryItems.apprentice_ice_wand); - registerItemModel(WizardryItems.apprentice_lightning_wand); - registerItemModel(WizardryItems.apprentice_necromancy_wand); - registerItemModel(WizardryItems.apprentice_earth_wand); - registerItemModel(WizardryItems.apprentice_sorcery_wand); - registerItemModel(WizardryItems.apprentice_healing_wand); - - registerItemModel(WizardryItems.advanced_fire_wand); - registerItemModel(WizardryItems.advanced_ice_wand); - registerItemModel(WizardryItems.advanced_lightning_wand); - registerItemModel(WizardryItems.advanced_necromancy_wand); - registerItemModel(WizardryItems.advanced_earth_wand); - registerItemModel(WizardryItems.advanced_sorcery_wand); - registerItemModel(WizardryItems.advanced_healing_wand); - - registerItemModel(WizardryItems.master_fire_wand); - registerItemModel(WizardryItems.master_ice_wand); - registerItemModel(WizardryItems.master_lightning_wand); - registerItemModel(WizardryItems.master_necromancy_wand); - registerItemModel(WizardryItems.master_earth_wand); - registerItemModel(WizardryItems.master_sorcery_wand); - registerItemModel(WizardryItems.master_healing_wand); - - registerItemModel(WizardryItems.spectral_sword); - registerItemModel(WizardryItems.spectral_pickaxe); - registerItemModel(WizardryItems.spectral_bow); - - registerItemModel(WizardryItems.mana_flask); - - registerItemModel(WizardryItems.storage_upgrade); - registerItemModel(WizardryItems.siphon_upgrade); - registerItemModel(WizardryItems.condenser_upgrade); - registerItemModel(WizardryItems.range_upgrade); - registerItemModel(WizardryItems.duration_upgrade); - registerItemModel(WizardryItems.cooldown_upgrade); - registerItemModel(WizardryItems.blast_upgrade); - registerItemModel(WizardryItems.attunement_upgrade); - - registerItemModel(WizardryItems.flaming_axe); - registerItemModel(WizardryItems.frost_axe); - - registerItemModel(WizardryItems.firebomb); - registerItemModel(WizardryItems.poison_bomb); - - registerItemModel(WizardryItems.blank_scroll); - registerItemModel(WizardryItems.scroll); - - registerItemModel(WizardryItems.armour_upgrade); - - registerItemModel(WizardryItems.magic_silk); - - registerItemModel(WizardryItems.wizard_hat); - registerItemModel(WizardryItems.wizard_robe); - registerItemModel(WizardryItems.wizard_leggings); - registerItemModel(WizardryItems.wizard_boots); - - registerItemModel(WizardryItems.wizard_hat_fire); - registerItemModel(WizardryItems.wizard_robe_fire); - registerItemModel(WizardryItems.wizard_leggings_fire); - registerItemModel(WizardryItems.wizard_boots_fire); - - registerItemModel(WizardryItems.wizard_hat_ice); - registerItemModel(WizardryItems.wizard_robe_ice); - registerItemModel(WizardryItems.wizard_leggings_ice); - registerItemModel(WizardryItems.wizard_boots_ice); - - registerItemModel(WizardryItems.wizard_hat_lightning); - registerItemModel(WizardryItems.wizard_robe_lightning); - registerItemModel(WizardryItems.wizard_leggings_lightning); - registerItemModel(WizardryItems.wizard_boots_lightning); - - registerItemModel(WizardryItems.wizard_hat_necromancy); - registerItemModel(WizardryItems.wizard_robe_necromancy); - registerItemModel(WizardryItems.wizard_leggings_necromancy); - registerItemModel(WizardryItems.wizard_boots_necromancy); - - registerItemModel(WizardryItems.wizard_hat_earth); - registerItemModel(WizardryItems.wizard_robe_earth); - registerItemModel(WizardryItems.wizard_leggings_earth); - registerItemModel(WizardryItems.wizard_boots_earth); - - registerItemModel(WizardryItems.wizard_hat_sorcery); - registerItemModel(WizardryItems.wizard_robe_sorcery); - registerItemModel(WizardryItems.wizard_leggings_sorcery); - registerItemModel(WizardryItems.wizard_boots_sorcery); - - registerItemModel(WizardryItems.wizard_hat_healing); - registerItemModel(WizardryItems.wizard_robe_healing); - registerItemModel(WizardryItems.wizard_leggings_healing); - registerItemModel(WizardryItems.wizard_boots_healing); - - registerItemModel(WizardryItems.spectral_helmet); - registerItemModel(WizardryItems.spectral_chestplate); - registerItemModel(WizardryItems.spectral_leggings); - registerItemModel(WizardryItems.spectral_boots); - - registerItemModel(WizardryItems.smoke_bomb); - - registerItemModel(WizardryItems.identification_scroll); - } - - // Moved from the proxies - - /** Registers an item model, using the item's registry name as the model name (this - * convention makes it easier to keep track of everything). Variant defaults to "normal". Registers the model - * for metadata 0 automatically, plus all the other metadata values that the item can take, as defined in - * {@link Item#getSubItems(Item, net.minecraft.creativetab.CreativeTabs, java.util.List)}. The passed in item - * must allow null to be passed in for the creative tab parameter in the aforementioned method, or a - * {@link NullPointerException} will result. */ - private static void registerItemModel(Item item){ - - if(item.getHasSubtypes()){ - List items = new ArrayList(); - item.getSubItems(item, null, items); // Client-only method, but we're client-side so this is OK. - for(ItemStack stack : items){ - ModelLoader.setCustomModelResourceLocation(item, stack.getMetadata(), new ModelResourceLocation(item.getRegistryName(), "inventory")); - } - } - // Changing the last parameter from null to "inventory" fixed the item/block model weirdness. No idea why! - ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(item.getRegistryName(), "inventory")); - } - - /** Registers an item model for the given metadata, using the item's registry name as the model name (this - * convention makes it easier to keep track of everything). This is intended for registering additional metadata - * values which aren't displayed in the creative menu, for example the wildcard spell book used in wizard trades. */ - private static void registerItemModel(Item item, int metadata, String variant) { - ModelLoader.setCustomModelResourceLocation(item, metadata, new ModelResourceLocation(item.getRegistryName(), variant)); - } - -} diff --git a/src/main/java/electroblob/wizardry/client/particle/EntityBlizzardFX.java b/src/main/java/electroblob/wizardry/client/particle/EntityBlizzardFX.java new file mode 100644 index 00000000..6e4b204f --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/particle/EntityBlizzardFX.java @@ -0,0 +1,139 @@ +package electroblob.wizardry.client.particle; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.Wizardry; +import net.minecraft.client.particle.EffectRenderer; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; + +@SideOnly(Side.CLIENT) +public class EntityBlizzardFX extends EntitySnowFX +{ + /** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would + * be any, but I may as well.) */ + public static final String NAME = Wizardry.MODID + "blizzard"; + + private boolean gravity = false; + private double angle; + private double radius; + private double speed; + + public EntityBlizzardFX(World world, float red, float green, float blue, int maxAge, double originX, double originZ, double radius, double yPos) + { + super(world, 0, 0, 0, 0, 0, 0, maxAge); + this.angle = this.rand.nextDouble() * Math.PI * 2; + double x = originX - Math.cos(angle)*radius; + double z = originZ + radius*Math.sin(angle); + this.radius = radius; + this.setPosition(x, yPos, z); + //this.particleScale *= 0.75F; + this.noClip = true; + particleRed = red; + particleGreen = green; + particleBlue = blue; + if(rand.nextBoolean()){ + speed = rand.nextDouble()*2 + 1; + }else{ + speed = rand.nextDouble()*-2 - 1; + } + } + + public EntityBlizzardFX(World world, double x, double y, double z, double vx, double vy, double vz, float red, float green, float blue) + { + super(world, x, y, z, vx, vy, vz); + //this.particleScale *= 0.75F; + this.particleMaxAge = 48 + this.rand.nextInt(12); + this.noClip = true; + particleRed = red; + particleGreen = green; + particleBlue = blue; + } + + public void setColour(int par1) + { + float f = (float)((par1 & 16711680) >> 16) / 255.0F; + float f1 = (float)((par1 & 65280) >> 8) / 255.0F; + float f2 = (float)((par1 & 255) >> 0) / 255.0F; + float f3 = 1.0F; + this.setRBGColorF(f * f3, f1 * f3, f2 * f3); + } + + /** + * returns the bounding box for this entity + */ + public AxisAlignedBB getBoundingBox() + { + return null; + } + + /** + * Returns true if this entity should push and be pushed by other entities when colliding. + */ + public boolean canBePushed() + { + return false; + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) + { + if (this.particleAge < this.particleMaxAge / 3 || (this.particleAge + this.particleMaxAge) / 3 % 2 == 0) + { + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); + } + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() + { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) + { + this.setDead(); + } + + // This is in radians per tick... + double omega = (Math.PI*2)/20 - speed/(20*radius); + + if(speed < 0){ + omega = -(Math.PI*2)/20 + speed/(20*radius); + } + + // v = r times omega; therefore the normalised velocity vector needs to be r times the angle increment / 2 pi. + this.angle += omega; + + this.motionZ = radius * omega * Math.cos(angle); + this.motionX = radius * omega * Math.sin(angle); + this.moveEntity(motionX, motionY, motionZ); + + if(this.gravity){ + this.motionY -= 0.05d; + } + + if (this.particleAge > this.particleMaxAge / 2) + { + this.setAlphaF(1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge); + } + + } +/* + @Override + public int getBrightnessForRender(float par1) + { + return 15728880; + } + + @Override + public float getBrightness(float par1) + { + return 1.0F; + } + */ +} diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleDarkMagic.java b/src/main/java/electroblob/wizardry/client/particle/EntityDarkMagicFX.java similarity index 66% rename from src/main/java/electroblob/wizardry/client/particle/ParticleDarkMagic.java rename to src/main/java/electroblob/wizardry/client/particle/EntityDarkMagicFX.java index 986e3c7c..2052bf72 100644 --- a/src/main/java/electroblob/wizardry/client/particle/ParticleDarkMagic.java +++ b/src/main/java/electroblob/wizardry/client/particle/EntityDarkMagicFX.java @@ -1,19 +1,23 @@ package electroblob.wizardry.client.particle; -import net.minecraft.client.particle.Particle; -import net.minecraft.client.renderer.VertexBuffer; -import net.minecraft.entity.Entity; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.Wizardry; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) -public class ParticleDarkMagic extends Particle { +public class EntityDarkMagicFX extends EntityFX +{ + /** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would + * be any, but I may as well.) */ + public static final String NAME = Wizardry.MODID + "darkmagic"; /** Base spell texture index */ private int baseSpellTextureIndex = 128; - public ParticleDarkMagic(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float r, float g, float b) + public EntityDarkMagicFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float r, float g, float b) { super(par1World, par2, par4, par6, par8, par10, par12); this.motionY *= 0.20000000298023224D; @@ -24,13 +28,12 @@ public class ParticleDarkMagic extends Particle { this.particleScale *= 0.75F; this.particleMaxAge = (int)(8.0D / (Math.random() * 0.8D + 0.2D)); - this.canCollide = true; + this.noClip = true; } - @Override - public void renderParticle(VertexBuffer buffer, Entity entity, float partialTicks, float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ) + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) { - float f6 = ((float)this.particleAge + partialTicks) / (float)this.particleMaxAge * 32.0F; + float f6 = ((float)this.particleAge + par2) / (float)this.particleMaxAge * 32.0F; if (f6 < 0.0F) { @@ -42,7 +45,7 @@ public class ParticleDarkMagic extends Particle { f6 = 1.0F; } - super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ); + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); } /** @@ -56,7 +59,7 @@ public class ParticleDarkMagic extends Particle { if (this.particleAge++ >= this.particleMaxAge) { - this.setExpired(); + this.setDead(); } this.setParticleTextureIndex(this.baseSpellTextureIndex + (7 - this.particleAge * 8 / this.particleMaxAge)); @@ -73,7 +76,7 @@ public class ParticleDarkMagic extends Particle { this.motionY *= 0.9599999785423279D; this.motionZ *= 0.9599999785423279D; - if (this.isCollided) + if (this.onGround) { this.motionX *= 0.699999988079071D; this.motionZ *= 0.699999988079071D; diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleDust.java b/src/main/java/electroblob/wizardry/client/particle/EntityDustFX.java similarity index 64% rename from src/main/java/electroblob/wizardry/client/particle/ParticleDust.java rename to src/main/java/electroblob/wizardry/client/particle/EntityDustFX.java index 6a121fa3..77e35ebc 100644 --- a/src/main/java/electroblob/wizardry/client/particle/ParticleDust.java +++ b/src/main/java/electroblob/wizardry/client/particle/EntityDustFX.java @@ -1,16 +1,27 @@ package electroblob.wizardry.client.particle; -import net.minecraft.client.particle.Particle; +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.Wizardry; +import net.minecraft.block.material.Material; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) -public class ParticleDust extends Particle { +public class EntityDustFX extends EntityFX +{ + /** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would + * be any, but I may as well.) */ + public static final String NAME = Wizardry.MODID + "dust"; private final boolean shaded; - public ParticleDust(World par1World, double x, double y, double z, double par8, double par10, double par12, float r, float g, float b, boolean shaded) + public EntityDustFX(World par1World, double x, double y, double z, double par8, double par10, double par12, float r, float g, float b, boolean shaded) { super(par1World, x, y, z, par8, par10, par12); this.particleRed = r; @@ -38,7 +49,7 @@ public class ParticleDust extends Particle { if (this.particleMaxAge-- <= 0) { - this.setExpired(); + this.setDead(); } } @@ -47,11 +58,10 @@ public class ParticleDust extends Particle { { return shaded ? super.getBrightnessForRender(par1) : 15728880; } - /* + @Override public float getBrightness(float par1) { return shaded ? super.getBrightness(par1) : 1.0F; } - */ } diff --git a/src/main/java/electroblob/wizardry/client/particle/EntityIceFX.java b/src/main/java/electroblob/wizardry/client/particle/EntityIceFX.java new file mode 100644 index 00000000..88039816 --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/particle/EntityIceFX.java @@ -0,0 +1,199 @@ +package electroblob.wizardry.client.particle; + +import java.lang.reflect.Field; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.Wizardry; +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.entity.Entity; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +@SideOnly(Side.CLIENT) +public class EntityIceFX extends EntityFX +{ + /** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would + * be any, but I may as well.) */ + public static final String NAME = Wizardry.MODID + "ice"; + + private static final ResourceLocation iceTextures = new ResourceLocation("wizardry:textures/particle/ice_particles.png"); + + public EntityIceFX(World world, double x, double y, double z, double vx, double vy, double vz) + { + super(world, x, y, z, vx, vy, vz); + this.particleRed = 1.0F; + this.particleGreen = 1.0F; + this.particleBlue = 1.0F; + this.setParticleTextureIndex(rand.nextInt(8)); + this.setSize(0.02F, 0.02F); + this.particleScale *= 0.75f; + this.motionX = vx; + this.motionY = vy; + this.motionZ = vz; + this.particleMaxAge = 40 + rand.nextInt(10); + this.noClip = true; + } + + public EntityIceFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, int maxAge){ + this(par1World, par2, par4, par6, par8, par10, par12); + this.particleMaxAge = maxAge; + this.noClip = true; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate(){ + + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) + { + this.setDead(); + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.9800000190734863D; + this.motionZ *= 0.9800000190734863D; + // Gravity + this.motionY -= 0.05d; + } + + /* There are 4 layers of particles, specified as 0-3 by the method below. + * - Layer 0 causes the normal particles.png to be bound to the render engine for normal particles. + * - Layer 1 causes the block textures to be bound to the render engine for digging fx and falling fx. + * - Layer 2 causes the item textures to be bound to the render engine for tool breaking fx, snowballpoofs, slime particles, etc. + * - Layer 3 is not used in vanilla minecraft and was presumably added by forge for exactly this reason. + * This means no texture is bound by vanilla minecraft, meaning you are free to do as you wish without possibly + * overwriting vanilla particles. Mod particles won't be overwritten anyway since they bind their own textures. + * It is of course important to bind the texture every time you render a custom particle, but I don't see how + * you could do it any other way, since you don't have access to EffectRenderer. + */ + @Override + public int getFXLayer() { + // This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer. + return 3; + } + + @Override + public void setParticleTextureIndex(int par1) + { + this.particleTextureIndexX = par1 % 4; + this.particleTextureIndexY = par1 / 4; + } + + // Overwitten from entityfx to bind the new texture. + @Override + public void renderParticle(Tessellator tessellator, float partialTicks, float par3, float par4, float par5, float par6, float par7) + { + // Resets the tessellator and binds the new texture. Used to check if tessellator is drawing, but that field + // is no longer visible. If this results in an IllegalStateException (tessellator not drawing), look into this. + // Perhaps I could use reflection (ooooooh) to access it? Like this: + + /* + Field f = null; + boolean isDrawing = false; + + try { + f = tessellator.getClass().getDeclaredField("isDrawing"); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } + + if(f != null){ + + f.setAccessible(true); + + try { + isDrawing = (Boolean)f.get(tessellator); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + if(isDrawing)*/ + //tessellator.draw(); + + GL11.glPushMatrix(); + + // This stuff does the shading. The parameter does nothing apparently. + int j = this.getBrightnessForRender(0); + int k = j % 65536; + int l = j / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F); + + RenderHelper.disableStandardItemLighting(); + + Minecraft.getMinecraft().renderEngine.bindTexture(iceTextures); + + tessellator.startDrawingQuads(); + + float f6 = (float)this.particleTextureIndexX / 4.0F; + float f7 = f6 + 0.0624375F*4; + float f8 = (float)this.particleTextureIndexY / 4.0F; + float f9 = f8 + 0.0624375F*4; + float f10 = 0.1F * this.particleScale; + + if (this.particleIcon != null) + { + f6 = this.particleIcon.getMinU(); + f7 = this.particleIcon.getMaxU(); + f8 = this.particleIcon.getMinV(); + f9 = this.particleIcon.getMaxV(); + } + + // Fix which gets proper values for interpPos so the particles don't appear to move. + Entity player = Minecraft.getMinecraft().thePlayer; + this.interpPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)partialTicks; + this.interpPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)partialTicks; + this.interpPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)partialTicks; + + float f11 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX); + float f12 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY); + float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ); + float f14 = 1.0F; + + tessellator.setColorRGBA_F(this.particleRed * f14, this.particleGreen * f14, this.particleBlue * f14, this.particleAlpha); + tessellator.addVertexWithUV((double)(f11 - par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 - par5 * f10 - par7 * f10), (double)f7, (double)f9); + tessellator.addVertexWithUV((double)(f11 - par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 - par5 * f10 + par7 * f10), (double)f7, (double)f8); + tessellator.addVertexWithUV((double)(f11 + par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 + par5 * f10 + par7 * f10), (double)f6, (double)f8); + tessellator.addVertexWithUV((double)(f11 + par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 + par5 * f10 - par7 * f10), (double)f6, (double)f9); + + tessellator.draw(); + + GL11.glPopMatrix(); + + // Re-binds the normal particles so that the mod texture isn't on all of them + //Minecraft.getMinecraft().renderEngine.bindTexture(new ResourceLocation("textures/particle/particles.png")); + + //tessellator.startDrawingQuads(); + + } + + public int getBrightnessForRender(float par1) + { + return 15728880; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) + { + return 1.0F; + } +} diff --git a/src/main/java/electroblob/wizardry/client/particle/EntityLeafFX.java b/src/main/java/electroblob/wizardry/client/particle/EntityLeafFX.java new file mode 100644 index 00000000..d565c241 --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/particle/EntityLeafFX.java @@ -0,0 +1,180 @@ +package electroblob.wizardry.client.particle; + +import java.lang.reflect.Field; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.Wizardry; +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.entity.Entity; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +@SideOnly(Side.CLIENT) +public class EntityLeafFX extends EntityFX +{ + /** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would + * be any, but I may as well.) */ + public static final String NAME = Wizardry.MODID + "leaf"; + + private static final ResourceLocation leafTextures = new ResourceLocation("wizardry:textures/particle/leaf_particles.png"); + + public EntityLeafFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) + { + super(par1World, par2, par4, par6, par8, par10, par12); + this.particleRed = 1.0F; + this.particleGreen = 1.0F; + this.particleBlue = 1.0F; + this.setParticleTextureIndex(rand.nextInt(16)); + this.setSize(0.02F, 0.02F); + this.particleScale *= 1.4f; + this.motionX = par8; + this.motionY = par10; + this.motionZ = par12; + this.particleMaxAge = 40 + rand.nextInt(10); + } + + public EntityLeafFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, int maxAge){ + this(par1World, par2, par4, par6, par8, par10, par12); + this.particleMaxAge = maxAge; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() + { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (this.particleMaxAge-- <= 0) + { + this.setDead(); + } + } + + /* There are 4 layers of particles, specified as 0-3 by the method below. + * - Layer 0 causes the normal particles.png to be bound to the render engine for normal particles. + * - Layer 1 causes the block textures to be bound to the render engine for digging fx and falling fx. + * - Layer 2 causes the item textures to be bound to the render engine for tool breaking fx, snowballpoofs, slime particles, etc. + * - Layer 3 is not used in vanilla minecraft and was presumably added by forge for exactly this reason. + * This means no texture is bound by vanilla minecraft, meaning you are free to do as you wish without possibly + * overwriting vanilla particles. Mod particles won't be overwritten anyway since they bind their own textures. + * It is of course important to bind the texture every time you render a custom particle, but I don't see how + * you could do it any other way, since you don't have access to EffectRenderer. + */ + @Override + public int getFXLayer() { + // This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer. + return 3; + } + + /** + * Public method to set private field particleTextureIndex. + */ + public void setParticleTextureIndex(int par1) + { + this.particleTextureIndexX = par1 % 4; + this.particleTextureIndexY = par1 / 4; + } + + // Overwitten from entityfx to bind the new texture. + @Override + public void renderParticle(Tessellator tessellator, float partialTicks, float par3, float par4, float par5, float par6, float par7) + { + // Resets the tessellator and binds the new texture. Used to check if tessellator is drawing, but that field + // is no longer visible. If this results in an IllegalStateException (tessellator not drawing), look into this. + // Perhaps I could use reflection (ooooooh) to access it? Like this: + + /* + Field f = null; + boolean isDrawing = false; + + try { + f = tessellator.getClass().getDeclaredField("isDrawing"); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } + + if(f != null){ + + f.setAccessible(true); + + try { + isDrawing = (Boolean)f.get(tessellator); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + if(isDrawing)*/ + //tessellator.draw(); + + GL11.glPushMatrix(); + + // This stuff does the shading. The parameter does nothing apparently. + int j = this.getBrightnessForRender(0); + int k = j % 65536; + int l = j / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F); + + RenderHelper.disableStandardItemLighting(); + + Minecraft.getMinecraft().renderEngine.bindTexture(leafTextures); + + tessellator.startDrawingQuads(); + + float f6 = (float)this.particleTextureIndexX / 4.0F; + float f7 = f6 + 0.0624375F*4; + float f8 = (float)this.particleTextureIndexY / 4.0F; + float f9 = f8 + 0.0624375F*4; + float f10 = 0.1F * this.particleScale; + + if (this.particleIcon != null) + { + f6 = this.particleIcon.getMinU(); + f7 = this.particleIcon.getMaxU(); + f8 = this.particleIcon.getMinV(); + f9 = this.particleIcon.getMaxV(); + } + + // Fix which gets proper values for interpPos so the particles don't appear to move. + Entity player = Minecraft.getMinecraft().thePlayer; + this.interpPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)partialTicks; + this.interpPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)partialTicks; + this.interpPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)partialTicks; + + float f11 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX); + float f12 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY); + float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ); + float f14 = 1.0F; + + tessellator.setColorRGBA_F(this.particleRed * f14, this.particleGreen * f14, this.particleBlue * f14, this.particleAlpha); + tessellator.addVertexWithUV((double)(f11 - par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 - par5 * f10 - par7 * f10), (double)f7, (double)f9); + tessellator.addVertexWithUV((double)(f11 - par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 - par5 * f10 + par7 * f10), (double)f7, (double)f8); + tessellator.addVertexWithUV((double)(f11 + par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 + par5 * f10 + par7 * f10), (double)f6, (double)f8); + tessellator.addVertexWithUV((double)(f11 + par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 + par5 * f10 - par7 * f10), (double)f6, (double)f9); + + tessellator.draw(); + + GL11.glPopMatrix(); + + // Re-binds the normal particles so that the mod texture isn't on all of them + //Minecraft.getMinecraft().renderEngine.bindTexture(new ResourceLocation("textures/particle/particles.png")); + + //tessellator.startDrawingQuads(); + + } +} diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleGiantBubble.java b/src/main/java/electroblob/wizardry/client/particle/EntityMagicBubbleFX.java similarity index 82% rename from src/main/java/electroblob/wizardry/client/particle/ParticleGiantBubble.java rename to src/main/java/electroblob/wizardry/client/particle/EntityMagicBubbleFX.java index b469bcb2..48780022 100644 --- a/src/main/java/electroblob/wizardry/client/particle/ParticleGiantBubble.java +++ b/src/main/java/electroblob/wizardry/client/particle/EntityMagicBubbleFX.java @@ -1,19 +1,21 @@ package electroblob.wizardry.client.particle; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import electroblob.wizardry.Wizardry; -import net.minecraft.client.particle.Particle; +import net.minecraft.block.material.Material; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) -public class ParticleGiantBubble extends Particle +public class EntityMagicBubbleFX extends EntityFX { /** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would * be any, but I may as well.) */ public static final String NAME = Wizardry.MODID + "magicbubble"; - public ParticleGiantBubble(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) + public EntityMagicBubbleFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) { super(par1World, par2, par4, par6, par8, par10, par12); this.particleRed = 1.0F; @@ -44,7 +46,7 @@ public class ParticleGiantBubble extends Particle if (this.particleMaxAge-- <= 0) { - this.setExpired(); + this.setDead(); } } } diff --git a/src/main/java/electroblob/wizardry/client/particle/EntityMagicFireFX.java b/src/main/java/electroblob/wizardry/client/particle/EntityMagicFireFX.java new file mode 100644 index 00000000..d15ed7ec --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/particle/EntityMagicFireFX.java @@ -0,0 +1,108 @@ +package electroblob.wizardry.client.particle; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.Wizardry; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.world.World; + +@SideOnly(Side.CLIENT) +public class EntityMagicFireFX extends EntityFX +{ + /** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would + * be any, but I may as well.) */ + public static final String NAME = Wizardry.MODID + "magicfire"; + + /** the scale of the flame FX */ + private float flameScale; + + public EntityMagicFireFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, int maxAge, float scale) + { + super(par1World, par2, par4, par6, par8, par10, par12); + this.motionX = this.motionX * 0.009999999776482582D + par8; + this.motionY = this.motionY * 0.009999999776482582D + par10; + this.motionZ = this.motionZ * 0.009999999776482582D + par12; + double d6 = par2 + (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F); + d6 = par4 + (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F); + d6 = par6 + (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F); + this.flameScale = scale; + this.particleRed = this.particleGreen = this.particleBlue = 1.0F; + if(maxAge == 0){ + this.particleMaxAge = (int)(2.0D / (Math.random() * 0.8D + 0.2D)); + }else{ + this.particleMaxAge = maxAge; + } + this.noClip = true; + this.setParticleTextureIndex(48); + } + + public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7) + { + float f6 = ((float)this.particleAge + par2) / (float)this.particleMaxAge; + this.particleScale = this.flameScale * (1.0F - f6 * f6 * 0.5F); + super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7); + } + + public int getBrightnessForRender(float par1) + { + float f1 = ((float)this.particleAge + par1) / (float)this.particleMaxAge; + + if (f1 < 0.0F) + { + f1 = 0.0F; + } + + if (f1 > 1.0F) + { + f1 = 1.0F; + } + + int i = super.getBrightnessForRender(par1); + int j = i & 255; + int k = i >> 16 & 255; + j += (int)(f1 * 15.0F * 16.0F); + + if (j > 240) + { + j = 240; + } + + //return j | k << 16; + return 256; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) + { + return 1.0f; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() + { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) + { + this.setDead(); + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9599999785423279D; + this.motionY *= 0.9599999785423279D; + this.motionZ *= 0.9599999785423279D; + + if (this.onGround) + { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + } + } +} diff --git a/src/main/java/electroblob/wizardry/client/particle/EntityPathFX.java b/src/main/java/electroblob/wizardry/client/particle/EntityPathFX.java new file mode 100644 index 00000000..8111c43a --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/particle/EntityPathFX.java @@ -0,0 +1,181 @@ +package electroblob.wizardry.client.particle; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.spell.Clairvoyance; +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.entity.Entity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +@SideOnly(Side.CLIENT) +public class EntityPathFX extends EntityFX +{ + /** The name used to identify this particle, without gravity. Uses the mod id to avoid any possible conflicts (Not that there would + * be any, but I may as well.) */ + public static final String NAME = Wizardry.MODID + "path"; + + private static final ResourceLocation pathTextures = new ResourceLocation("wizardry:textures/particle/path_particles.png"); + + private final double originX, originY, originZ; + + public EntityPathFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float red, float green, float blue, int maxAge) + { + super(par1World, par2, par4, par6); + this.motionX = par8; + this.motionY = par10; + this.motionZ = par12; + // Set to a constant to remove the randomness from EntityFX. + this.particleScale = 1.25F; + this.particleMaxAge = maxAge; + this.noClip = true; + particleRed = red; + particleGreen = green; + particleBlue = blue; + this.originX = par2; + this.originY = par4; + this.originZ = par6; + } + + public EntityPathFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float red, float green, float blue) + { + super(par1World, par2, par4, par6); + this.motionX = par8; + this.motionY = par10; + this.motionZ = par12; + // Set to a constant to remove the randomness from EntityFX. + this.particleScale = 1.25F; + this.particleMaxAge = 48 + this.rand.nextInt(12); + this.noClip = true; + particleRed = red; + particleGreen = green; + particleBlue = blue; + this.originX = par2; + this.originY = par4; + this.originZ = par6; + } + + /** + * returns the bounding box for this entity + */ + public AxisAlignedBB getBoundingBox() + { + return null; + } + + /** + * Returns true if this entity should push and be pushed by other entities when colliding. + */ + public boolean canBePushed() + { + return false; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() + { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) + { + this.setDead(); + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (this.particleAge > this.particleMaxAge / 2) + { + this.setAlphaF(1.0F - 2 * (((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge)); + } + + if(this.particleAge % Clairvoyance.PARTICLE_MOVEMENT_INTERVAL == 0){ + this.setPosition(this.originX, this.originY, this.originZ); + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + } + + } + + /* There are 4 layers of particles, specified as 0-3 by the method below. + * - Layer 0 causes the normal particles.png to be bound to the render engine for normal particles. + * - Layer 1 causes the block textures to be bound to the render engine for digging fx and falling fx. + * - Layer 2 causes the item textures to be bound to the render engine for tool breaking fx, snowballpoofs, slime particles, etc. + * - Layer 3 is not used in vanilla minecraft and was presumably added by forge for exactly this reason. + * This means no texture is bound by vanilla minecraft, meaning you are free to do as you wish without possibly + * overwriting vanilla particles. Mod particles won't be overwritten anyway since they bind their own textures. + * It is of course important to bind the texture every time you render a custom particle, but I don't see how + * you could do it any other way, since you don't have access to EffectRenderer. + */ + @Override + public int getFXLayer() { + // This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer. + return 3; + } + + @Override + public void renderParticle(Tessellator tessellator, float partialTicks, float par3, float par4, float par5, float par6, float par7){ + + GL11.glPushMatrix(); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); + + RenderHelper.disableStandardItemLighting(); + + Minecraft.getMinecraft().renderEngine.bindTexture(pathTextures); + + tessellator.startDrawingQuads(); + + float f10 = 0.1F * this.particleScale; + + // Fix which gets proper values for interpPos so the particles don't appear to move. + Entity player = Minecraft.getMinecraft().thePlayer; + this.interpPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)partialTicks; + this.interpPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)partialTicks; + this.interpPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)partialTicks; + + float f11 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX); + float f12 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY); + float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ); + float f14 = 1.0F; + + tessellator.setColorRGBA_F(this.particleRed * f14, this.particleGreen * f14, this.particleBlue * f14, this.particleAlpha); + tessellator.addVertexWithUV((double)(f11 - par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 - par5 * f10 - par7 * f10), 1, 1); + tessellator.addVertexWithUV((double)(f11 - par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 - par5 * f10 + par7 * f10), 1, 0); + tessellator.addVertexWithUV((double)(f11 + par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 + par5 * f10 + par7 * f10), 0, 0); + tessellator.addVertexWithUV((double)(f11 + par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 + par5 * f10 - par7 * f10), 0, 1); + + tessellator.draw(); + + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_BLEND); + GL11.glPopMatrix(); + + } + + @Override + public int getBrightnessForRender(float par1) + { + return 15728880; + } + + @Override + public float getBrightness(float par1) + { + return 1.0F; + } +} diff --git a/src/main/java/electroblob/wizardry/client/particle/EntitySnowFX.java b/src/main/java/electroblob/wizardry/client/particle/EntitySnowFX.java new file mode 100644 index 00000000..e8ad6365 --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/particle/EntitySnowFX.java @@ -0,0 +1,131 @@ +package electroblob.wizardry.client.particle; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.Wizardry; +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.entity.Entity; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +@SideOnly(Side.CLIENT) +public class EntitySnowFX extends EntityFX +{ + /** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would + * be any, but I may as well.) */ + public static final String NAME = Wizardry.MODID + "snow"; + + private static final ResourceLocation snowTextures = new ResourceLocation("wizardry:textures/particle/snow_particles.png"); + + public EntitySnowFX(World world, double x, double y, double z, double velX, double velY, double velZ) + { + super(world, x, y, z, velX, velY, velZ); + this.particleRed = 1.0F; + this.particleGreen = 1.0F; + this.particleBlue = 1.0F; + this.setParticleTextureIndex(rand.nextInt(8)); + this.setSize(0.02F, 0.02F); + this.particleScale *= 0.6f; + this.motionX = velX; + this.motionY = velY; + this.motionZ = velZ; + this.particleMaxAge = 40 + rand.nextInt(10); + } + + public EntitySnowFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, int maxAge){ + this(par1World, par2, par4, par6, par8, par10, par12); + this.particleMaxAge = maxAge; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() + { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + + if (this.particleMaxAge-- <= 0) + { + this.setDead(); + } + } + + /** + * Public method to set private field particleTextureIndex. + */ + public void setParticleTextureIndex(int par1) + { + this.particleTextureIndexX = par1 % 4; + this.particleTextureIndexY = par1 / 4; + } + + @Override + public int getFXLayer() { + // This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer. + return 3; + } + + // Overwitten from entityfx to bind the new texture. + @Override + public void renderParticle(Tessellator tessellator, float partialTicks, float par3, float par4, float par5, float par6, float par7) + { + GL11.glPushMatrix(); + + // This stuff does the shading. The parameter does nothing apparently. + int j = this.getBrightnessForRender(0); + int k = j % 65536; + int l = j / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F); + + RenderHelper.disableStandardItemLighting(); + + Minecraft.getMinecraft().renderEngine.bindTexture(snowTextures); + + tessellator.startDrawingQuads(); + + float f6 = (float)this.particleTextureIndexX / 4.0F; + float f7 = f6 + 0.0624375F*4; + float f8 = (float)this.particleTextureIndexY / 4.0F; + float f9 = f8 + 0.0624375F*4; + float f10 = 0.1F * this.particleScale; + + if (this.particleIcon != null) + { + f6 = this.particleIcon.getMinU(); + f7 = this.particleIcon.getMaxU(); + f8 = this.particleIcon.getMinV(); + f9 = this.particleIcon.getMaxV(); + } + + // Fix which gets proper values for interpPos so the particles don't appear to move. + Entity player = Minecraft.getMinecraft().thePlayer; + this.interpPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)partialTicks; + this.interpPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)partialTicks; + this.interpPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)partialTicks; + + float f11 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX); + float f12 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY); + float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ); + float f14 = 1.0F; + + tessellator.setColorRGBA_F(this.particleRed * f14, this.particleGreen * f14, this.particleBlue * f14, this.particleAlpha); + tessellator.addVertexWithUV((double)(f11 - par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 - par5 * f10 - par7 * f10), (double)f7, (double)f9); + tessellator.addVertexWithUV((double)(f11 - par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 - par5 * f10 + par7 * f10), (double)f7, (double)f8); + tessellator.addVertexWithUV((double)(f11 + par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 + par5 * f10 + par7 * f10), (double)f6, (double)f8); + tessellator.addVertexWithUV((double)(f11 + par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 + par5 * f10 - par7 * f10), (double)f6, (double)f9); + + tessellator.draw(); + + GL11.glPopMatrix(); + + } +} diff --git a/src/main/java/electroblob/wizardry/client/particle/EntitySparkFX.java b/src/main/java/electroblob/wizardry/client/particle/EntitySparkFX.java new file mode 100644 index 00000000..4e5b7fa6 --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/particle/EntitySparkFX.java @@ -0,0 +1,117 @@ +package electroblob.wizardry.client.particle; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.Wizardry; +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.entity.Entity; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +@SideOnly(Side.CLIENT) +public class EntitySparkFX extends EntityFX +{ + /** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would + * be any, but I may as well.) */ + public static final String NAME = Wizardry.MODID + "spark"; + + private static final ResourceLocation sparkTextures = new ResourceLocation("wizardry:textures/particle/lightning_particles.png"); + + public EntitySparkFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12) + { + super(par1World, par2, par4, par6, par8, par10, par12); + this.particleRed = 1.0F; + this.particleGreen = 1.0F; + this.particleBlue = 1.0F; + this.setParticleTextureIndex(rand.nextInt(8)); + this.setSize(0.02F, 0.02F); + this.particleScale *= 1.4f; + this.motionX = par8 * 0.20000000298023224D + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.02F); + this.motionY = par10 * 0.20000000298023224D + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.02F); + this.motionZ = par12 * 0.20000000298023224D + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.02F); + this.particleMaxAge = 3; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() + { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if(this.particleAge++ >= this.particleMaxAge) + { + this.setDead(); + } + } + + /** + * Public method to set private field particleTextureIndex. + */ + public void setParticleTextureIndex(int par1) + { + this.particleTextureIndexY = par1; + } + + @Override + public int getFXLayer() { + // This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer. + return 3; + } + + // Overwitten from entityfx to bind the new texture. + @Override + public void renderParticle(Tessellator par1Tessellator, float partialTicks, float par3, float par4, float par5, float par6, float par7) + { + GL11.glPushMatrix(); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); + + RenderHelper.disableStandardItemLighting(); + + Minecraft.getMinecraft().renderEngine.bindTexture(sparkTextures); + + par1Tessellator.startDrawingQuads(); + + // Particles are now animated using a strip of 4 from left to right. + float f6 = (float)this.particleAge / 4.0F; + float f7 = f6 + 0.0624375F*4; + float f8 = (float)this.particleTextureIndexY / 8.0f; + float f9 = f8 + 0.0624375F*2; + float f10 = 0.1F * this.particleScale; + + // Fix which gets proper values for interpPos so the particles don't appear to move. + Entity player = Minecraft.getMinecraft().thePlayer; + this.interpPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)partialTicks; + this.interpPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)partialTicks; + this.interpPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)partialTicks; + + float f11 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX); + float f12 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY); + float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ); + float f14 = 1.0F; + + par1Tessellator.setColorRGBA_F(this.particleRed * f14, this.particleGreen * f14, this.particleBlue * f14, this.particleAlpha); + par1Tessellator.addVertexWithUV((double)(f11 - par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 - par5 * f10 - par7 * f10), (double)f7, (double)f9); + par1Tessellator.addVertexWithUV((double)(f11 - par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 - par5 * f10 + par7 * f10), (double)f7, (double)f8); + par1Tessellator.addVertexWithUV((double)(f11 + par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 + par5 * f10 + par7 * f10), (double)f6, (double)f8); + par1Tessellator.addVertexWithUV((double)(f11 + par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 + par5 * f10 - par7 * f10), (double)f6, (double)f9); + + par1Tessellator.draw(); + + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_BLEND); + GL11.glPopMatrix(); + + } +} diff --git a/src/main/java/electroblob/wizardry/client/particle/EntitySparkleFX.java b/src/main/java/electroblob/wizardry/client/particle/EntitySparkleFX.java new file mode 100644 index 00000000..9dc164fc --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/particle/EntitySparkleFX.java @@ -0,0 +1,203 @@ +package electroblob.wizardry.client.particle; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.Wizardry; +import net.minecraft.client.Minecraft; +import net.minecraft.client.particle.EffectRenderer; +import net.minecraft.client.particle.EntityFX; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.entity.Entity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +@SideOnly(Side.CLIENT) +public class EntitySparkleFX extends EntityFX +{ + /** The name used to identify this particle, without gravity. Uses the mod id to avoid any possible conflicts (Not that there would + * be any, but I may as well.) */ + public static final String NAME = Wizardry.MODID + "sparkle"; + + /** The name used to identify this particle, with gravity. Uses the mod id to avoid any possible conflicts (Not that there would + * be any, but I may as well.) */ + public static final String NAME_GRAVITY = Wizardry.MODID + "sparkleGravity"; + + private static final ResourceLocation sparkleTextures = new ResourceLocation("wizardry:textures/particle/sparkle_particles.png"); + + private boolean gravity = false; + + public EntitySparkleFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float red, float green, float blue, int maxAge) + { + super(par1World, par2, par4, par6); + this.motionX = par8; + this.motionY = par10; + this.motionZ = par12; + this.particleScale *= 0.75F; + this.particleMaxAge = maxAge; + this.noClip = true; + particleRed = red; + particleGreen = green; + particleBlue = blue; + } + + public EntitySparkleFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float red, float green, float blue) + { + super(par1World, par2, par4, par6); + this.motionX = par8; + this.motionY = par10; + this.motionZ = par12; + this.particleScale *= 0.75F; + this.particleMaxAge = 48 + this.rand.nextInt(12); + this.noClip = true; + particleRed = red; + particleGreen = green; + particleBlue = blue; + } + + public EntitySparkleFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float red, float green, float blue, boolean doGravity){ + this(par1World, par2, par4, par6, par8, par10, par12, red, green, blue); + this.gravity = doGravity; + } + + public EntitySparkleFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float red, float green, float blue, int maxAge, boolean doGravity){ + this(par1World, par2, par4, par6, par8, par10, par12, red, green, blue, maxAge); + this.gravity = doGravity; + } + + /** + * returns the bounding box for this entity + */ + public AxisAlignedBB getBoundingBox() + { + return null; + } + + /** + * Returns true if this entity should push and be pushed by other entities when colliding. + */ + public boolean canBePushed() + { + return false; + } + + @Override + public void setParticleTextureIndex(int par1) + { + this.particleTextureIndexX = par1 % 4; + this.particleTextureIndexY = par1 / 4; + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() + { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) + { + this.setDead(); + } + + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.9800000190734863D; + this.motionZ *= 0.9800000190734863D; + if(this.gravity){ + this.motionY -= 0.05d; + } + + if (this.particleAge > this.particleMaxAge / 2) + { + this.setAlphaF(1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge); + } + + this.setParticleTextureIndex((this.particleAge * 11)/this.particleMaxAge); + + } + + /* There are 4 layers of particles, specified as 0-3 by the method below. + * - Layer 0 causes the normal particles.png to be bound to the render engine for normal particles. + * - Layer 1 causes the block textures to be bound to the render engine for digging fx and falling fx. + * - Layer 2 causes the item textures to be bound to the render engine for tool breaking fx, snowballpoofs, slime particles, etc. + * - Layer 3 is not used in vanilla minecraft and was presumably added by forge for exactly this reason. + * This means no texture is bound by vanilla minecraft, meaning you are free to do as you wish without possibly + * overwriting vanilla particles. Mod particles won't be overwritten anyway since they bind their own textures. + * It is of course important to bind the texture every time you render a custom particle, but I don't see how + * you could do it any other way, since you don't have access to EffectRenderer. + */ + @Override + public int getFXLayer() { + // This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer. + return 3; + } + + @Override + public void renderParticle(Tessellator tessellator, float partialTicks, float par3, float par4, float par5, float par6, float par7){ + + GL11.glPushMatrix(); + + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); + + RenderHelper.disableStandardItemLighting(); + + Minecraft.getMinecraft().renderEngine.bindTexture(sparkleTextures); + + tessellator.startDrawingQuads(); + + float f6 = (float)this.particleTextureIndexX / 4.0F; + float f7 = f6 + 0.0624375F*4; + float f8 = (float)this.particleTextureIndexY / 4.0F; + float f9 = f8 + 0.0624375F*4; + float f10 = 0.1F * this.particleScale; + + if (this.particleIcon != null) + { + f6 = this.particleIcon.getMinU(); + f7 = this.particleIcon.getMaxU(); + f8 = this.particleIcon.getMinV(); + f9 = this.particleIcon.getMaxV(); + } + + // Fix which gets proper values for interpPos so the particles don't appear to move. + Entity player = Minecraft.getMinecraft().thePlayer; + this.interpPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)partialTicks; + this.interpPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)partialTicks; + this.interpPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)partialTicks; + + float f11 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX); + float f12 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY); + float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ); + float f14 = 1.0F; + + tessellator.setColorRGBA_F(this.particleRed * f14, this.particleGreen * f14, this.particleBlue * f14, this.particleAlpha); + tessellator.addVertexWithUV((double)(f11 - par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 - par5 * f10 - par7 * f10), (double)f7, (double)f9); + tessellator.addVertexWithUV((double)(f11 - par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 - par5 * f10 + par7 * f10), (double)f7, (double)f8); + tessellator.addVertexWithUV((double)(f11 + par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 + par5 * f10 + par7 * f10), (double)f6, (double)f8); + tessellator.addVertexWithUV((double)(f11 + par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 + par5 * f10 - par7 * f10), (double)f6, (double)f9); + + tessellator.draw(); + + GL11.glPopMatrix(); + + } + + @Override + public int getBrightnessForRender(float par1) + { + return 15728880; + } + + @Override + public float getBrightness(float par1) + { + return 1.0F; + } +} diff --git a/src/main/java/electroblob/wizardry/client/particle/EntityTornadoFX.java b/src/main/java/electroblob/wizardry/client/particle/EntityTornadoFX.java new file mode 100644 index 00000000..dc75b635 --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/particle/EntityTornadoFX.java @@ -0,0 +1,135 @@ +package electroblob.wizardry.client.particle; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.Wizardry; +import net.minecraft.block.Block; +import net.minecraft.client.particle.EntityDiggingFX; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.init.Blocks; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.world.World; + +@SideOnly(Side.CLIENT) +public class EntityTornadoFX extends EntityDiggingFX +{ + /** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would + * be any, but I may as well.) */ + public static final String NAME = Wizardry.MODID + "tornado"; + + private boolean gravity = false; + private double angle; + private double radius; + private double speed; + private double velX, velZ; + private boolean fullBrightness = false; + + public EntityTornadoFX(World world, int maxAge, double originX, double originZ, double radius, double yPos, double velX, double velZ, Block block, int metadata, int side) + { + super(world, 0, 0, 0, 0, 0, 0, block, metadata, side); + this.angle = this.rand.nextDouble() * Math.PI * 2; + double x = originX - Math.cos(angle)*radius; + double z = originZ + radius*Math.sin(angle); + this.radius = radius; + this.setPosition(x, yPos, z); + //this.particleScale *= 0.75F; + this.particleMaxAge = maxAge; + this.noClip = true; + // Grass has special treatment, since it has a colourised top but the rest is normal. + if(block != Blocks.grass || side == 1) this.setColour(block.getRenderColor(side)); + + if(block.getLightValue() == 0){ + this.particleRed *= 0.75; + this.particleGreen *= 0.75; + this.particleBlue *= 0.75; + }else{ + this.fullBrightness = true; + } + + speed = rand.nextDouble()*2 + 1; + this.velX = velX; + this.velZ = velZ; + } + + public EntityTornadoFX(World world, double x, double y, double z, double vx, double vy, double vz, float red, float green, float blue) + { + super(world, x, y, z, vx, vy, vz, Blocks.dirt, 0); + //this.particleScale *= 0.75F; + this.particleMaxAge = 48 + this.rand.nextInt(12); + this.noClip = true; + particleRed = red; + particleGreen = green; + particleBlue = blue; + } + + public void setColour(int par1) + { + float f = (float)((par1 & 16711680) >> 16) / 255.0F; + float f1 = (float)((par1 & 65280) >> 8) / 255.0F; + float f2 = (float)((par1 & 255) >> 0) / 255.0F; + float f3 = 1.0F; + this.setRBGColorF(f * f3, f1 * f3, f2 * f3); + } + + /** + * returns the bounding box for this entity + */ + public AxisAlignedBB getBoundingBox() + { + return null; + } + + /** + * Returns true if this entity should push and be pushed by other entities when colliding. + */ + public boolean canBePushed() + { + return false; + } + + @Override + public void onUpdate() + { + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + + if (this.particleAge++ >= this.particleMaxAge) + { + this.setDead(); + } + + // This is in radians per tick... + double omega = Math.signum(speed) * ((Math.PI*2)/20 - speed/(20*radius)); + + // v = r times omega; therefore the normalised velocity vector needs to be r times the angle increment / 2 pi. + this.angle += omega; + + this.motionZ = radius * omega * Math.cos(angle); + this.motionX = radius * omega * Math.sin(angle); + this.moveEntity(motionX + velX, 0, motionZ + velZ); + + if(this.gravity){ + this.motionY -= 0.05d; + } + + if (this.particleAge > this.particleMaxAge / 2) + { + this.setAlphaF(1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge); + } + + } + + @Override + public int getBrightnessForRender(float par1) + { + return fullBrightness ? 15728880 : super.getBrightnessForRender(par1); + } + + @Override + public float getBrightness(float par1) + { + return fullBrightness ? 1.0F : super.getBrightness(par1); + } + +} diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleBlizzard.java b/src/main/java/electroblob/wizardry/client/particle/ParticleBlizzard.java deleted file mode 100644 index 4ea3114b..00000000 --- a/src/main/java/electroblob/wizardry/client/particle/ParticleBlizzard.java +++ /dev/null @@ -1,72 +0,0 @@ -package electroblob.wizardry.client.particle; - -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class ParticleBlizzard extends ParticleSnow { - - private double angle; - private double radius; - private double speed; - - public ParticleBlizzard(World world, int maxAge, double originX, double originZ, double radius, double yPos){ - super(world, 0, 0, 0, 0, 0, 0, maxAge); - this.angle = this.rand.nextDouble() * Math.PI * 2; - double x = originX - Math.cos(angle)*radius; - double z = originZ + radius*Math.sin(angle); - this.radius = radius; - this.setPosition(x, yPos, z); - this.prevPosX = x; - this.prevPosY = yPos; - this.prevPosZ = z; - if(rand.nextBoolean()){ - speed = rand.nextDouble()*2 + 1; - }else{ - speed = rand.nextDouble()*-2 - 1; - } - this.multipleParticleScaleBy(1.5f); - } - - @Override - public void init(){ - super.init(); - this.fullBrightness = true; - } - -// @Override -// public void renderParticle(VertexBuffer buffer, Entity entity, float partialTicks, float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ){ -// if(this.particleAge < this.particleMaxAge / 3 || (this.particleAge + this.particleMaxAge) / 3 % 2 == 0){ -// super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ); -// } -// } - - @Override - public void onUpdate(){ - - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; - - if(this.particleAge++ >= this.particleMaxAge){ - this.setExpired(); - } - - // This is in radians per tick... - double omega = Math.signum(speed) * ((Math.PI*2)/20 - speed/(20*radius)); - - // v = r times omega; therefore the normalised velocity vector needs to be r times the angle increment / 2 pi. - this.angle += omega; - - this.motionY -= 0.04D * (double)this.particleGravity; - this.motionZ = radius * omega * Math.cos(angle); - this.motionX = radius * omega * Math.sin(angle); - this.moveEntity(motionX, motionY, motionZ); - - if(this.particleAge > this.particleMaxAge / 2){ - this.setAlphaF(1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge); - } - - } -} diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleCustomTexture.java b/src/main/java/electroblob/wizardry/client/particle/ParticleCustomTexture.java deleted file mode 100644 index 3d5fa986..00000000 --- a/src/main/java/electroblob/wizardry/client/particle/ParticleCustomTexture.java +++ /dev/null @@ -1,195 +0,0 @@ -package electroblob.wizardry.client.particle; - -import java.util.List; - -import org.lwjgl.opengl.GL11; - -import net.minecraft.client.Minecraft; -import net.minecraft.client.particle.Particle; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.client.renderer.RenderHelper; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.VertexBuffer; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.entity.Entity; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -/** - * Abstract superclass for all particles that use custom textures. This is intended to centralise as much code as - * possible; all subclasses need to do is to define the texture to use, how the frames are arranged (and which to - * choose), and any properties like gravity and collisions. - * @author Electroblob - * @since Wizardry 1.2 - */ -@SideOnly(Side.CLIENT) -public abstract class ParticleCustomTexture extends Particle { - - /** True if the particle always renders at full brightness. Defaults to false. */ - protected boolean fullBrightness = false; - - public ParticleCustomTexture(World world, double x, double y, double z, double vx, double vy, double vz){ - super(world, x, y, z, vx, vy, vz); - this.motionX = vx; - this.motionY = vy; - this.motionZ = vz; - this.init(); - } - - public ParticleCustomTexture(World world, double x, double y, double z, double vx, double vy, double vz, int maxAge){ - this(world, x, y, z, vx, vy, vz); - this.particleMaxAge = maxAge; - } - - /** Called from both constructors to set constants, avoiding duplicate code. Common fields to set here - * include: particleScale, particleGravity, canCollide, fullBrightness and setting the texture index. */ - public abstract void init(); - /** Returns a ResourceLocation for the particle's texture sheet. Do not create a new ResourceLocation in this - * method, only return a constant. */ - public abstract ResourceLocation getTexture(); - /** Returns how many 'frames' there are in the x direction on the texture. */ - protected abstract int getXFrames(); - /** Returns how many 'frames' there are in the y direction on the texture. */ - protected abstract int getYFrames(); - - /* There are 4 layers of particles, specified as 0-3 by the method below. - * - Layer 0 causes the normal particles.png to be bound to the render engine for normal particles. - * - Layer 1 causes the block textures to be bound to the render engine for digging fx and falling fx. - * - Layer 2 causes the item textures to be bound to the render engine for tool breaking fx, snowballpoofs, slime particles, etc. - * - Layer 3 is not used in vanilla minecraft and was presumably added by forge for exactly this reason. - * This means no texture is bound by vanilla minecraft, meaning you are free to do as you wish without possibly - * overwriting vanilla particles. Mod particles won't be overwritten anyway since they bind their own textures. - * It is of course important to bind the texture every time you render a custom particle, but I don't see how - * you could do it any other way, since you don't have access to EffectRenderer. */ - @Override - public int getFXLayer() { - // This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer. - return 3; - } - - @Override - public void setParticleTextureIndex(int index){ - this.particleTextureIndexX = index % getXFrames(); - this.particleTextureIndexY = index / getYFrames(); - } - - // Overridden to fix the bug with vanilla that makes particles frictionless. (y != y... seriously, Mojang?) - @Override - public void moveEntity(double x, double y, double z){ - - double d0 = y; - - if (this.canCollide) - { - List list = this.worldObj.getCollisionBoxes((Entity)null, this.getEntityBoundingBox().addCoord(x, y, z)); - - for (AxisAlignedBB axisalignedbb : list) - { - y = axisalignedbb.calculateYOffset(this.getEntityBoundingBox(), y); - } - - this.setEntityBoundingBox(this.getEntityBoundingBox().offset(0.0D, y, 0.0D)); - - for (AxisAlignedBB axisalignedbb1 : list) - { - x = axisalignedbb1.calculateXOffset(this.getEntityBoundingBox(), x); - } - - this.setEntityBoundingBox(this.getEntityBoundingBox().offset(x, 0.0D, 0.0D)); - - for (AxisAlignedBB axisalignedbb2 : list) - { - z = axisalignedbb2.calculateZOffset(this.getEntityBoundingBox(), z); - } - - this.setEntityBoundingBox(this.getEntityBoundingBox().offset(0.0D, 0.0D, z)); - } - else - { - this.setEntityBoundingBox(this.getEntityBoundingBox().offset(x, y, z)); - } - - this.resetPositionToBB(); - this.isCollided = d0 != y && d0 < 0.0D; - - /* Can never be true! - But this doesn't seem to make any difference anyway. - if (x != x) - { - this.motionX = 0.0D; - } - - if (z != z) - { - this.motionZ = 0.0D; - } - */ - } - - // Overridden to bind the new texture. I think this can be done with TextureAtlasSprite, but this works as it is - // so I'm not changing it for the time being. - @Override - public void renderParticle(VertexBuffer buffer, Entity viewer, float partialTicks, float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ){ - - GlStateManager.pushMatrix(); - GlStateManager.pushAttrib(); - - this.applyGLStateChanges(); - - // This stuff does the shading. It vanilla does this later on for each point, but this also seems to work. - int brightness = this.getBrightnessForRender(partialTicks); - int lightmapX = brightness % 65536; - int lightmapY = brightness / 65536; - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)lightmapX / 1.0F, (float)lightmapY / 1.0F); - - RenderHelper.disableStandardItemLighting(); - - Minecraft.getMinecraft().getTextureManager().bindTexture(getTexture()); - - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); - - float u1 = (float)this.particleTextureIndexX / (float)getXFrames(); - float u2 = u1 + 1.0f/getXFrames(); - float v1 = (float)this.particleTextureIndexY / (float)getYFrames(); - float v2 = v1 + 1.0f/getYFrames(); - float scale = 0.1F * this.particleScale; - - // I'm pretty sure these were always static. - Particle.interpPosX = viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * (double)partialTicks; - Particle.interpPosY = viewer.lastTickPosY + (viewer.posY - viewer.lastTickPosY) * (double)partialTicks; - Particle.interpPosZ = viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * (double)partialTicks; - - float x = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX); - float y = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY); - float z = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ); - - buffer.pos((double)(x - rotationX * scale - rotationXY * scale), (double)(y - rotationZ * scale), (double)(z - rotationYZ * scale - rotationXZ * scale)).tex(u2, v2).color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex(); - buffer.pos((double)(x - rotationX * scale + rotationXY * scale), (double)(y + rotationZ * scale), (double)(z - rotationYZ * scale + rotationXZ * scale)).tex(u2, v1).color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex(); - buffer.pos((double)(x + rotationX * scale + rotationXY * scale), (double)(y + rotationZ * scale), (double)(z + rotationYZ * scale + rotationXZ * scale)).tex(u1, v1).color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex(); - buffer.pos((double)(x + rotationX * scale - rotationXY * scale), (double)(y - rotationZ * scale), (double)(z + rotationYZ * scale - rotationXZ * scale)).tex(u1, v2).color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex();; - - Tessellator.getInstance().draw(); - - this.undoGLStateChanges(); - - GlStateManager.popAttrib(); - GlStateManager.popMatrix(); - - } - - /** Override to add any GL state changes, like blending. Does nothing by default. State changes should be - * done using GLStateManager, not using GL11 directly (as is the case with all rendering code now). */ - public void applyGLStateChanges(){} - - /** Override to undo any GL state changes, like blending. Does nothing by default. State changes should be - * done using GLStateManager, not using GL11 directly (as is the case with all rendering code now). */ - public void undoGLStateChanges(){} - - @Override - public int getBrightnessForRender(float partialTick){ - return fullBrightness ? 15728880 : super.getBrightnessForRender(partialTick); - } -} diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleIce.java b/src/main/java/electroblob/wizardry/client/particle/ParticleIce.java deleted file mode 100644 index 3332db15..00000000 --- a/src/main/java/electroblob/wizardry/client/particle/ParticleIce.java +++ /dev/null @@ -1,34 +0,0 @@ -package electroblob.wizardry.client.particle; - -import electroblob.wizardry.Wizardry; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class ParticleIce extends ParticleCustomTexture { - - private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/ice_particles.png"); - - public ParticleIce(World world, double x, double y, double z, double vx, double vy, double vz){ - super(world, x, y, z, vx, vy, vz); - } - - public ParticleIce(World world, double x, double y, double z, double vx, double vy, double vz, int maxAge){ - super(world, x, y, z, vx, vy, vz, maxAge); - } - - @Override - public void init(){ - this.setParticleTextureIndex(rand.nextInt(8)); - this.particleScale *= 0.75f; - this.particleGravity = 1; - this.canCollide = true; - this.fullBrightness = true; - } - - @Override public ResourceLocation getTexture(){ return TEXTURE; } - @Override protected int getXFrames(){ return 4; } - @Override protected int getYFrames(){ return 4; } -} diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleLeaf.java b/src/main/java/electroblob/wizardry/client/particle/ParticleLeaf.java deleted file mode 100644 index 0292dddf..00000000 --- a/src/main/java/electroblob/wizardry/client/particle/ParticleLeaf.java +++ /dev/null @@ -1,33 +0,0 @@ -package electroblob.wizardry.client.particle; - -import electroblob.wizardry.Wizardry; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class ParticleLeaf extends ParticleCustomTexture { - - private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/leaf_particles.png"); - - public ParticleLeaf(World world, double x, double y, double z, double vx, double vy, double vz){ - super(world, x, y, z, vx, vy, vz); - } - - public ParticleLeaf(World world, double x, double y, double z, double vx, double vy, double vz, int maxAge){ - super(world, x, y, z, vx, vy, vz, maxAge); - } - - @Override - public void init() { - this.setParticleTextureIndex(rand.nextInt(16)); - this.particleScale *= 1.4f; - this.particleGravity = 0; - this.canCollide = true; - } - - @Override public ResourceLocation getTexture(){ return TEXTURE; } - @Override protected int getXFrames(){ return 4; } - @Override protected int getYFrames(){ return 4; } -} diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleMagicFlame.java b/src/main/java/electroblob/wizardry/client/particle/ParticleMagicFlame.java deleted file mode 100644 index 755fa4db..00000000 --- a/src/main/java/electroblob/wizardry/client/particle/ParticleMagicFlame.java +++ /dev/null @@ -1,47 +0,0 @@ -package electroblob.wizardry.client.particle; - -import net.minecraft.client.particle.Particle; -import net.minecraft.client.renderer.VertexBuffer; -import net.minecraft.entity.Entity; -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class ParticleMagicFlame extends Particle { - - /** The scale of the flame particle */ - private float flameScale; - - public ParticleMagicFlame(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, int maxAge, float scale) - { - super(par1World, par2, par4, par6, par8, par10, par12); - this.motionX = this.motionX * 0.009999999776482582D + par8; - this.motionY = this.motionY * 0.009999999776482582D + par10; - this.motionZ = this.motionZ * 0.009999999776482582D + par12; - this.flameScale = scale; - this.particleRed = this.particleGreen = this.particleBlue = 1.0F; - if(maxAge == 0){ - this.particleMaxAge = (int)(2.0D / (Math.random() * 0.8D + 0.2D)); - }else{ - this.particleMaxAge = maxAge; - } - // IDEA: Make the particles for ray spells collide properly and not spawn on the other side of stuff. - this.canCollide = false; - this.setParticleTextureIndex(48); - } - - @Override - public void renderParticle(VertexBuffer buffer, Entity entity, float partialTicks, float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ) - { - float f6 = ((float)this.particleAge + partialTicks) / (float)this.particleMaxAge; - this.particleScale = this.flameScale * (1.0F - f6 * f6 * 0.5F); - super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ); - } - - @Override - public int getBrightnessForRender(float par1) - { - return 256; - } -} diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticlePath.java b/src/main/java/electroblob/wizardry/client/particle/ParticlePath.java deleted file mode 100644 index cf7b2c6e..00000000 --- a/src/main/java/electroblob/wizardry/client/particle/ParticlePath.java +++ /dev/null @@ -1,93 +0,0 @@ -package electroblob.wizardry.client.particle; - -import org.lwjgl.opengl.GL11; - -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.spell.Clairvoyance; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class ParticlePath extends ParticleCustomTexture { - - private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/path_particles.png"); - - private final double originX, originY, originZ; - - public ParticlePath(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g, float b){ - super(world, x, y, z, vx, vy, vz); - this.setRBGColorF(r, g, b); - this.originX = x; - this.originY = y; - this.originZ = z; - } - - public ParticlePath(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g, float b, int maxAge){ - super(world, x, y, z, vx, vy, vz, maxAge); - this.setRBGColorF(r, g, b); - this.originX = x; - this.originY = y; - this.originZ = z; - } - - @Override - public void init(){ - this.setParticleTextureIndex(0); - // Set to a constant to remove the randomness from Particle. - this.particleScale = 1.25f; - this.particleGravity = 0; - this.fullBrightness = true; - this.canCollide = false; - } - - @Override public ResourceLocation getTexture(){ return TEXTURE; } - @Override protected int getXFrames(){ return 1; } - @Override protected int getYFrames(){ return 1; } - - @Override - public void onUpdate(){ - - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; - - if (this.particleAge++ >= this.particleMaxAge) - { - this.setExpired(); - } - - this.moveEntity(this.motionX, this.motionY, this.motionZ); - - // Fading - if(this.particleAge > this.particleMaxAge / 2){ - this.setAlphaF(1.0F - 2 * (((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge)); - } - - if(this.particleAge % Clairvoyance.PARTICLE_MOVEMENT_INTERVAL == 0){ - this.setPosition(this.originX, this.originY, this.originZ); - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; - } - - } - - @Override - public void applyGLStateChanges(){ - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - // TESTME: Are these two actually necessary? - GlStateManager.disableLighting(); - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); - } - - @Override - public void undoGLStateChanges(){ - GlStateManager.disableBlend(); - GlStateManager.enableLighting(); - } -} diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleRotatingSparkle.java b/src/main/java/electroblob/wizardry/client/particle/ParticleRotatingSparkle.java deleted file mode 100644 index eadc09bb..00000000 --- a/src/main/java/electroblob/wizardry/client/particle/ParticleRotatingSparkle.java +++ /dev/null @@ -1,59 +0,0 @@ -package electroblob.wizardry.client.particle; - -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class ParticleRotatingSparkle extends ParticleSparkle { - - private double angle; - private double radius; - private double speed; - - public ParticleRotatingSparkle(World world, int maxAge, double originX, double originZ, double radius, double yPos, float r, float g , float b){ - super(world, 0, 0, 0, 0, 0, 0, r, g, b, maxAge); - this.angle = this.rand.nextDouble() * Math.PI * 2; - double x = originX - Math.cos(angle)*radius; - double z = originZ + radius*Math.sin(angle); - this.radius = radius; - this.setPosition(x, yPos, z); - this.prevPosX = x; - this.prevPosY = yPos; - this.prevPosZ = z; - if(rand.nextBoolean()){ - speed = rand.nextDouble()*2 + 1; - }else{ - speed = rand.nextDouble()*-2 - 1; - } - this.multipleParticleScaleBy(1.5f); - } - - @Override - public void onUpdate(){ - - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; - - if(this.particleAge++ >= this.particleMaxAge){ - this.setExpired(); - } - - // This is in radians per tick... - double omega = Math.signum(speed) * ((Math.PI*2)/20 - speed/(20*radius)); - - // v = r times omega; therefore the normalised velocity vector needs to be r times the angle increment / 2 pi. - this.angle += omega; - - this.motionY -= 0.04D * (double)this.particleGravity; - this.motionZ = radius * omega * Math.cos(angle); - this.motionX = radius * omega * Math.sin(angle); - this.moveEntity(motionX, motionY, motionZ); - - if(this.particleAge > this.particleMaxAge / 2){ - this.setAlphaF(1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge); - } - - } -} diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleSnow.java b/src/main/java/electroblob/wizardry/client/particle/ParticleSnow.java deleted file mode 100644 index a1455c22..00000000 --- a/src/main/java/electroblob/wizardry/client/particle/ParticleSnow.java +++ /dev/null @@ -1,33 +0,0 @@ -package electroblob.wizardry.client.particle; - -import electroblob.wizardry.Wizardry; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class ParticleSnow extends ParticleCustomTexture { - - private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/snow_particles.png"); - - public ParticleSnow(World world, double x, double y, double z, double vx, double vy, double vz){ - super(world, x, y, z, vx, vy, vz); - } - - public ParticleSnow(World world, double x, double y, double z, double vx, double vy, double vz, int maxAge){ - super(world, x, y, z, vx, vy, vz, maxAge); - } - - @Override - public void init(){ - this.setParticleTextureIndex(rand.nextInt(8)); - this.particleScale *= 0.6f; - this.particleGravity = 0; - this.canCollide = true; - } - - @Override public ResourceLocation getTexture(){ return TEXTURE; } - @Override protected int getXFrames(){ return 4; } - @Override protected int getYFrames(){ return 4; } -} diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleSpark.java b/src/main/java/electroblob/wizardry/client/particle/ParticleSpark.java deleted file mode 100644 index 57965ed2..00000000 --- a/src/main/java/electroblob/wizardry/client/particle/ParticleSpark.java +++ /dev/null @@ -1,58 +0,0 @@ -package electroblob.wizardry.client.particle; - -import org.lwjgl.opengl.GL11; - -import electroblob.wizardry.Wizardry; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class ParticleSpark extends ParticleCustomTexture { - - private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/lightning_particles.png"); - - public ParticleSpark(World world, double x, double y, double z, double vx, double vy, double vz){ - // Max age is always 3. - super(world, x, y, z, vx, vy, vz, 3); - } - - @Override - public void init(){ - // Multiplied by 4 because the index works slightly differently for spark particles. - this.setParticleTextureIndex(rand.nextInt(8)*4); - this.particleScale *= 1.4f; - this.fullBrightness = true; - this.canCollide = false; - } - - @Override - public void onUpdate(){ - super.onUpdate(); - // Well this is handy! Looks like vanilla uses the texture index like this too. - this.nextTextureIndexX(); - } - - @Override public ResourceLocation getTexture(){ return TEXTURE; } - @Override protected int getXFrames(){ return 4; } - @Override protected int getYFrames(){ return 8; } - - @Override - public void applyGLStateChanges(){ - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - // TESTME: Are these two actually necessary? - GlStateManager.disableLighting(); - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); - } - - @Override - public void undoGLStateChanges(){ - GlStateManager.disableBlend(); - GlStateManager.enableLighting(); - } - -} diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleSparkle.java b/src/main/java/electroblob/wizardry/client/particle/ParticleSparkle.java deleted file mode 100644 index da0e461d..00000000 --- a/src/main/java/electroblob/wizardry/client/particle/ParticleSparkle.java +++ /dev/null @@ -1,96 +0,0 @@ -package electroblob.wizardry.client.particle; - -import electroblob.wizardry.Wizardry; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class ParticleSparkle extends ParticleCustomTexture { - - /* I have now figured out what particle factories are for: they separate out the individual uses of the varargs - * parameter in spawnParticle so they are kept with the particle class. For my purposes, it would be easier to do - * that in the particle spawning method itself. */ - - private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/sparkle_particles.png"); - - // NOTE: Uncomment once 2.1.0 is released - //private final float initialRed; - //private final float initialGreen; - //private final float initialBlue; - - // TODO: Assign these via the constructors, as part of the refactoring for particle parameters. - // NOTE: Uncomment once 2.1.0 is released -// private final float fadeRed = 1; -// private final float fadeGreen = 1; -// private final float fadeBlue = 0; - - public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g, float b){ - super(world, x, y, z, vx, vy, vz); - this.setRBGColorF(r, g, b); - // NOTE: Uncomment once 2.1.0 is released - //initialRed = r; - //initialGreen = g; - //initialBlue = b; - this.particleMaxAge = 48 + this.rand.nextInt(12); - } - - public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g, float b, int maxAge){ - super(world, x, y, z, vx, vy, vz, maxAge); - this.setRBGColorF(r, g, b); - // NOTE: Uncomment once 2.1.0 is released - //initialRed = r; - //initialGreen = g; - //initialBlue = b; - } - - public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g, float b, boolean doGravity){ - this(world, x, y, z, vx, vy, vz, r, g, b); - this.particleGravity = doGravity ? 1 : 0; - } - - public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g, float b, int maxAge, boolean doGravity){ - this(world, x, y, z, vx, vy, vz, r, g, b, maxAge); - this.particleGravity = doGravity ? 1 : 0; - } - - @Override - public void init(){ - this.setParticleTextureIndex(rand.nextInt(16)); - this.particleScale *= 0.75f; - this.particleGravity = 0; - this.canCollide = false; - this.fullBrightness = true; - } - - @Override public ResourceLocation getTexture(){ return TEXTURE; } - @Override protected int getXFrames(){ return 4; } - @Override protected int getYFrames(){ return 4; } - - @Override - public void onUpdate(){ - - super.onUpdate(); - // Fading - if(this.particleAge > this.particleMaxAge / 2){ - this.setAlphaF(1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge); - } - // Colour fading TODO Uncomment once 2.1.0 is released -// float ageFraction = (float)this.particleAge / (float)this.particleMaxAge; -// this.setRBGColorF(this.initialRed + (this.fadeRed - this.initialRed)*ageFraction, -// this.initialGreen + (this.fadeGreen - this.initialGreen)*ageFraction, -// this.initialBlue + (this.fadeBlue - this.initialBlue)*ageFraction); - - this.setParticleTextureIndex((this.particleAge * 11)/this.particleMaxAge); - } - - /* - * As a side note, I see a lot of magic mods with fancy-looking particle effects that really seem to 'glow'. It's - * actually not that hard - you simply create a reasonably high-res texture with translucency and then set the - * OpenGL blend function to something like SRC_ALPHA, SRC_ALPHA or ONE, ONE. The thing is... they're not very - * Minecraft-y. I still maintain that part of wizardry's appeal is that it stays true to the game's pixelated charm, - * rather than trying to make it something it's not. Still, the newer textures are much better than the defaults I - * used to use. - */ -} diff --git a/src/main/java/electroblob/wizardry/client/particle/ParticleTornado.java b/src/main/java/electroblob/wizardry/client/particle/ParticleTornado.java deleted file mode 100644 index 1dd5635b..00000000 --- a/src/main/java/electroblob/wizardry/client/particle/ParticleTornado.java +++ /dev/null @@ -1,83 +0,0 @@ -package electroblob.wizardry.client.particle; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.particle.ParticleDigging; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -@SideOnly(Side.CLIENT) -public class ParticleTornado extends ParticleDigging { - - private double angle; - private double radius; - private double speed; - /** Velocity of the tornado itself; in other words the velocity of the point the particle circles around. */ - private double velX, velZ; - private boolean fullBrightness = false; - - public ParticleTornado(World world, int maxAge, double originX, double originZ, double radius, double yPos, double velX, double velZ, IBlockState block){ - super(world, 0, 0, 0, 0, 0, 0, block); - this.angle = this.rand.nextDouble() * Math.PI * 2; - double x = originX - Math.cos(angle)*radius; - double z = originZ + radius*Math.sin(angle); - this.radius = radius; - this.setPosition(x, yPos, z); - this.prevPosX = x; - this.prevPosY = yPos; - this.prevPosZ = z; - //this.particleScale *= 0.75F; - this.particleMaxAge = maxAge; - this.canCollide = false; - // Grass has special treatment, since it has a colourised top but the rest is normal. - // Commented out for now since vanilla does something about this now, but I'm not sure what exactly - //if(block.getBlock() != Blocks.GRASS || side == 1) this.setColour(block.getRenderColor(side)); - - // Blocks that emit light are rendered with full brightness. - if(block.getLightValue(world, new BlockPos(this.posX, this.posY, this.posZ)) == 0){ - this.particleRed *= 0.75; - this.particleGreen *= 0.75; - this.particleBlue *= 0.75; - }else{ - this.fullBrightness = true; - } - - speed = rand.nextDouble()*2 + 1; - this.velX = velX; - this.velZ = velZ; - } - - @Override - public void onUpdate(){ - - this.prevPosX = this.posX; - this.prevPosY = this.posY; - this.prevPosZ = this.posZ; - - if(this.particleAge++ >= this.particleMaxAge){ - this.setExpired(); - } - - // This is in radians per tick... - double omega = Math.signum(speed) * ((Math.PI*2)/20 - speed/(20*radius)); - - // v = r times omega; therefore the normalised velocity vector needs to be r times the angle increment / 2 pi. - this.angle += omega; - - this.motionZ = radius * omega * Math.cos(angle); - this.motionX = radius * omega * Math.sin(angle); - this.moveEntity(motionX + velX, 0, motionZ + velZ); - - if(this.particleAge > this.particleMaxAge / 2){ - this.setAlphaF(1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge); - } - - } - - @Override - public int getBrightnessForRender(float partialTicks){ - return fullBrightness ? 15728880 : super.getBrightnessForRender(partialTicks); - } - -} diff --git a/src/main/java/electroblob/wizardry/client/renderer/LayerStone.java b/src/main/java/electroblob/wizardry/client/renderer/LayerStone.java deleted file mode 100644 index 4365a842..00000000 --- a/src/main/java/electroblob/wizardry/client/renderer/LayerStone.java +++ /dev/null @@ -1,191 +0,0 @@ -package electroblob.wizardry.client.renderer; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.List; -import java.util.Map.Entry; - -import org.lwjgl.opengl.GL11; - -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.client.ClientProxy; -import electroblob.wizardry.spell.Petrify; -import net.minecraft.client.Minecraft; -import net.minecraft.client.model.ModelBase; -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.GlStateManager.DestFactor; -import net.minecraft.client.renderer.GlStateManager.SourceFactor; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.client.renderer.entity.Render; -import net.minecraft.client.renderer.entity.RenderLivingBase; -import net.minecraft.client.renderer.entity.RenderZombie; -import net.minecraft.client.renderer.entity.layers.LayerRenderer; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.monster.EntityZombie; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraftforge.fml.relauncher.ReflectionHelper; - -/** - * Layer used to render the stone texture on a petrified creature. Handles dynamic tiling of the stone texture and - * reflective access for classes that don't play nicely (looking at you, {@link RenderZombie}). - * @author Electroblob - * @since Wizardry 1.2 - */ -public class LayerStone implements LayerRenderer { - - protected ModelBase model; - private final RenderLivingBase renderer; - - private static final ResourceLocation texture = new ResourceLocation("textures/blocks/stone.png"); - - private static final Field zombieLayers = ReflectionHelper.findField(RenderZombie.class, "defaultLayers", "field_177122_o"); - private static final Field zombieVillagerLayers = ReflectionHelper.findField(RenderZombie.class, "villagerLayers", "field_177121_n"); - private static final Method swapZombieModel = ReflectionHelper.findMethod(RenderZombie.class, null, - new String[]{"swapArmor", "func_82427_a"}, EntityZombie.class); // Second parameter (null) is unused - - @SuppressWarnings("unchecked") // The compiler is being annoying and I know that what I'm doing is type-safe. - public static void initialiseLayers(){ - for(Entry, Render> entry : Minecraft.getMinecraft().getRenderManager().entityRenderMap.entrySet()){ - // Zombies don't play nicely because they have their own, private lists of layers for the regular zombie - // and the zombie villager, which are assigned within the constructor for RenderZombie and swapped out - // as necessary. However, Mojang, in their infinite wisdom, haven't bothered to override addLayer to - // modify those internal lists, so that method is useless. - if(entry.getValue() instanceof RenderZombie){ - try { - Object layers = zombieLayers.get(entry.getValue()); - if(layers instanceof List){ - // Nice as the layer renderer system is, it doesn't lend itself to reflective access. - // I KNOW that 'layers' (which was obtained using reflection) is of the type - // List>, because that's what it's declared as. However, if I cast - // 'layers' to List>, I can't add a LayerStone because it's only a - // LayerRenderer, not a LayerRenderer. - ((List>)layers).add(new LayerStone((RenderLivingBase)entry.getValue())); - } - layers = zombieVillagerLayers.get(entry.getValue()); - if(layers instanceof List){ - ((List>)layers).add(new LayerStone((RenderLivingBase)entry.getValue())); - } - } catch (IllegalArgumentException | IllegalAccessException e){ - Wizardry.logger.error("Error while reflectively accessing zombie render layers"); - e.printStackTrace(); - } - }else if(entry.getValue() instanceof RenderLivingBase){ - // Adds a stone layer to all the living entity renderers in the game. Whether it is actually rendered - // is decided in doRenderLayer below on a per-entity basis. - ((RenderLivingBase)entry.getValue()).addLayer(new LayerStone((RenderLivingBase)entry.getValue())); - } - // NOTE: May have to do some special stuff for players if they are to be added; see Minecraft.getMinecraft().getRenderManager().getSkinMap() - } - } - - public LayerStone(RenderLivingBase renderer){ - this.renderer = renderer; - this.model = renderer.getMainModel(); - } - - @Override - public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale){ - - if(entity.getEntityData().getBoolean(Petrify.NBT_KEY)){ - - GlStateManager.enableLighting(); - int i = this.getBlockBrightnessForEntity(entity, partialTicks); - - int j = i % 65536; - int k = i / 65536; - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)j / 1.0F, (float)k / 1.0F); - - ResourceLocation breakingTexture = ClientProxy.renderStatue.getBlockBreakingTexture(); - - if(breakingTexture != null){ - // Block breaking animation - // TODO: Spider eyes and enderman eyes (any others?) show through the stone when the block is being broken... - GlStateManager.enableBlend(); - GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA); - this.renderer.bindTexture(breakingTexture); - this.renderEntityModel(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale); - GlStateManager.disableBlend(); - }else{ - // Stone texture - this.renderer.bindTexture(texture); - this.renderEntityModel(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale); - } - } - } - - private int getBlockBrightnessForEntity(Entity entity, float partialTicks){ - - BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(MathHelper.floor_double(entity.posX), 0, MathHelper.floor_double(entity.posZ)); - - if(entity.worldObj.isBlockLoaded(pos)){ - pos.setY(MathHelper.floor_double(entity.posY + (double)entity.getEyeHeight())); - return entity.worldObj.getCombinedLight(pos, 0); - }else{ - return 0; - } - } - - private void renderEntityModel(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale){ - - GlStateManager.pushMatrix(); - // Enables tiling (Also used for guardian beam, beacon beam and ender crystal beam) - // TODO: Backport this improvement - GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); - GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); - - GlStateManager.depthMask(true); // Some entities set depth mask to false (i.e. no sorting of faces by depth) - // In particular, LayerSpiderEyes sets it to false when the spider is invisible, for some reason. - - // Changes the scale at which the texture is applied to the model. See LayerCreeper for a similar example, - // but with translation instead of scaling. - GlStateManager.matrixMode(GL11.GL_TEXTURE); - GlStateManager.loadIdentity(); - double scaleX = 1, scaleY = 1; - // It's more logical to use the model's texture size, but some classes don't bother setting it properly - // (e.g. ModelVillager), so to get the correct dimensions I'm getting them from the first box instead. - if(model.boxList != null && model.boxList.get(0) != null){ - scaleX = (double)model.boxList.get(0).textureWidth/16d; - scaleY = (double)model.boxList.get(0).textureHeight/16d; - }else{ // Fallback to model fields; should never be needed - scaleX = (double)model.textureWidth/16d; - scaleY = (double)model.textureHeight/16d; - } - GlStateManager.scale(scaleX, scaleY, 1); - GlStateManager.matrixMode(GL11.GL_MODELVIEW); - - // Lets RenderZombie do its (stupid and inflexible) model switching thing - if(this.renderer instanceof RenderZombie && entity instanceof EntityZombie){ - try { - swapZombieModel.invoke(this.renderer, entity); - this.model = this.renderer.getMainModel(); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - Wizardry.logger.error("Error while reflectively calling RenderZombie#swapArmor"); - e.printStackTrace(); - } - } - // Hides the hat layer for bipeds - if(this.model instanceof ModelBiped) ((ModelBiped) this.model).bipedHeadwear.isHidden = true; - - this.model.setLivingAnimations(entity, limbSwing, limbSwingAmount, partialTicks); - this.model.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); - - if(this.model instanceof ModelBiped) ((ModelBiped) this.model).bipedHeadwear.isHidden = false; - - // Undoes the texture scaling - GlStateManager.matrixMode(GL11.GL_TEXTURE); - GlStateManager.loadIdentity(); - GlStateManager.matrixMode(GL11.GL_MODELVIEW); - - GlStateManager.popMatrix(); - } - - @Override - public boolean shouldCombineTextures(){ - return false; - } -} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderArc.java b/src/main/java/electroblob/wizardry/client/renderer/RenderArc.java index 6bf600d1..cb08aefd 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderArc.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderArc.java @@ -1,129 +1,136 @@ package electroblob.wizardry.client.renderer; -import org.lwjgl.opengl.GL11; +import java.util.Random; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; -import electroblob.wizardry.Wizardry; import electroblob.wizardry.entity.EntityArc; -import net.minecraft.client.renderer.GlStateManager; +import electroblob.wizardry.entity.projectile.EntityMagicMissile; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityClientPlayerMP; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.entity.Render; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; +import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; -public class RenderArc extends Render { +public class RenderArc extends Render { private static final ResourceLocation[] textures = new ResourceLocation[16]; - - public RenderArc(RenderManager renderManager){ - super(renderManager); + + public RenderArc(){ for(int i=0;i<16;i++){ - textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/arc_" + i + ".png"); + textures[i] = new ResourceLocation("wizardry:textures/entity/arc_" + i + ".png"); } } - + @Override - public void doRender(EntityArc arc, double d0, double d1, double d2, + public void doRender(Entity entity, double d0, double d1, double d2, float fa, float fb) { - GlStateManager.pushMatrix(); - GlStateManager.translate((float)d0, (float)d1, (float)d2); - GlStateManager.disableLighting(); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); //This line fixes the weird brightness bug. - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); - + GL11.glPushMatrix(); + GL11.glTranslatef((float)d0, (float)d1, (float)d2); + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); //This line fixes the weird brightness bug. + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); + //System.out.println("Entity coords: " + entity.posX + ", " + entity.posY + ", " + entity.posZ); //System.out.println("doRender parameters: " + d0 + ", " + d1 + ", " + d2 + ", " + fa + ", " + fb); - - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); - - bindTexture(textures[arc.textureIndex]); // This MUST be after the tessellator declaration and the gl stuff - - /** - * Note: A lot of the maths here works on similar triangles and the ratios between them, avoiding too much - * pythagoras and eliminating the need for any trig. Ratios are used for the positioning of the arc endpoints. - * Ratios are usually used swapping x and z because the triangles are rotated through 90 degrees. - */ - - double dx = -d0; - double dy = -d1; - double dz = -d2; - - if(arc.x1 != 0){ - dx = arc.x1 - arc.posX;// - d2/lengthOffsetRatio; - dy = arc.y1 - arc.posY + 0.3; - dz = arc.z1 - arc.posZ;// + d0/lengthOffsetRatio; - - - //The distance from caster to target - double arcLength = Math.sqrt(dz*dz+dx*dx); - - //The ratio between the length of the arc and the offset of the start point from the player's centre (which is always 0.3). - //double lengthOffsetRatio = arcLength/0.3; - - //EntityClientPlayerMP player = Minecraft.getMinecraft().thePlayer; - - //double xViewDist = player.posX - d0; - //double yViewDist = player.posY + player.eyeHeight - d1; - //double zViewDist = player.posZ - d2; - - //double xzViewDist = Math.sqrt(xViewDist * xViewDist + zViewDist * zViewDist); - - //The angle above the horizontal that this particular player is viewing the arc from - //double viewAngle = Math.atan(yViewDist/xzViewDist); - - //Half the width of the arc - double arcWidth = 0.3d; - - //Right hand side of vertical plane - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - //Target end - buffer.pos(0, -0.5, 0).tex(1, 1).endVertex(); - buffer.pos(0, 0.5, 0).tex(1, 0).endVertex(); - //Caster end - buffer.pos(dx, dy, dz).tex(0, 0).endVertex(); - buffer.pos(dx, dy-1, dz).tex(0, 1).endVertex(); - tessellator.draw(); - - //Left - buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); - //Target end - buffer.pos(0, -0.5, 0).tex(1, 1).endVertex(); - //Caster end - buffer.pos(dx, dy-1, dz).tex(0, 1).endVertex(); - buffer.pos(dx, dy, dz).tex(0, 0).endVertex(); - //Target end - buffer.pos(0, 0.5, 0).tex(1, 0).endVertex(); - tessellator.draw(); - - //Bottom of horizontal plane - buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); - buffer.pos((arcWidth/arcLength)*dz, 0, (-arcWidth/arcLength)*dx).tex(1, 1).endVertex(); - buffer.pos(dx + (arcWidth/arcLength)*dz, dy-0.5, dz - (arcWidth/arcLength)*dx).tex(0, 1).endVertex(); - buffer.pos(dx - (arcWidth/arcLength)*dz, dy-0.5, dz + (arcWidth/arcLength)*dx).tex(0, 0).endVertex(); - buffer.pos((-arcWidth/arcLength)*dz, 0, (arcWidth/arcLength)*dx).tex(1, 0).endVertex(); - tessellator.draw(); - - //Top - buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); - buffer.pos((arcWidth/arcLength)*dz, 0, (-arcWidth/arcLength)*dx).tex(1, 1).endVertex(); - buffer.pos((-arcWidth/arcLength)*dz, 0, (arcWidth/arcLength)*dx).tex(1, 0).endVertex(); - buffer.pos(dx - (arcWidth/arcLength)*dz, dy-0.5, dz + (arcWidth/arcLength)*dx).tex(0, 0).endVertex(); - buffer.pos(dx + (arcWidth/arcLength)*dz, dy-0.5, dz - (arcWidth/arcLength)*dx).tex(0, 1).endVertex(); - tessellator.draw(); - } - - GlStateManager.enableLighting(); - GlStateManager.disableBlend(); - GlStateManager.popMatrix(); + + Tessellator tessellator = Tessellator.instance; + + if(entity instanceof EntityArc){ + EntityArc arc = (EntityArc)entity; + bindTexture(textures[arc.textureIndex]); // This MUST be after the tessellator declaration and the gl stuff + + /** + * Note: A lot of the maths here works on similar triangles and the ratios between them, avoiding too much + * pythagoras and eliminating the need for any trig. Ratios are used for the positioning of the arc endpoints. + * Ratios are usually used swapping x and z because the triangles are rotated through 90 degrees. + */ + + double dx = -d0; + double dy = -d1; + double dz = -d2; + + if(arc.x1 != 0){ + dx = arc.x1 - arc.posX;// - d2/lengthOffsetRatio; + dy = arc.y1 - arc.posY + 0.3; + dz = arc.z1 - arc.posZ;// + d0/lengthOffsetRatio; + + + //The distance from caster to target + double arcLength = Math.sqrt(dz*dz+dx*dx); + + //The ratio between the length of the arc and the offset of the start point from the player's centre (which is always 0.3). + double lengthOffsetRatio = arcLength/0.3; + + //EntityClientPlayerMP player = Minecraft.getMinecraft().thePlayer; + + //double xViewDist = player.posX - d0; + //double yViewDist = player.posY + player.eyeHeight - d1; + //double zViewDist = player.posZ - d2; + + //double xzViewDist = Math.sqrt(xViewDist * xViewDist + zViewDist * zViewDist); + + //The angle above the horizontal that this particular player is viewing the arc from + //double viewAngle = Math.atan(yViewDist/xzViewDist); + + //Half the width of the arc + double arcWidth = 0.3d; + + //Right hand side of vertical plane + tessellator.startDrawingQuads(); + //Target end + tessellator.addVertexWithUV(0, -0.5, 0, 1, 1); + tessellator.addVertexWithUV(0, 0.5, 0, 1, 0); + //Caster end + tessellator.addVertexWithUV(dx, dy, dz, 0, 0); + tessellator.addVertexWithUV(dx, dy-1, dz, 0, 1); + tessellator.draw(); + + //Left + tessellator.startDrawingQuads(); + //Target end + tessellator.addVertexWithUV(0, -0.5, 0, 1, 1); + //Caster end + tessellator.addVertexWithUV(dx, dy-1, dz, 0, 1); + tessellator.addVertexWithUV(dx, dy, dz, 0, 0); + //Target end + tessellator.addVertexWithUV(0, 0.5, 0, 1, 0); + tessellator.draw(); + + //Bottom of horizontal plane + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV((arcWidth/arcLength)*dz, 0, (-arcWidth/arcLength)*dx, 1, 1); + tessellator.addVertexWithUV(dx + (arcWidth/arcLength)*dz, dy-0.5, dz - (arcWidth/arcLength)*dx, 0, 1); + tessellator.addVertexWithUV(dx - (arcWidth/arcLength)*dz, dy-0.5, dz + (arcWidth/arcLength)*dx, 0, 0); + tessellator.addVertexWithUV((-arcWidth/arcLength)*dz, 0, (arcWidth/arcLength)*dx, 1, 0); + tessellator.draw(); + + //Top + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV((arcWidth/arcLength)*dz, 0, (-arcWidth/arcLength)*dx, 1, 1); + tessellator.addVertexWithUV((-arcWidth/arcLength)*dz, 0, (arcWidth/arcLength)*dx, 1, 0); + tessellator.addVertexWithUV(dx - (arcWidth/arcLength)*dz, dy-0.5, dz + (arcWidth/arcLength)*dx, 0, 0); + tessellator.addVertexWithUV(dx + (arcWidth/arcLength)*dz, dy-0.5, dz - (arcWidth/arcLength)*dx, 0, 1); + tessellator.draw(); + } + } + + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_BLEND); + GL11.glPopMatrix(); } @Override - protected ResourceLocation getEntityTexture(EntityArc entity) { - return textures[entity.textureIndex]; + protected ResourceLocation getEntityTexture(Entity entity) { + if(entity instanceof EntityArc){ + return textures[((EntityArc)entity).textureIndex]; + } + return null; } } \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderArcaneWorkbench.java b/src/main/java/electroblob/wizardry/client/renderer/RenderArcaneWorkbench.java index 12203694..600527cc 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderArcaneWorkbench.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderArcaneWorkbench.java @@ -1,45 +1,48 @@ package electroblob.wizardry.client.renderer; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.entity.RenderItem; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ResourceLocation; + import org.lwjgl.opengl.GL11; -import electroblob.wizardry.Wizardry; import electroblob.wizardry.tileentity.ContainerArcaneWorkbench; import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.VertexBuffer; -import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; -import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -public class RenderArcaneWorkbench extends TileEntitySpecialRenderer { - - private static final ResourceLocation runeTexture = new ResourceLocation(Wizardry.MODID, "textures/entity/rune.png"); +public class RenderArcaneWorkbench extends TileEntitySpecialRenderer +{ + private final RenderBlocks renderBlocksInstance = new RenderBlocks(); + private static final ResourceLocation runeTexture = new ResourceLocation("wizardry:textures/entity/rune.png"); - public RenderArcaneWorkbench(){} + public RenderArcaneWorkbench(){ + } @Override - public void renderTileEntityAt(TileEntityArcaneWorkbench tileentity, double x, double y, double z, float partialTicks, int destroyStage) { + public void renderTileEntityAt(TileEntity tileentity, double x, double y, double z, float f) { - GlStateManager.pushMatrix(); - // This line makes stuff render in the same place relative to the world wherever the player is. - GlStateManager.translate((float)x + 0.5F, (float)y + 1.5F, (float)z + 0.5F); - GlStateManager.rotate(180, 0F, 0F, 1F); - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); + // It seems that these next two lines make stuff render in the same place relative to the world wherever + // the player is. + GL11.glTranslatef((float)x + 0.5F, (float)y +1.5F, (float)z + 0.5F); + GL11.glRotatef(180, 0F, 0F, 1F); + GL11.glPushMatrix(); double angle = 0.0d; if(x < -0.5){ angle = Math.toDegrees(Math.atan((z+0.5)/(x+0.5))) + 180; }else{ angle = Math.toDegrees(Math.atan((z+0.5)/(x+0.5))); } - this.renderEffect(tileentity); - this.renderWand(tileentity, angle); - GlStateManager.popMatrix(); - GlStateManager.popMatrix(); + this.renderEffect((TileEntityArcaneWorkbench)tileentity); + this.renderWand((TileEntityArcaneWorkbench)tileentity, angle); + GL11.glPopMatrix(); + GL11.glPopMatrix(); } private void renderEffect(TileEntityArcaneWorkbench tileentity) { @@ -47,27 +50,26 @@ public class RenderArcaneWorkbench extends TileEntitySpecialRenderer { - - private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/dark_ray.png"); - private static final ResourceLocation texture2 = new ResourceLocation(Wizardry.MODID, "textures/entity/black_hole.png"); - - public RenderBlackHole(RenderManager renderManager) { - super(renderManager); - } +public class RenderBlackHole extends Render{ + private static final ResourceLocation texture = new ResourceLocation("wizardry:textures/entity/dark_ray.png"); + private static final ResourceLocation texture2 = new ResourceLocation("wizardry:textures/entity/black_hole.png"); + @Override - public void doRender(EntityBlackHole blackhole, double x, double y, double z, float fa, float fb) { + public void doRender(Entity entity, double x, double y, double z, + float fa, float fb) { - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); - GlStateManager.disableCull(); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - GlStateManager.shadeModel(GL11.GL_SMOOTH); - GlStateManager.disableLighting(); - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); - RenderHelper.disableStandardItemLighting(); - - GlStateManager.translate(x, y, z); + GL11.glDisable(GL11.GL_CULL_FACE); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glShadeModel(GL11.GL_SMOOTH); + GL11.glDisable(GL11.GL_LIGHTING); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); + RenderHelper.disableStandardItemLighting(); + GL11.glTranslated(x, y, z); + //float pitch = (float) Math.toDegrees(Math.atan(y/(x*x+z*z))); //float yaw = (float) Math.toDegrees(Math.atan(x/z)); + + Tessellator tessellator = Tessellator.instance; + + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + // Renders the rays + if(entity instanceof EntityBlackHole){ + + EntityBlackHole blackhole = (EntityBlackHole)entity; + + if(blackhole.ticksExisted < 10){ + GL11.glScalef((float)blackhole.ticksExisted/10, (float)blackhole.ticksExisted/10, (float)blackhole.ticksExisted/10); + } + if(blackhole.ticksExisted > blackhole.lifetime - 10){ + GL11.glScalef((float)(blackhole.lifetime-blackhole.ticksExisted)/10, (float)(blackhole.lifetime-blackhole.ticksExisted)/10, (float)(blackhole.lifetime-blackhole.ticksExisted)/10); + } + + this.bindTexture(texture); + + // In theory this stuff should sort the rays into the correct render order based on the distance from + // the 'camera' (i.e. the player's viewpoint) + // In the end it was easier to do away with the openGL rotation because for some reason it produced + // coordinates which were inconsistent with my calculated ones. Since I know those will give the desired + // effect anyway, I just used them directly instead. + + ArrayList rays = new ArrayList(1); + + for(int j=0; j<30; j++){ - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); - - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - - if(blackhole.ticksExisted < 10){ - GlStateManager.scale((float)blackhole.ticksExisted/10, (float)blackhole.ticksExisted/10, (float)blackhole.ticksExisted/10); - } - if(blackhole.ticksExisted > blackhole.lifetime - 10){ - GlStateManager.scale((float)(blackhole.lifetime-blackhole.ticksExisted)/10, (float)(blackhole.lifetime-blackhole.ticksExisted)/10, (float)(blackhole.lifetime-blackhole.ticksExisted)/10); - } - - this.bindTexture(texture); - - // In theory this stuff should sort the rays into the correct render order based on the distance from - // the 'camera' (i.e. the player's viewpoint) - // In the end it was easier to do away with the openGL rotation because for some reason it produced - // coordinates which were inconsistent with my calculated ones. Since I know those will give the desired - // effect anyway, I just used them directly instead. - - ArrayList rays = new ArrayList(1); - - for(int j=0; j<30; j++){ - - float scale = 3.0f; - - int a = blackhole.randomiser[j]; - int b = blackhole.randomiser2[j]; - - int sliceAngle = 20 + a; - - double x1 = scale*Math.sin((blackhole.ticksExisted + 40*j)*(Math.PI/180)); - //double y1 = 0.7*Math.cos((blackhole.timer - 40*j)*(Math.PI/180))*j/10; - double z1 = scale*Math.cos((blackhole.ticksExisted + 40*j)*(Math.PI/180)); - - double x2 = scale*Math.sin((blackhole.ticksExisted + 40*j - sliceAngle)*(Math.PI/180)); - //double y2 = 0.7*Math.sin((blackhole.timer - 40*j)*(Math.PI/180))*j/10; - double z2 = scale*Math.cos((blackhole.ticksExisted + 40*j - sliceAngle)*(Math.PI/180)); - - double absoluteX = x1*Math.cos(31*b); - double absoluteY = z1*Math.sin(31*a) + x1*Math.cos(31*a)*Math.sin(31*b); - double absoluteZ = z1*Math.cos(31*a); - - double absoluteX2 = x2*Math.cos(31*b); - double absoluteY2 = z2*Math.sin(31*a) + x2*Math.cos(31*a)*Math.sin(31*b); - double absoluteZ2 = z2*Math.cos(31*a); - /* - buffer.begin(0, DefaultVertexFormats.POSITION_TEX); + float scale = 3.0f; + + int a = blackhole.randomiser[j]; + int b = blackhole.randomiser2[j]; + + int sliceAngle = 20 + a; + + double x1 = scale*Math.sin((blackhole.ticksExisted + 40*j)*(Math.PI/180)); + //double y1 = 0.7*Math.cos((blackhole.timer - 40*j)*(Math.PI/180))*j/10; + double z1 = scale*Math.cos((blackhole.ticksExisted + 40*j)*(Math.PI/180)); + double x2 = scale*Math.sin((blackhole.ticksExisted + 40*j - sliceAngle)*(Math.PI/180)); + //double y2 = 0.7*Math.sin((blackhole.timer - 40*j)*(Math.PI/180))*j/10; + double z2 = scale*Math.cos((blackhole.ticksExisted + 40*j - sliceAngle)*(Math.PI/180)); + + double absoluteX = x1*Math.cos(31*b); + double absoluteY = z1*Math.sin(31*a) + x1*Math.cos(31*a)*Math.sin(31*b); + double absoluteZ = z1*Math.cos(31*a); + + double absoluteX2 = x2*Math.cos(31*b); + double absoluteY2 = z2*Math.sin(31*a) + x2*Math.cos(31*a)*Math.sin(31*b); + double absoluteZ2 = z2*Math.cos(31*a); + /* + tessellator.startDrawing(0); + tessellator.setColorOpaque(255, 255, 255); GL11.glPointSize(5); tessellator.addVertex(absoluteX-x, 0, 0); tessellator.addVertex(0, absoluteY-y, 0); tessellator.addVertex(0, 0, absoluteZ-z); - + tessellator.draw(); - */ - rays.add(new RayHelper(j, absoluteX, absoluteY, absoluteZ, absoluteX2, absoluteY2, absoluteZ2, x, y, z)); + */ + rays.add(new RayHelper(j, absoluteX, absoluteY, absoluteZ, absoluteX2, absoluteY2, absoluteZ2, x, y, z)); + + } + + Collections.sort(rays); + + for(RayHelper ray : rays){ + + GL11.glPushMatrix(); + //GL11.glRotatef(31*blackhole.randomiser[ray.ordinal], 1, 0, 0); + //GL11.glRotatef(31*blackhole.randomiser2[ray.ordinal], 0, 0, 1); + + tessellator.startDrawing(5); + //tessellator.setColorRGBA(255, 255, 255, 0); + tessellator.addVertexWithUV(0, 0, 0, 0, 0); + tessellator.addVertexWithUV(0, 0, 0, 0, 1); + + //tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(ray.x1, ray.y1, ray.z1, 1, 0); + tessellator.addVertexWithUV(ray.x2, ray.y2, ray.z2, 1, 1); + + tessellator.draw(); + + GL11.glPopMatrix(); + } } + - Collections.sort(rays); - - for(RayHelper ray : rays){ - - GlStateManager.pushMatrix(); - //GlStateManager.rotate(31*blackhole.randomiser[ray.ordinal], 1, 0, 0); - //GlStateManager.rotate(31*blackhole.randomiser2[ray.ordinal], 0, 0, 1); - - buffer.begin(5, DefaultVertexFormats.POSITION_TEX); - - //tessellator.setColorRGBA(255, 255, 255, 0); - buffer.pos(0, 0, 0).tex(0, 0).endVertex(); - buffer.pos(0, 0, 0).tex(0, 1).endVertex(); - - //tessellator.setColorRGBA(0, 0, 0, 255); - buffer.pos(ray.x1, ray.y1, ray.z1).tex(1, 0).endVertex(); - buffer.pos(ray.x2, ray.y2, ray.z2).tex(1, 1).endVertex(); - - tessellator.draw(); - - GlStateManager.popMatrix(); - } - - GlStateManager.pushMatrix(); - - /* Deprecated in favour of particle style method. - GlStateManager.rotate(yaw, 0, 1, 0); + GL11.glPushMatrix(); + + /* Deprecated in favour of particle style method. + GL11.glRotatef(yaw, 0, 1, 0); // GL transformations are relative, hence only x rotation if(z < 0){ - GlStateManager.rotate(pitch, 1, 0, 0); + GL11.glRotatef(pitch, 1, 0, 0); }else{ - GlStateManager.rotate(-1*pitch, 1, 0, 0); + GL11.glRotatef(-1*pitch, 1, 0, 0); } - */ + */ - // Renders the aura effect - - // This counteracts the reverse rotation behaviour when in front f5 view. Vanilla now has this fix too. - float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? this.renderManager.playerViewX : -this.renderManager.playerViewX; - GlStateManager.rotate(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); - GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F); - - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + // Renders the aura effect + + // This counteracts the reverse rotation behaviour when in front f5 view. + // Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example. + float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? this.renderManager.playerViewX : -this.renderManager.playerViewX; + GL11.glRotatef(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(yaw, 1.0F, 0.0F, 0.0F); + + tessellator.startDrawingQuads(); this.bindTexture(texture2); - - buffer.pos(-0.4, 0.4, 0).tex(0, 0).endVertex(); - buffer.pos(0.4, 0.4, 0).tex(1, 0).endVertex(); - buffer.pos(0.4, -0.4, 0).tex(1, 1).endVertex(); - buffer.pos(-0.4, -0.4, 0).tex(0, 1).endVertex(); - - tessellator.draw(); - - GlStateManager.popMatrix(); - - - GlStateManager.shadeModel(GL11.GL_FLAT); - GlStateManager.enableCull(); - GlStateManager.disableBlend(); - GlStateManager.enableLighting(); - RenderHelper.enableStandardItemLighting(); - - GlStateManager.popMatrix(); + + tessellator.addVertexWithUV(-0.4, 0.4, 0, 0, 0); + tessellator.addVertexWithUV(0.4, 0.4, 0, 1, 0); + tessellator.addVertexWithUV(0.4, -0.4, 0, 1, 1); + tessellator.addVertexWithUV(-0.4, -0.4, 0, 0, 1); + + tessellator.draw(); + + GL11.glPopMatrix(); + + + GL11.glShadeModel(GL11.GL_FLAT); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); + RenderHelper.enableStandardItemLighting(); + + GL11.glPopMatrix(); } @Override - protected ResourceLocation getEntityTexture(EntityBlackHole entity) { + protected ResourceLocation getEntityTexture(Entity entity) { return texture; } diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderBlank.java b/src/main/java/electroblob/wizardry/client/renderer/RenderBlank.java index 01926ccc..9dcf7d80 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderBlank.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderBlank.java @@ -1,24 +1,21 @@ package electroblob.wizardry.client.renderer; import net.minecraft.client.renderer.entity.Render; -import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.entity.Entity; import net.minecraft.util.ResourceLocation; -public class RenderBlank extends Render { - - public RenderBlank(RenderManager renderManager) { - super(renderManager); - } +public class RenderBlank extends Render { @Override public void doRender(Entity entity, double d0, double d1, double d2, float f, float f1) { + // TODO Auto-generated method stub } @Override protected ResourceLocation getEntityTexture(Entity entity) { + // TODO Auto-generated method stub return null; } diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderBubble.java b/src/main/java/electroblob/wizardry/client/renderer/RenderBubble.java index d96a1020..14a23526 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderBubble.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderBubble.java @@ -1,103 +1,101 @@ package electroblob.wizardry.client.renderer; import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; -import electroblob.wizardry.Wizardry; import electroblob.wizardry.entity.construct.EntityBubble; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.entity.Render; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; +import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; -public class RenderBubble extends Render { +public class RenderBubble extends Render { + + private static final ResourceLocation particleTextures = new ResourceLocation("textures/particle/particles.png"); + private static final ResourceLocation darkOrbTexture = new ResourceLocation("wizardry:textures/entity/dark_orb.png"); - private static final ResourceLocation particleTextures = new ResourceLocation("textures/particle/particles.png"); - private static final ResourceLocation darkOrbTexture = new ResourceLocation(Wizardry.MODID, "textures/entity/dark_orb.png"); - - public RenderBubble(RenderManager renderManager) { - super(renderManager); + public RenderBubble() { + } @Override - public void doRender(EntityBubble entity, double par2, double par4, double par6, float par8, float par9){ - - GlStateManager.pushMatrix(); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - - float yOffset = 0; - - if(WizardryUtilities.getRider(entity) != null){ - yOffset = WizardryUtilities.getRider(entity).height/2; + public void doRender(Entity entity, double par2, double par4, double par6, float par8, float par9) + { + if(entity instanceof EntityBubble){ + + GL11.glPushMatrix(); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + float yOffset = 0; + + if(entity.riddenByEntity != null){ + yOffset = entity.riddenByEntity.height/2; + } + + GL11.glTranslatef((float)par2, (float)par4 + yOffset, (float)par6); + + this.bindTexture(((EntityBubble)entity).isDarkOrb ? darkOrbTexture : particleTextures); + float f6 = 1.0F; + float f7 = 0.5F; + float f8 = 0.5F; + + if(((EntityBubble)entity).isDarkOrb){ + GL11.glDisable(GL11.GL_LIGHTING); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); + }else{ + int j = entity.getBrightnessForRender(par9); + int k = j % 65536; + int l = j / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F); + } + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + // This counteracts the reverse rotation behaviour when in front f5 view. + // Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example. + float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? this.renderManager.playerViewX : -this.renderManager.playerViewX; + GL11.glRotatef(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(yaw, 1.0F, 0.0F, 0.0F); + + float f11 = 3.0F; + GL11.glScalef(f11, f11, f11); + + double pixelwidth = (1.0d/128); + + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + //tessellator.setColorRGBA_I(k1, 128); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + + if(((EntityBubble)entity).isDarkOrb){ + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(0.0F - f8), 0.0D, 0, 1); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(0.0F - f8), 0.0D, 1, 1); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(1.0F - f8), 0.0D, 1, 0); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(1.0F - f8), 0.0D, 0, 0); + }else{ + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(0.0F - f8), 0.0D, pixelwidth, pixelwidth * 24); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(0.0F - f8), 0.0D, pixelwidth*8, pixelwidth * 24); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(1.0F - f8), 0.0D, pixelwidth*8, pixelwidth * 17); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(1.0F - f8), 0.0D, pixelwidth, pixelwidth * 17); + } + + tessellator.draw(); + + GL11.glDisable(GL11.GL_BLEND); + if(((EntityBubble)entity).isDarkOrb){ + GL11.glEnable(GL11.GL_LIGHTING); + } + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glPopMatrix(); } - - GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6); - - this.bindTexture(((EntityBubble)entity).isDarkOrb ? darkOrbTexture : particleTextures); - float f6 = 1.0F; - float f7 = 0.5F; - float f8 = 0.5F; - - if(((EntityBubble)entity).isDarkOrb){ - GlStateManager.disableLighting(); - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); - }else{ - int j = entity.getBrightnessForRender(par9); - int k = j % 65536; - int l = j / 65536; - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F); - } - - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - - // This counteracts the reverse rotation behaviour when in front f5 view. - // Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example. - float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? this.renderManager.playerViewX : -this.renderManager.playerViewX; - GlStateManager.rotate(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); - GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F); - - float f11 = 3.0F; - GlStateManager.scale(f11, f11, f11); - - double pixelwidth = (1.0d/128); - - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - //tessellator.setColorRGBA_I(k1, 128); - //buffer.normal(0.0F, 1.0F, 0.0F); - - if(((EntityBubble)entity).isDarkOrb){ - buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.0D).tex(0, 1).endVertex(); - buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.0D).tex(1, 1).endVertex(); - buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.0D).tex(1, 0).endVertex(); - buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.0D).tex(0, 0).endVertex(); - }else{ - buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.0D).tex(pixelwidth, pixelwidth * 24).endVertex(); - buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.0D).tex(pixelwidth*8, pixelwidth * 24).endVertex(); - buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.0D).tex(pixelwidth*8, pixelwidth * 17).endVertex(); - buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.0D).tex(pixelwidth, pixelwidth * 17).endVertex(); - } - - tessellator.draw(); - - GlStateManager.disableBlend(); - if(((EntityBubble)entity).isDarkOrb){ - GlStateManager.enableLighting(); - } - GlStateManager.disableRescaleNormal(); - GlStateManager.popMatrix(); - - } + } @Override - protected ResourceLocation getEntityTexture(EntityBubble entity) { + protected ResourceLocation getEntityTexture(Entity entity) { return null; } diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderDecay.java b/src/main/java/electroblob/wizardry/client/renderer/RenderDecay.java index f849f967..3a333caa 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderDecay.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderDecay.java @@ -1,73 +1,73 @@ package electroblob.wizardry.client.renderer; import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; -import electroblob.wizardry.Wizardry; import electroblob.wizardry.entity.construct.EntityDecay; -import net.minecraft.client.renderer.GlStateManager; +import electroblob.wizardry.entity.construct.EntityHealAura; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.entity.Render; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; import net.minecraft.util.ResourceLocation; -public class RenderDecay extends Render { +public class RenderDecay extends Render { private static final ResourceLocation[] textures = new ResourceLocation[10]; - public RenderDecay(RenderManager renderManager){ - super(renderManager); + public RenderDecay(){ for(int i=0;i<10;i++){ - textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/decay_" + i + ".png"); + textures[i] = new ResourceLocation("wizardry:textures/entity/decay_" + i + ".png"); } } @Override - public void doRender(EntityDecay entity, double par2, double par4, double par6, float par8, float par9){ + public void doRender(Entity entity, double par2, double par4, double par6, float par8, float par9){ - GlStateManager.pushMatrix(); - GlStateManager.enableBlend(); - GlStateManager.disableLighting(); + GL11.glPushMatrix(); + GL11.glEnable(GL11.GL_BLEND); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); float yOffset = 0; - GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6); + if(entity.riddenByEntity != null){ + yOffset = entity.riddenByEntity.height/2; + } + + GL11.glTranslatef((float)par2, (float)par4 + yOffset, (float)par6); this.bindTexture(textures[((EntityDecay)entity).textureIndex]); float f6 = 1.0F; float f7 = 0.5F; float f8 = 0.5F; - GlStateManager.rotate(-90, 1, 0, 0); + GL11.glRotatef(-90, 1, 0, 0); float scale = 2*Math.min(1, (float)(EntityDecay.LIFETIME - entity.ticksExisted)/50f); - GlStateManager.scale(scale, scale, scale); + GL11.glScalef(scale, scale, scale); - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); //tessellator.setColorRGBA_I(k1, 128); - //buffer.normal(0.0F, 1.0F, 0.0F); - buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex(); - buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex(); - buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex(); - buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(0.0F - f8), 0.01, 0, 1); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(0.0F - f8), 0.01, 1, 1); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(1.0F - f8), 0.01, 1, 0); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(1.0F - f8), 0.01, 0, 0); tessellator.draw(); - GlStateManager.disableBlend(); - GlStateManager.enableLighting(); - GlStateManager.disableRescaleNormal(); - GlStateManager.popMatrix(); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glPopMatrix(); } @Override - protected ResourceLocation getEntityTexture(EntityDecay entity) { + protected ResourceLocation getEntityTexture(Entity entity) { return null; } diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderDecoy.java b/src/main/java/electroblob/wizardry/client/renderer/RenderDecoy.java index 8e373b04..d45d3ee0 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderDecoy.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderDecoy.java @@ -1,108 +1,498 @@ package electroblob.wizardry.client.renderer; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; +import java.util.UUID; -import electroblob.wizardry.Wizardry; +import org.lwjgl.opengl.GL11; + +import com.mojang.authlib.GameProfile; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.client.model.ModelWizard; import electroblob.wizardry.entity.living.EntityDecoy; +import electroblob.wizardry.entity.living.EntityEvilWizard; +import electroblob.wizardry.entity.living.EntityWizard; +import net.minecraft.block.Block; +import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.client.renderer.entity.RenderBiped; -import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.entity.RendererLivingEntity; +import net.minecraft.client.renderer.tileentity.TileEntitySkullRenderer; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.EnumAction; +import net.minecraft.item.Item; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTUtil; +import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.relauncher.ReflectionHelper; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraft.util.StringUtils; -// TODO: Backport the rewrite of this entire class. @SideOnly(Side.CLIENT) -public class RenderDecoy extends RenderBiped { - - private static final ResourceLocation steveTextures = new ResourceLocation("textures/entity/steve.png"); - - private static final Method getEntityTexture = ReflectionHelper.findMethod(Render.class, null, - new String[]{"getEntityTexture", "func_110775_a"}, Entity.class); // Generic parameter T is erased to Entity at runtime. - - public RenderDecoy(RenderManager manager){ - super(manager, new ModelBiped(0.0f), 0.5f); - } - - @Override - public void doRender(EntityDecoy entity, double x, double y, double z, float entityYaw, float partialTicks) { - - if(entity.getCaster() != null){ - - this.renderName(entity, x, y, z); - - // Save relevant animation fields from the caster to local variables - float pitch = entity.getCaster().rotationPitch; - float prevPitch = entity.getCaster().prevRotationPitch; - float swing = entity.getCaster().swingProgress; - float prevSwing = entity.getCaster().prevSwingProgress; - float yawOffset = entity.getCaster().renderYawOffset; - float prevYawOffset = entity.getCaster().prevRenderYawOffset; - float yaw = entity.getCaster().rotationYawHead; - float prevYaw = entity.getCaster().prevRotationYawHead; - float limbSwing = entity.getCaster().limbSwing; - float limbSwingAmount = entity.getCaster().limbSwingAmount; - float prevLimbSwingAmount = entity.getCaster().prevLimbSwingAmount; - int hurtTime = entity.getCaster().hurtTime; - boolean sneak = entity.getCaster().isSneaking(); - Entity mount = entity.getCaster().getRidingEntity(); - - // Assign decoy's animation fields to the caster - entity.getCaster().rotationPitch = entity.rotationPitch; - entity.getCaster().prevRotationPitch = entity.prevRotationPitch; - entity.getCaster().swingProgress = entity.swingProgress; - entity.getCaster().prevSwingProgress = entity.prevSwingProgress; - entity.getCaster().renderYawOffset = entity.renderYawOffset; - entity.getCaster().prevRenderYawOffset = entity.prevRenderYawOffset; - entity.getCaster().rotationYawHead = entity.rotationYawHead; - entity.getCaster().prevRotationYawHead = entity.prevRotationYawHead; - entity.getCaster().limbSwing = entity.limbSwing; - entity.getCaster().limbSwingAmount = entity.limbSwingAmount; - entity.getCaster().prevLimbSwingAmount = entity.prevLimbSwingAmount; - entity.getCaster().hurtTime = entity.hurtTime; - entity.getCaster().setSneaking(false); // Decoys can't sneak FIXME Not working! - entity.getCaster().dismountRidingEntity(); // Decoys can't ride anything - - // Do the rendering - renderManager.getEntityRenderObject(entity.getCaster()).doRender(entity.getCaster(), x, y, z, entityYaw, partialTicks); - - // Reset caster's animation fields to their original values - entity.getCaster().rotationPitch = pitch; - entity.getCaster().prevRotationPitch = prevPitch; - entity.getCaster().swingProgress = swing; - entity.getCaster().prevSwingProgress = prevSwing; - entity.getCaster().renderYawOffset = yawOffset; - entity.getCaster().prevRenderYawOffset = prevYawOffset; - entity.getCaster().rotationYawHead = yaw; - entity.getCaster().prevRotationYawHead = prevYaw; - entity.getCaster().limbSwing = limbSwing; - entity.getCaster().limbSwingAmount = limbSwingAmount; - entity.getCaster().prevLimbSwingAmount = prevLimbSwingAmount; - entity.getCaster().hurtTime = hurtTime; - entity.getCaster().setSneaking(sneak); - if(mount != null) entity.getCaster().startRiding(mount); - - }else{ - super.doRender(entity, x, y, z, entityYaw, partialTicks); - } - } - - @Override - protected ResourceLocation getEntityTexture(EntityDecoy entity){ - if(entity.getCaster() != null){ - try { - return (ResourceLocation)getEntityTexture.invoke(renderManager.getEntityRenderObject(entity.getCaster())); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | ClassCastException e){ - Wizardry.logger.error("Error while reflectively calling Render#getEntityTexture as part of decoy rendering"); - e.printStackTrace(); - } - } - // Fallback to steve textures - return steveTextures; - } +public class RenderDecoy extends RenderBiped +{ + private static final ResourceLocation steveTextures = new ResourceLocation("textures/entity/steve.png"); + public ModelBiped modelBipedMain; + public ModelBiped modelArmorChestplate; + public ModelBiped modelArmor; + public ModelWizard modelWizard; + public RenderDecoy() + { + super(new ModelBiped(0.0F), 0.5F); + this.modelBipedMain = (ModelBiped)this.mainModel; + this.modelArmorChestplate = new ModelBiped(1.0F); + this.modelArmor = new ModelBiped(0.5F); + this.modelWizard = new ModelWizard(); + } + + /** + * Queries whether should render the specified pass or not. + */ + protected int shouldRenderPass(EntityDecoy decoy, int pass, float partialTickTime) + { + if(decoy.getCaster() instanceof EntityPlayer){ + + ItemStack itemstack = ((AbstractClientPlayer)decoy.getCaster()).inventory.armorItemInSlot(3 - pass); + + if (itemstack != null) + { + Item item = itemstack.getItem(); + + if (item instanceof ItemArmor) + { + ItemArmor itemarmor = (ItemArmor)item; + this.bindTexture(RenderBiped.getArmorResource(decoy, itemstack, pass, null)); + ModelBiped modelbiped = pass == 2 ? this.modelArmor : this.modelArmorChestplate; + modelbiped.bipedHead.showModel = pass == 0; + modelbiped.bipedHeadwear.showModel = pass == 0; + modelbiped.bipedBody.showModel = pass == 1 || pass == 2; + modelbiped.bipedRightArm.showModel = pass == 1; + modelbiped.bipedLeftArm.showModel = pass == 1; + modelbiped.bipedRightLeg.showModel = pass == 2 || pass == 3; + modelbiped.bipedLeftLeg.showModel = pass == 2 || pass == 3; + modelbiped = net.minecraftforge.client.ForgeHooksClient.getArmorModel(decoy, itemstack, pass, modelbiped); + this.setRenderPassModel(modelbiped); + modelbiped.onGround = this.mainModel.onGround; + modelbiped.isRiding = this.mainModel.isRiding; + modelbiped.isChild = this.mainModel.isChild; + + //Move outside if to allow for more then just CLOTH + int j = itemarmor.getColor(itemstack); + if (j != -1) + { + float f1 = (float)(j >> 16 & 255) / 255.0F; + float f2 = (float)(j >> 8 & 255) / 255.0F; + float f3 = (float)(j & 255) / 255.0F; + GL11.glColor3f(f1, f2, f3); + + if (itemstack.isItemEnchanted()) + { + return 31; + } + + return 16; + } + + GL11.glColor3f(1.0F, 1.0F, 1.0F); + + if (itemstack.isItemEnchanted()) + { + return 15; + } + + return 1; + } + } + }else{ + + return super.shouldRenderPass(decoy.getCaster(), pass, partialTickTime); + } + + return -1; + } + + protected void func_82408_c(EntityDecoy decoy, int p_82408_2_, float p_82408_3_) + { + ItemStack itemstack = ((AbstractClientPlayer)decoy.getCaster()).inventory.armorItemInSlot(3 - p_82408_2_); + + if (itemstack != null) + { + Item item = itemstack.getItem(); + + if (item instanceof ItemArmor) + { + this.bindTexture(RenderBiped.getArmorResource(decoy, itemstack, p_82408_2_, "overlay")); + GL11.glColor3f(1.0F, 1.0F, 1.0F); + } + } + } + + public void doRender(EntityDecoy decoy, double x, double y, double z, float yaw, float pitch) + { + if(decoy.getCaster() instanceof EntityPlayer){ + + this.mainModel = this.modelBipedMain; + + GL11.glColor3f(1.0F, 1.0F, 1.0F); + ItemStack itemstack = ((AbstractClientPlayer)decoy.getCaster()).inventory.getCurrentItem(); + this.modelArmorChestplate.heldItemRight = this.modelArmor.heldItemRight = this.modelBipedMain.heldItemRight = itemstack != null ? 1 : 0; + + if (itemstack != null && ((AbstractClientPlayer)decoy.getCaster()).getItemInUseCount() > 0) + { + EnumAction enumaction = itemstack.getItemUseAction(); + + if (enumaction == EnumAction.block) + { + this.modelArmorChestplate.heldItemRight = this.modelArmor.heldItemRight = this.modelBipedMain.heldItemRight = 3; + } + else if (enumaction == EnumAction.bow) + { + this.modelArmorChestplate.aimedBow = this.modelArmor.aimedBow = this.modelBipedMain.aimedBow = true; + } + } + + this.modelArmorChestplate.isSneak = this.modelArmor.isSneak = this.modelBipedMain.isSneak = decoy.isSneaking(); + double d3 = y - (double)decoy.yOffset; + + super.doRender((EntityLivingBase)decoy, x, d3, z, yaw, pitch); + this.modelArmorChestplate.aimedBow = this.modelArmor.aimedBow = this.modelBipedMain.aimedBow = false; + this.modelArmorChestplate.isSneak = this.modelArmor.isSneak = this.modelBipedMain.isSneak = false; + this.modelArmorChestplate.heldItemRight = this.modelArmor.heldItemRight = this.modelBipedMain.heldItemRight = 0; + + }else{ + + this.mainModel = this.modelWizard; + + // Since wizards always have a wand, I don't see any point in checking + this.modelArmorChestplate.heldItemRight = this.modelArmor.heldItemRight = this.modelBipedMain.heldItemRight = 1; + + super.doRender(decoy, x, y, z, yaw, pitch); + + } + } + + /** + * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. + */ + protected ResourceLocation getEntityTexture(EntityDecoy decoy) + { + //System.out.println(decoy.getCaster()); + + if(decoy.getCaster() instanceof EntityWizard){ + return RenderWizard.textures[((EntityWizard)decoy.getCaster()).textureIndex]; + }else if(decoy.getCaster() instanceof EntityEvilWizard){ + return RenderEvilWizard.textures[((EntityEvilWizard)decoy.getCaster()).textureIndex]; + }else if(decoy.getCaster() instanceof EntityPlayer){ + return ((AbstractClientPlayer) decoy.getCaster()).getLocationSkin(); + }else{ + return steveTextures; + } + } + + protected void renderEquippedItems(EntityDecoy decoy, float p_77029_2_) + { + if(decoy.getCaster() instanceof EntityPlayer){ + + GL11.glColor3f(1.0F, 1.0F, 1.0F); + super.renderEquippedItems(decoy, p_77029_2_); + super.renderArrowsStuckInEntity(decoy, p_77029_2_); + ItemStack itemstack = ((AbstractClientPlayer)decoy.getCaster()).inventory.armorItemInSlot(3); + + if (itemstack != null) + { + GL11.glPushMatrix(); + this.modelBipedMain.bipedHead.postRender(0.0625F); + float f1; + + if (itemstack.getItem() instanceof ItemBlock) + { + net.minecraftforge.client.IItemRenderer customRenderer = net.minecraftforge.client.MinecraftForgeClient.getItemRenderer(itemstack, net.minecraftforge.client.IItemRenderer.ItemRenderType.EQUIPPED); + boolean is3D = (customRenderer != null && customRenderer.shouldUseRenderHelper(net.minecraftforge.client.IItemRenderer.ItemRenderType.EQUIPPED, itemstack, net.minecraftforge.client.IItemRenderer.ItemRendererHelper.BLOCK_3D)); + + if (is3D || RenderBlocks.renderItemIn3d(Block.getBlockFromItem(itemstack.getItem()).getRenderType())) + { + f1 = 0.625F; + GL11.glTranslatef(0.0F, -0.25F, 0.0F); + GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F); + GL11.glScalef(f1, -f1, -f1); + } + + this.renderManager.itemRenderer.renderItem(decoy, itemstack, 0); + } + else if (itemstack.getItem() == Items.skull) + { + f1 = 1.0625F; + GL11.glScalef(f1, -f1, -f1); + GameProfile gameprofile = null; + + if (itemstack.hasTagCompound()) + { + NBTTagCompound nbttagcompound = itemstack.getTagCompound(); + + if (nbttagcompound.hasKey("SkullOwner", 10)) + { + gameprofile = NBTUtil.func_152459_a(nbttagcompound.getCompoundTag("SkullOwner")); + } + else if (nbttagcompound.hasKey("SkullOwner", 8) && !StringUtils.isNullOrEmpty(nbttagcompound.getString("SkullOwner"))) + { + gameprofile = new GameProfile((UUID)null, nbttagcompound.getString("SkullOwner")); + } + } + + TileEntitySkullRenderer.field_147536_b.func_152674_a(-0.5F, 0.0F, -0.5F, 1, 180.0F, itemstack.getItemDamage(), gameprofile); + } + + GL11.glPopMatrix(); + } + + float f2; + + if (decoy.getCommandSenderName().equals("deadmau5") && ((AbstractClientPlayer)decoy.getCaster()).func_152123_o()) + { + this.bindTexture(((AbstractClientPlayer)decoy.getCaster()).getLocationSkin()); + + for (int j = 0; j < 2; ++j) + { + float f9 = decoy.prevRotationYaw + (decoy.rotationYaw - decoy.prevRotationYaw) * p_77029_2_ - (decoy.prevRenderYawOffset + (decoy.renderYawOffset - decoy.prevRenderYawOffset) * p_77029_2_); + float f10 = decoy.prevRotationPitch + (decoy.rotationPitch - decoy.prevRotationPitch) * p_77029_2_; + GL11.glPushMatrix(); + GL11.glRotatef(f9, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(f10, 1.0F, 0.0F, 0.0F); + GL11.glTranslatef(0.375F * (float)(j * 2 - 1), 0.0F, 0.0F); + GL11.glTranslatef(0.0F, -0.375F, 0.0F); + GL11.glRotatef(-f10, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(-f9, 0.0F, 1.0F, 0.0F); + f2 = 1.3333334F; + GL11.glScalef(f2, f2, f2); + this.modelBipedMain.renderEars(0.0625F); + GL11.glPopMatrix(); + } + } + + boolean flag = ((AbstractClientPlayer)decoy.getCaster()).func_152122_n(); + float f4; + + if (flag && !decoy.isInvisible() && !((AbstractClientPlayer)decoy.getCaster()).getHideCape()) + { + this.bindTexture(((AbstractClientPlayer)decoy.getCaster()).getLocationCape()); + GL11.glPushMatrix(); + GL11.glTranslatef(0.0F, 0.0F, 0.125F); + double d3 = ((AbstractClientPlayer)decoy.getCaster()).field_71091_bM + (((AbstractClientPlayer)decoy.getCaster()).field_71094_bP - ((AbstractClientPlayer)decoy.getCaster()).field_71091_bM) * (double)p_77029_2_ - (decoy.prevPosX + (decoy.posX - decoy.prevPosX) * (double)p_77029_2_); + double d4 = ((AbstractClientPlayer)decoy.getCaster()).field_71096_bN + (((AbstractClientPlayer)decoy.getCaster()).field_71095_bQ - ((AbstractClientPlayer)decoy.getCaster()).field_71096_bN) * (double)p_77029_2_ - (decoy.prevPosY + (decoy.posY - decoy.prevPosY) * (double)p_77029_2_); + double d0 = ((AbstractClientPlayer)decoy.getCaster()).field_71097_bO + (((AbstractClientPlayer)decoy.getCaster()).field_71085_bR - ((AbstractClientPlayer)decoy.getCaster()).field_71097_bO) * (double)p_77029_2_ - (decoy.prevPosZ + (decoy.posZ - decoy.prevPosZ) * (double)p_77029_2_); + f4 = decoy.prevRenderYawOffset + (decoy.renderYawOffset - decoy.prevRenderYawOffset) * p_77029_2_; + double d1 = (double)MathHelper.sin(f4 * (float)Math.PI / 180.0F); + double d2 = (double)(-MathHelper.cos(f4 * (float)Math.PI / 180.0F)); + float f5 = (float)d4 * 10.0F; + + if (f5 < -6.0F) + { + f5 = -6.0F; + } + + if (f5 > 32.0F) + { + f5 = 32.0F; + } + + float f6 = (float)(d3 * d1 + d0 * d2) * 100.0F; + float f7 = (float)(d3 * d2 - d0 * d1) * 100.0F; + + if (f6 < 0.0F) + { + f6 = 0.0F; + } + + float f8 = ((AbstractClientPlayer)decoy.getCaster()).prevCameraYaw + (((AbstractClientPlayer)decoy.getCaster()).cameraYaw - ((AbstractClientPlayer)decoy.getCaster()).prevCameraYaw) * p_77029_2_; + f5 += MathHelper.sin((decoy.prevDistanceWalkedModified + (decoy.distanceWalkedModified - decoy.prevDistanceWalkedModified) * p_77029_2_) * 6.0F) * 32.0F * f8; + + if (decoy.isSneaking()) + { + f5 += 25.0F; + } + + GL11.glRotatef(6.0F + f6 / 2.0F + f5, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(f7 / 2.0F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(-f7 / 2.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(180.0F, 0.0F, 1.0F, 0.0F); + this.modelBipedMain.renderCloak(0.0625F); + GL11.glPopMatrix(); + } + + ItemStack itemstack1 = ((AbstractClientPlayer)decoy.getCaster()).inventory.getCurrentItem(); + + if (itemstack1 != null) + { + GL11.glPushMatrix(); + this.modelBipedMain.bipedRightArm.postRender(0.0625F); + GL11.glTranslatef(-0.0625F, 0.4375F, 0.0625F); + + EnumAction enumaction = null; + + if (((AbstractClientPlayer)decoy.getCaster()).getItemInUseCount() > 0) + { + enumaction = itemstack1.getItemUseAction(); + } + + net.minecraftforge.client.IItemRenderer customRenderer = net.minecraftforge.client.MinecraftForgeClient.getItemRenderer(itemstack1, net.minecraftforge.client.IItemRenderer.ItemRenderType.EQUIPPED); + boolean is3D = (customRenderer != null && customRenderer.shouldUseRenderHelper(net.minecraftforge.client.IItemRenderer.ItemRenderType.EQUIPPED, itemstack1, net.minecraftforge.client.IItemRenderer.ItemRendererHelper.BLOCK_3D)); + + if (is3D || itemstack1.getItem() instanceof ItemBlock && RenderBlocks.renderItemIn3d(Block.getBlockFromItem(itemstack1.getItem()).getRenderType())) + { + f2 = 0.5F; + GL11.glTranslatef(0.0F, 0.1875F, -0.3125F); + f2 *= 0.75F; + GL11.glRotatef(20.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + GL11.glScalef(-f2, -f2, f2); + } + else if (itemstack1.getItem() == Items.bow) + { + f2 = 0.625F; + GL11.glTranslatef(0.0F, 0.125F, 0.3125F); + GL11.glRotatef(-20.0F, 0.0F, 1.0F, 0.0F); + GL11.glScalef(f2, -f2, f2); + GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + } + else if (itemstack1.getItem().isFull3D()) + { + f2 = 0.625F; + + if (itemstack1.getItem().shouldRotateAroundWhenRendering()) + { + GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(0.0F, -0.125F, 0.0F); + } + + if (((AbstractClientPlayer)decoy.getCaster()).getItemInUseCount() > 0 && enumaction == EnumAction.block) + { + GL11.glTranslatef(0.05F, 0.0F, -0.1F); + GL11.glRotatef(-50.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(-10.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(-60.0F, 0.0F, 0.0F, 1.0F); + } + + GL11.glTranslatef(0.0F, 0.1875F, 0.0F); + GL11.glScalef(f2, -f2, f2); + GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + } + else + { + f2 = 0.375F; + GL11.glTranslatef(0.25F, 0.1875F, -0.1875F); + GL11.glScalef(f2, f2, f2); + GL11.glRotatef(60.0F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(20.0F, 0.0F, 0.0F, 1.0F); + } + + float f3; + int k; + float f12; + + if (itemstack1.getItem().requiresMultipleRenderPasses()) + { + for (k = 0; k < itemstack1.getItem().getRenderPasses(itemstack1.getItemDamage()); ++k) + { + int i = itemstack1.getItem().getColorFromItemStack(itemstack1, k); + f12 = (float)(i >> 16 & 255) / 255.0F; + f3 = (float)(i >> 8 & 255) / 255.0F; + f4 = (float)(i & 255) / 255.0F; + GL11.glColor4f(f12, f3, f4, 1.0F); + this.renderManager.itemRenderer.renderItem(decoy, itemstack1, k); + } + } + else + { + k = itemstack1.getItem().getColorFromItemStack(itemstack1, 0); + float f11 = (float)(k >> 16 & 255) / 255.0F; + f12 = (float)(k >> 8 & 255) / 255.0F; + f3 = (float)(k & 255) / 255.0F; + GL11.glColor4f(f11, f12, f3, 1.0F); + this.renderManager.itemRenderer.renderItem(decoy, itemstack1, 0); + } + + GL11.glPopMatrix(); + } + + }else{ + super.renderEquippedItems(decoy, p_77029_2_); + } + } + + /** + * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: + * entityLiving, partialTickTime + */ + protected void preRenderCallback(EntityDecoy p_77041_1_, float p_77041_2_) + { + float f1 = 0.9375F; + GL11.glScalef(f1, f1, f1); + } + + /** + * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: + * entityLiving, partialTickTime + */ + protected void preRenderCallback(EntityLivingBase p_77041_1_, float p_77041_2_) + { + this.preRenderCallback((EntityDecoy)p_77041_1_, p_77041_2_); + } + + protected void func_82408_c(EntityLivingBase p_82408_1_, int p_82408_2_, float p_82408_3_) + { + this.func_82408_c((EntityDecoy)p_82408_1_, p_82408_2_, p_82408_3_); + } + + /** + * Queries whether should render the specified pass or not. + */ + protected int shouldRenderPass(EntityLivingBase p_77032_1_, int p_77032_2_, float p_77032_3_) + { + return this.shouldRenderPass((EntityDecoy)p_77032_1_, p_77032_2_, p_77032_3_); + } + + protected void renderEquippedItems(EntityLivingBase p_77029_1_, float p_77029_2_) + { + this.renderEquippedItems((EntityDecoy)p_77029_1_, p_77029_2_); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then + * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic + * (Render +public class RenderEvilWizard extends RenderBiped { static final ResourceLocation[] textures = new ResourceLocation[6]; - public RenderEvilWizard(RenderManager renderManager){ - - super(renderManager, new ModelWizard(), 0.5F); - + /** Model of the EvilWizard. */ + protected ModelWizard villagerModel; + + public RenderEvilWizard() + { + super(new ModelWizard(), 0.5F); + this.villagerModel = (ModelWizard)this.mainModel; for(int i=0;i<6;i++){ - textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/evil_wizard_" + i + ".png"); + textures[i] = new ResourceLocation("wizardry:textures/entity/evil_wizard_" + i + ".png"); } - // Just using the default without overriding models, since the armour sets its own model anyway. - this.addLayer(new LayerBipedArmor(this)); - } - - @Override - protected ResourceLocation getEntityTexture(EntityEvilWizard wizard) { - return textures[wizard.textureIndex]; } + /** + * Determines wether Villager Render pass or not. + */ + protected int shouldVillagerRenderPass(EntityEvilWizard par1EntityEvilWizard, int par2, float par3) + { + return -1; + } + + public void renderVillager(EntityEvilWizard par1EntityEvilWizard, double par2, double par4, double par6, float par8, float par9) + { + super.doRender(par1EntityEvilWizard, par2, par4, par6, par8, par9); + } + + protected ResourceLocation func_110902_a(EntityEvilWizard par1EntityEvilWizard) + { + return textures[par1EntityEvilWizard.textureIndex]; + } + + protected void renderVillagerEquipedItems(EntityEvilWizard par1EntityEvilWizard, float par2) + { + super.renderEquippedItems(par1EntityEvilWizard, par2); + } + + protected void preRenderVillager(EntityEvilWizard par1EntityEvilWizard, float par2) + { + float f1 = 0.9375F; + this.shadowSize = 0.5F; + + GL11.glScalef(f1, f1, f1); + } + + public void doRenderLiving(EntityLiving par1EntityLiving, double par2, double par4, double par6, float par8, float par9) + { + this.renderVillager((EntityEvilWizard)par1EntityLiving, par2, par4, par6, par8, par9); + } + + /** + * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: + * entityLiving, partialTickTime + */ + protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float par2) + { + this.preRenderVillager((EntityEvilWizard)par1EntityLivingBase, par2); + } + + /** + * Queries whether should render the specified pass or not. + */ + protected int shouldRenderPass(EntityLivingBase par1EntityLivingBase, int par2, float par3) + { + // TODO: Is this the right method name now? There are several with correct parameters. This one may end up being recursive! + return this.shouldRenderPass((EntityLiving)par1EntityLivingBase, par2, par3); + //return this.shouldVillagerRenderPass((EntityEvilWizard)par1EntityLivingBase, par2, par3); + } + + protected void renderEquippedItems(EntityLivingBase par1EntityLivingBase, float par2) + { + this.renderVillagerEquipedItems((EntityEvilWizard)par1EntityLivingBase, par2); + } + + public void renderPlayer(EntityLivingBase par1EntityLivingBase, double par2, double par4, double par6, float par8, float par9) + { + this.renderVillager((EntityEvilWizard)par1EntityLivingBase, par2, par4, par6, par8, par9); + } + + /** + * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. + */ + protected ResourceLocation getEntityTexture(Entity par1Entity) + { + return this.func_110902_a((EntityEvilWizard)par1Entity); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then + * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic + * (Render> 16 & 255) / 255.0F; + float g = (float)(colour >> 8 & 255) / 255.0F; + float b = (float)(colour & 255) / 255.0F; + + tessellator.setColorOpaque_F(f1*r, f1*g, f1*b); + this.renderBlocks.renderFaceYPos(block, -0.5D, -0.5D, -0.5D, this.renderBlocks.getBlockIconFromSideAndMetadata(block, 1, metadata)); + tessellator.setColorOpaque_F(f2, f2, f2); + this.renderBlocks.renderFaceZNeg(block, -0.5D, -0.5D, -0.5D, this.renderBlocks.getBlockIconFromSideAndMetadata(block, 2, metadata)); + tessellator.setColorOpaque_F(f2, f2, f2); + this.renderBlocks.renderFaceZPos(block, -0.5D, -0.5D, -0.5D, this.renderBlocks.getBlockIconFromSideAndMetadata(block, 3, metadata)); + tessellator.setColorOpaque_F(f3, f3, f3); + this.renderBlocks.renderFaceXNeg(block, -0.5D, -0.5D, -0.5D, this.renderBlocks.getBlockIconFromSideAndMetadata(block, 4, metadata)); + tessellator.setColorOpaque_F(f3, f3, f3); + this.renderBlocks.renderFaceXPos(block, -0.5D, -0.5D, -0.5D, this.renderBlocks.getBlockIconFromSideAndMetadata(block, 5, metadata)); + tessellator.draw(); + } +} diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderFireRing.java b/src/main/java/electroblob/wizardry/client/renderer/RenderFireRing.java index 1f70169f..c3eb7c69 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderFireRing.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderFireRing.java @@ -1,102 +1,109 @@ package electroblob.wizardry.client.renderer; -import org.lwjgl.opengl.GL11; +import javax.swing.Icon; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; -import electroblob.wizardry.entity.construct.EntityFireRing; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.entity.Render; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; import net.minecraft.init.Blocks; +import net.minecraft.util.IIcon; import net.minecraft.util.ResourceLocation; -public class RenderFireRing extends Render { +public class RenderFireRing extends Render { private final ResourceLocation texture; private float scale = 1.0f; - public RenderFireRing(RenderManager renderManager, ResourceLocation texture, float scale) { - super(renderManager); + public RenderFireRing(ResourceLocation texture, float scale) { this.texture = texture; this.scale = scale; } @Override - public void doRender(EntityFireRing entity, double par2, double par4, double par6, float par8, float par9){ + public void doRender(Entity entity, double par2, double par4, double par6, float par8, float par9){ - GlStateManager.pushMatrix(); - GlStateManager.enableBlend(); - GlStateManager.disableLighting(); + GL11.glPushMatrix(); + GL11.glEnable(GL11.GL_BLEND); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); float yOffset = 0; - GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6); + if(entity.riddenByEntity != null){ + yOffset = entity.riddenByEntity.height/2; + } + + GL11.glTranslatef((float)par2, (float)par4 + yOffset, (float)par6); this.bindTexture(texture); float f6 = 1.0F; float f7 = 0.5F; float f8 = 0.5F; - GlStateManager.rotate(-90, 1, 0, 0); + GL11.glRotatef(-90, 1, 0, 0); - GlStateManager.scale(scale, scale, scale); + GL11.glScalef(scale, scale, scale); - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex(); - buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex(); - buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex(); - buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex(); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + //tessellator.setColorRGBA_I(k1, 128); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(0.0F - f8), 0.01, 0, 1); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(0.0F - f8), 0.01, 1, 1); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(1.0F - f8), 0.01, 1, 0); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(1.0F - f8), 0.01, 0, 0); tessellator.draw(); - GlStateManager.disableBlend(); - GlStateManager.enableLighting(); - GlStateManager.disableRescaleNormal(); - GlStateManager.popMatrix(); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glPopMatrix(); // Fire - GlStateManager.disableLighting(); - TextureAtlasSprite icon = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(Blocks.FIRE.getDefaultState()).getParticleTexture(); + GL11.glDisable(GL11.GL_LIGHTING); + IIcon icon = Blocks.fire.getFireIcon(0); + IIcon icon1 = Blocks.fire.getFireIcon(1); + int sides = 16; float height = 1.0f; for(int k=0; k 0.0F){ - - this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); - float f71 = icon.getMinU(); - float f81 = icon.getMinV(); - float f9 = icon.getMaxU(); - float f10 = icon.getMaxV(); + while (f4 > 0.0F) + { + IIcon icon2 = i % 2 == 0 ? icon : icon1; + this.bindTexture(TextureMap.locationBlocksTexture); + float f71 = icon2.getMinU(); + float f81 = icon2.getMinV(); + float f9 = icon2.getMaxU(); + float f10 = icon2.getMaxV(); if (i / 2 % 2 == 0) { @@ -105,10 +112,10 @@ public class RenderFireRing extends Render { f71 = f11; } - buffer.pos((double)(f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f9, (double)f10).endVertex(); - buffer.pos((double)(-f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f71, (double)f10).endVertex(); - buffer.pos((double)(-f2 - f3), (double)(height - f5), (double)f61).tex((double)f71, (double)f81).endVertex(); - buffer.pos((double)(f2 - f3), (double)(height - f5), (double)f61).tex((double)f9, (double)f81).endVertex(); + tessellator.addVertexWithUV((double)(f2 - f3), (double)(0.0F - f5), (double)f61, (double)f9, (double)f10); + tessellator.addVertexWithUV((double)(-f2 - f3), (double)(0.0F - f5), (double)f61, (double)f71, (double)f10); + tessellator.addVertexWithUV((double)(-f2 - f3), (double)(height - f5), (double)f61, (double)f71, (double)f81); + tessellator.addVertexWithUV((double)(f2 - f3), (double)(height - f5), (double)f61, (double)f9, (double)f81); f4 -= 0.45F; f5 -= 0.45F; f2 *= 0.9F; @@ -117,35 +124,38 @@ public class RenderFireRing extends Render { } tessellator.draw(); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); } for(int k=0; k 0.0F){ - - this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); - float f71 = icon.getMinU(); - float f81 = icon.getMinV(); - float f9 = icon.getMaxU(); - float f10 = icon.getMaxV(); + while (f4 > 0.0F) + { + IIcon icon2 = i % 2 == 0 ? icon : icon1; + this.bindTexture(TextureMap.locationBlocksTexture); + float f71 = icon2.getMinU(); + float f81 = icon2.getMinV(); + float f9 = icon2.getMaxU(); + float f10 = icon2.getMaxV(); if (i / 2 % 2 == 0) { @@ -154,10 +164,10 @@ public class RenderFireRing extends Render { f71 = f11; } - buffer.pos((double)(f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f9, (double)f10).endVertex(); - buffer.pos((double)(-f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f71, (double)f10).endVertex(); - buffer.pos((double)(-f2 - f3), (double)(height - f5), (double)f61).tex((double)f71, (double)f81).endVertex(); - buffer.pos((double)(f2 - f3), (double)(height - f5), (double)f61).tex((double)f9, (double)f81).endVertex(); + tessellator.addVertexWithUV((double)(f2 - f3), (double)(0.0F - f5), (double)f61, (double)f9, (double)f10); + tessellator.addVertexWithUV((double)(-f2 - f3), (double)(0.0F - f5), (double)f61, (double)f71, (double)f10); + tessellator.addVertexWithUV((double)(-f2 - f3), (double)(height - f5), (double)f61, (double)f71, (double)f81); + tessellator.addVertexWithUV((double)(f2 - f3), (double)(height - f5), (double)f61, (double)f9, (double)f81); f4 -= 0.45F; f5 -= 0.45F; f2 *= 0.9F; @@ -166,14 +176,14 @@ public class RenderFireRing extends Render { } tessellator.draw(); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); } - GlStateManager.enableLighting(); + GL11.glEnable(GL11.GL_LIGHTING); } @Override - protected ResourceLocation getEntityTexture(EntityFireRing entity) { + protected ResourceLocation getEntityTexture(Entity entity) { return null; } diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderFirestorm.java b/src/main/java/electroblob/wizardry/client/renderer/RenderFirestorm.java new file mode 100644 index 00000000..f2f99f07 --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderFirestorm.java @@ -0,0 +1,205 @@ +package electroblob.wizardry.client.renderer; + +import org.lwjgl.opengl.GL11; + +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.entity.Entity; +import net.minecraft.init.Blocks; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; + +public class RenderFirestorm extends Render { + + private final ResourceLocation texture; + private float scale = 1.0f; + + public RenderFirestorm(ResourceLocation texture, float scale) { + this.texture = texture; + this.scale = scale; + } + + @Override + public void doRender(Entity entity, double par2, double par4, double par6, float par8, float par9){ + + GL11.glPushMatrix(); + + GL11.glTranslatef((float)par2, (float)par4, (float)par6); + + GL11.glRotatef(-entity.rotationYaw, 0, 1, 0); + GL11.glRotatef(entity.rotationPitch, 1, 0, 0); + + GL11.glPushMatrix(); + + GL11.glEnable(GL11.GL_BLEND); + GL11.glDisable(GL11.GL_LIGHTING); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + this.bindTexture(texture); + float f6 = 1.0F; + float f7 = 0.5F; + float f8 = 0.5F; + + //GL11.glRotatef(-90, 1, 0, 0); + + GL11.glScalef(scale, scale, scale); + + Tessellator tessellator = Tessellator.instance; + + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(0.0F - f8), 0.01, 0, 1); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(0.0F - f8), 0.01, 1, 1); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(1.0F - f8), 0.01, 1, 0); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(1.0F - f8), 0.01, 0, 0); + + tessellator.draw(); + + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(0.0F - f8), 0.01, 0, 1); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(1.0F - f8), 0.01, 0, 0); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(1.0F - f8), 0.01, 1, 0); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(0.0F - f8), 0.01, 1, 1); + + tessellator.draw(); + + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); + //GL11.glDisable(GL12.GL_RESCALE_NORMAL); + + GL11.glPopMatrix(); + + // Fire + + GL11.glDisable(GL11.GL_LIGHTING); + IIcon icon = Blocks.fire.getFireIcon(0); + IIcon icon1 = Blocks.fire.getFireIcon(1); + + int sides = 16; + float height = 2.0f; + + for(int k=0; k 0.0F) + { + IIcon icon2 = i % 2 == 0 ? icon : icon1; + this.bindTexture(TextureMap.locationBlocksTexture); + float f71 = icon2.getMinU(); + float f81 = icon2.getMinV(); + float f9 = icon2.getMaxU(); + float f10 = icon2.getMaxV(); + + if (i / 2 % 2 == 0) + { + float f11 = f9; + f9 = f71; + f71 = f11; + } + + tessellator.addVertexWithUV((double)(f2 - f3), (double)(0.0F - f5), (double)f61, (double)f9, (double)f10); + tessellator.addVertexWithUV((double)(-f2 - f3), (double)(0.0F - f5), (double)f61, (double)f71, (double)f10); + tessellator.addVertexWithUV((double)(-f2 - f3), (double)(height - f5), (double)f61, (double)f71, (double)f81); + tessellator.addVertexWithUV((double)(f2 - f3), (double)(height - f5), (double)f61, (double)f9, (double)f81); + f4 -= 0.45F; + f5 -= 0.45F; + f2 *= 0.9F; + f61 += 0.03F; + ++i; + } + + tessellator.draw(); + GL11.glPopMatrix(); + } + + for(int k=0; k 0.0F) + { + IIcon icon2 = i % 2 == 0 ? icon : icon1; + this.bindTexture(TextureMap.locationBlocksTexture); + float f71 = icon2.getMinU(); + float f81 = icon2.getMinV(); + float f9 = icon2.getMaxU(); + float f10 = icon2.getMaxV(); + + if (i / 2 % 2 == 0) + { + float f11 = f9; + f9 = f71; + f71 = f11; + } + + tessellator.addVertexWithUV((double)(f2 - f3), (double)(0.0F - f5), (double)f61, (double)f9, (double)f10); + tessellator.addVertexWithUV((double)(-f2 - f3), (double)(0.0F - f5), (double)f61, (double)f71, (double)f10); + tessellator.addVertexWithUV((double)(-f2 - f3), (double)(height - f5), (double)f61, (double)f71, (double)f81); + tessellator.addVertexWithUV((double)(f2 - f3), (double)(height - f5), (double)f61, (double)f9, (double)f81); + f4 -= 0.45F; + f5 -= 0.45F; + f2 *= 0.9F; + f61 += 0.03F; + ++i; + } + + tessellator.draw(); + GL11.glPopMatrix(); + } + + GL11.glEnable(GL11.GL_LIGHTING); + + GL11.glPopMatrix(); + } + + @Override + protected ResourceLocation getEntityTexture(Entity entity) { + return null; + } + +} diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderForceArrow.java b/src/main/java/electroblob/wizardry/client/renderer/RenderForceArrow.java index db37b23d..215bf087 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderForceArrow.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderForceArrow.java @@ -1,47 +1,44 @@ package electroblob.wizardry.client.renderer; -import org.lwjgl.opengl.GL11; - -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.entity.projectile.EntityForceArrow; -import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.entity.Render; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.MathHelper; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.entity.projectile.EntityMagicMissile; @SideOnly(Side.CLIENT) -public class RenderForceArrow extends Render{ +public class RenderForceArrow extends Render +{ + private static final ResourceLocation arrowTextures = new ResourceLocation("wizardry:textures/entity/force_arrow.png"); - private static final ResourceLocation arrowTextures = new ResourceLocation(Wizardry.MODID, "textures/entity/force_arrow.png"); - - public RenderForceArrow(RenderManager renderManager){ - super(renderManager); + public RenderForceArrow(){ + } - @Override - public void doRender(EntityForceArrow arrow, double par2, double par4, double par6, float par8, float par9){ - - this.bindEntityTexture(arrow); - GlStateManager.pushMatrix(); - GlStateManager.disableLighting(); + public void renderArrow(Entity par1EntityArrow, double par2, double par4, double par6, float par8, float par9) + { + this.bindEntityTexture(par1EntityArrow); + GL11.glPushMatrix(); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - GlStateManager.translate((float)par2, (float)par4, (float)par6); - GlStateManager.rotate(arrow.prevRotationYaw + (arrow.rotationYaw - arrow.prevRotationYaw) * par9 - 90.0F, 0.0F, 1.0F, 0.0F); - GlStateManager.rotate(arrow.prevRotationPitch + (arrow.rotationPitch - arrow.prevRotationPitch) * par9, 0.0F, 0.0F, 1.0F); - GlStateManager.rotate(180, 0, 1, 0); - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); + GL11.glTranslatef((float)par2, (float)par4, (float)par6); + GL11.glRotatef(par1EntityArrow.prevRotationYaw + (par1EntityArrow.rotationYaw - par1EntityArrow.prevRotationYaw) * par9 - 90.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(par1EntityArrow.prevRotationPitch + (par1EntityArrow.rotationPitch - par1EntityArrow.prevRotationPitch) * par9, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(180, 0, 1, 0); + Tessellator tessellator = Tessellator.instance; float pixel = 1.0f/32.0f; float u1 = 0.0f; float u2 = pixel*14; @@ -57,71 +54,89 @@ public class RenderForceArrow extends Render{ float v6 = 1.0f; float scale = 0.05625F; float f11 = 0.0f; - GlStateManager.enableRescaleNormal(); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); //f11 = (float)par1EntityArrow.arrowShake - par9; if (f11 > 0.0F) { float f12 = -MathHelper.sin(f11 * 3.0F) * f11; - GlStateManager.rotate(f12, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(f12, 0.0F, 0.0F, 1.0F); } scale*=0.8f; - GlStateManager.rotate(45.0F, 1.0F, 0.0F, 0.0F); - GlStateManager.scale(scale, scale, scale); - GlStateManager.translate(-4.0F, 0.0F, 0.0F); + GL11.glRotatef(45.0F, 1.0F, 0.0F, 0.0F); + GL11.glScalef(scale, scale, scale); + GL11.glTranslatef(-4.0F, 0.0F, 0.0F); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - buffer.pos(-5, 3.5, -3.5).tex((double)u5, (double)v5).endVertex(); - buffer.pos(-5, 3.5, 3.5).tex((double)u6, (double)v5).endVertex(); - buffer.pos(-5, -3.5, 3.5).tex((double)u6, (double)v6).endVertex(); - buffer.pos(-5, -3.5, -3.5).tex((double)u5, (double)v6); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(-5, 3.5, -3.5, (double)u5, (double)v5); + tessellator.addVertexWithUV(-5, 3.5, 3.5, (double)u6, (double)v5); + tessellator.addVertexWithUV(-5, -3.5, 3.5, (double)u6, (double)v6); + tessellator.addVertexWithUV(-5, -3.5, -3.5, (double)u5, (double)v6); tessellator.draw(); for(int i=0; i<5; i++){ - GlStateManager.color(1, 1, 1, 1 - i*0.2f); - double j = i + ((double)arrow.ticksExisted%3)/3; + GL11.glColor4f(1, 1, 1, 1 - i*0.2f); + double j = i + ((double)par1EntityArrow.ticksExisted%3)/3; double width = 2.0d + (Math.sqrt(j*2)-0.6)*2; GL11.glNormal3f(scale, 0.0F, 0.0F); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - buffer.pos(-10 + j*4, -width, -width).tex((double)u3, (double)v3).endVertex(); - buffer.pos(-10 + j*4, -width, width).tex((double)u4, (double)v3).endVertex(); - buffer.pos(-10 + j*4, width, width).tex((double)u4, (double)v4).endVertex(); - buffer.pos(-10 + j*4, width, -width).tex((double)u3, (double)v4).endVertex(); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(-10 + j*4, -width, -width, (double)u3, (double)v3); + tessellator.addVertexWithUV(-10 + j*4, -width, width, (double)u4, (double)v3); + tessellator.addVertexWithUV(-10 + j*4, width, width, (double)u4, (double)v4); + tessellator.addVertexWithUV(-10 + j*4, width, -width, (double)u3, (double)v4); tessellator.draw(); GL11.glNormal3f(-scale, 0.0F, 0.0F); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - buffer.pos(-10 + j*4, width, -width).tex((double)u3, (double)v3).endVertex(); - buffer.pos(-10 + j*4, width, width).tex((double)u4, (double)v3).endVertex(); - buffer.pos(-10 + j*4, -width, width).tex((double)u4, (double)v4).endVertex(); - buffer.pos(-10 + j*4, -width, -width).tex((double)u3, (double)v4).endVertex(); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(-10 + j*4, width, -width, (double)u3, (double)v3); + tessellator.addVertexWithUV(-10 + j*4, width, width, (double)u4, (double)v3); + tessellator.addVertexWithUV(-10 + j*4, -width, width, (double)u4, (double)v4); + tessellator.addVertexWithUV(-10 + j*4, -width, -width, (double)u3, (double)v4); tessellator.draw(); } - GlStateManager.color(1, 1, 1, 1); + GL11.glColor4f(1, 1, 1, 1); for (int i = 0; i < 4; ++i) { - GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(90.0F, 1.0F, 0.0F, 0.0F); GL11.glNormal3f(0.0F, 0.0F, scale); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - buffer.pos(-10.0D, -4.0D, 0.0D).tex((double)u1, (double)v1).endVertex(); - buffer.pos(10.0D, -4.0D, 0.0D).tex((double)u2, (double)v1).endVertex(); - buffer.pos(10.0D, 4.0D, 0.0D).tex((double)u2, (double)v2).endVertex(); - buffer.pos(-10.0D, 4.0D, 0.0D).tex((double)u1, (double)v2).endVertex(); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(-10.0D, -4.0D, 0.0D, (double)u1, (double)v1); + tessellator.addVertexWithUV(10.0D, -4.0D, 0.0D, (double)u2, (double)v1); + tessellator.addVertexWithUV(10.0D, 4.0D, 0.0D, (double)u2, (double)v2); + tessellator.addVertexWithUV(-10.0D, 4.0D, 0.0D, (double)u1, (double)v2); tessellator.draw(); } - GlStateManager.disableBlend(); + GL11.glDisable(GL11.GL_BLEND); - GlStateManager.disableRescaleNormal(); - GlStateManager.enableLighting(); - GlStateManager.popMatrix(); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glPopMatrix(); } - @Override - protected ResourceLocation getEntityTexture(EntityForceArrow par1Entity) + protected ResourceLocation getArrowTextures(Entity par1Entity) { return arrowTextures; } + + /** + * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. + */ + protected ResourceLocation getEntityTexture(Entity par1Entity) + { + return this.getArrowTextures(par1Entity); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then + * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic + * (Render { +public class RenderHammer extends Render { - private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_hammer.png"); + private static final ResourceLocation texture = new ResourceLocation("wizardry:textures/entity/lightning_hammer.png"); private ModelHammer model = new ModelHammer(); - public RenderHammer(RenderManager renderManager){ - super(renderManager); + public RenderHammer(){ + } @Override - public void doRender(EntityHammer entity, double x, double y, double z, float f, float f1) { + public void doRender(Entity entity, double x, double y, double z, float f, float f1) { - GlStateManager.pushMatrix(); - GlStateManager.translate(x, y+1.5, z); - GlStateManager.rotate(180, 0F, 0F, 1F); + GL11.glPushMatrix(); + GL11.glTranslated(x, y+1.5, z); + GL11.glRotatef(180, 0F, 0F, 1F); this.bindTexture(texture); model.render(entity, 0, 0, 0, 0, 0, 0.0625f); - GlStateManager.popMatrix(); + GL11.glPopMatrix(); } @Override - protected ResourceLocation getEntityTexture(EntityHammer entity) { + protected ResourceLocation getEntityTexture(Entity entity) { return texture; } diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderIceGiant.java b/src/main/java/electroblob/wizardry/client/renderer/RenderIceGiant.java index 4ee0812e..bdc4ea7b 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderIceGiant.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderIceGiant.java @@ -1,39 +1,104 @@ package electroblob.wizardry.client.renderer; -import electroblob.wizardry.Wizardry; +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import electroblob.wizardry.client.model.ModelIceGiant; import electroblob.wizardry.entity.living.EntityIceGiant; -import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.entity.RenderLiving; -import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; @SideOnly(Side.CLIENT) -public class RenderIceGiant extends RenderLiving { - - private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/ice_giant.png"); +public class RenderIceGiant extends RenderLiving +{ + private static final ResourceLocation iceGiantTextures = new ResourceLocation("wizardry:textures/entity/ice_giant.png"); - public RenderIceGiant(RenderManager renderManager){ - super(renderManager, new ModelIceGiant(), 0.5F); + /** Iron Golem's Model. */ + private final ModelIceGiant iceGiantModel; + + public RenderIceGiant() + { + super(new ModelIceGiant(), 0.5F); + this.iceGiantModel = (ModelIceGiant)this.mainModel; } - @Override - protected ResourceLocation getEntityTexture(EntityIceGiant entity){ - return texture; - } - - @Override - protected void rotateCorpse(EntityIceGiant entityLiving, float pitch, float yaw, float partialTicks){ - - super.rotateCorpse(entityLiving, pitch, yaw, partialTicks); - - if ((double)entityLiving.limbSwingAmount >= 0.01D){ + /** + * Renders the Iron Golem. + */ + public void doRenderIceGiant(EntityIceGiant par1EntityIceGiant, double par2, double par4, double par6, float par8, float par9) + { + super.doRender(par1EntityIceGiant, par2, par4, par6, par8, par9); + } + + protected ResourceLocation getIceGiantTextures(EntityIceGiant par1EntityIceGiant) + { + return iceGiantTextures; + } + + /** + * Rotates Iron Golem corpse. + */ + protected void rotateIceGiantCorpse(EntityIceGiant par1EntityIceGiant, float par2, float par3, float par4) + { + super.rotateCorpse(par1EntityIceGiant, par2, par3, par4); + + if ((double)par1EntityIceGiant.limbSwingAmount >= 0.01D) + { float f3 = 13.0F; - float f4 = entityLiving.limbSwing - entityLiving.limbSwingAmount * (1.0F - partialTicks) + 6.0F; + float f4 = par1EntityIceGiant.limbSwing - par1EntityIceGiant.limbSwingAmount * (1.0F - par4) + 6.0F; float f5 = (Math.abs(f4 % f3 - f3 * 0.5F) - f3 * 0.25F) / (f3 * 0.25F); - GlStateManager.rotate(6.5F * f5, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(6.5F * f5, 0.0F, 0.0F, 1.0F); } } + + /** + * Renders Iron Golem Equipped items. + */ + protected void renderIceGiantEquippedItems(EntityIceGiant par1EntityIceGiant, float par2) + { + super.renderEquippedItems(par1EntityIceGiant, par2); + } + + public void doRenderLiving(EntityLiving par1EntityLiving, double par2, double par4, double par6, float par8, float par9) + { + this.doRenderIceGiant((EntityIceGiant)par1EntityLiving, par2, par4, par6, par8, par9); + } + + protected void renderEquippedItems(EntityLivingBase par1EntityLivingBase, float par2) + { + this.renderIceGiantEquippedItems((EntityIceGiant)par1EntityLivingBase, par2); + } + + protected void rotateCorpse(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4) + { + this.rotateIceGiantCorpse((EntityIceGiant)par1EntityLivingBase, par2, par3, par4); + } + + public void renderPlayer(EntityLivingBase par1EntityLivingBase, double par2, double par4, double par6, float par8, float par9) + { + this.doRenderIceGiant((EntityIceGiant)par1EntityLivingBase, par2, par4, par6, par8, par9); + } + + /** + * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. + */ + protected ResourceLocation getEntityTexture(Entity par1Entity) + { + return this.getIceGiantTextures((EntityIceGiant)par1Entity); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then + * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic + * (Render { +public class RenderIceSpike extends Render { - private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/ice_spike.png"); + private static final ResourceLocation texture = new ResourceLocation("wizardry:textures/entity/ice_spike.png"); + + public RenderIceSpike(){ - public RenderIceSpike(RenderManager renderManager){ - super(renderManager); } @Override - public void doRender(EntityIceSpike entity, double x, double y, double z, float fa, float partialTickTime) { + public void doRender(Entity entity, double x, double y, double z, float fa, float partialTickTime) { - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); - GlStateManager.translate((float)x, (float)y, (float)z); + GL11.glTranslatef((float)x, (float)y, (float)z); // Apparently, disabling lighting... doesn't disable lighting. Or at least, you can still set the brightness // with setLightmapTextureCoords. - GlStateManager.disableLighting(); + GL11.glDisable(GL11.GL_LIGHTING); int j = entity.getBrightnessForRender(partialTickTime); int k = j % 65536; int l = j / 65536; OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); + Tessellator tessellator = Tessellator.instance; bindTexture(texture); // West face - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - buffer.pos(0, 0, 0.5).tex(1, 1).endVertex(); - buffer.pos(0, 1, 0.5).tex(1, 0).endVertex(); - buffer.pos(0, 1, -0.5).tex(0, 0).endVertex(); - buffer.pos(0, 0, -0.5).tex(0, 1).endVertex(); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(0, 0, 0.5, 1, 1); + tessellator.addVertexWithUV(0, 1, 0.5, 1, 0); + tessellator.addVertexWithUV(0, 1, -0.5, 0, 0); + tessellator.addVertexWithUV(0, 0, -0.5, 0, 1); tessellator.draw(); // South face - buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); - buffer.pos( 0.5, 0, 0).tex(1, 1).endVertex(); - buffer.pos( 0.5, 1, 0).tex(1, 0).endVertex(); - buffer.pos(-0.5, 1, 0).tex(0, 0).endVertex(); - buffer.pos(-0.5, 0, 0).tex(0, 1).endVertex(); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV( 0.5, 0, 0, 1, 1); + tessellator.addVertexWithUV( 0.5, 1, 0, 1, 0); + tessellator.addVertexWithUV(-0.5, 1, 0, 0, 0); + tessellator.addVertexWithUV(-0.5, 0, 0, 0, 1); tessellator.draw(); // East face - buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); - buffer.pos(0, 0, -0.5).tex(0, 1).endVertex(); - buffer.pos(0, 1, -0.5).tex(0, 0).endVertex(); - buffer.pos(0, 1, 0.5).tex(1, 0).endVertex(); - buffer.pos(0, 0, 0.5).tex(1, 1).endVertex(); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(0, 0, -0.5, 0, 1); + tessellator.addVertexWithUV(0, 1, -0.5, 0, 0); + tessellator.addVertexWithUV(0, 1, 0.5, 1, 0); + tessellator.addVertexWithUV(0, 0, 0.5, 1, 1); tessellator.draw(); // North face - buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); - buffer.pos(-0.5, 0, 0).tex(0, 1).endVertex(); - buffer.pos(-0.5, 1, 0).tex(0, 0).endVertex(); - buffer.pos( 0.5, 1, 0).tex(1, 0).endVertex(); - buffer.pos( 0.5, 0, 0).tex(1, 1).endVertex(); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(-0.5, 0, 0, 0, 1); + tessellator.addVertexWithUV(-0.5, 1, 0, 0, 0); + tessellator.addVertexWithUV( 0.5, 1, 0, 1, 0); + tessellator.addVertexWithUV( 0.5, 0, 0, 1, 1); tessellator.draw(); - GlStateManager.enableLighting(); - GlStateManager.popMatrix(); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glPopMatrix(); } @Override - protected ResourceLocation getEntityTexture(EntityIceSpike entity) { + protected ResourceLocation getEntityTexture(Entity entity) { return texture; } diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderLightningDisc.java b/src/main/java/electroblob/wizardry/client/renderer/RenderLightningDisc.java index a9b620fa..a108a7cf 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderLightningDisc.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderLightningDisc.java @@ -1,81 +1,82 @@ package electroblob.wizardry.client.renderer; import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; -import electroblob.wizardry.entity.projectile.EntityLightningDisc; -import net.minecraft.client.renderer.GlStateManager; +import electroblob.wizardry.entity.construct.EntityBubble; +import electroblob.wizardry.entity.construct.EntityHealAura; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.entity.Render; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; import net.minecraft.util.ResourceLocation; -public class RenderLightningDisc extends Render { +public class RenderLightningDisc extends Render { private final ResourceLocation texture; private float scale = 1.0f; - public RenderLightningDisc(RenderManager renderManager, ResourceLocation texture, float scale) { - super(renderManager); + public RenderLightningDisc(ResourceLocation texture, float scale) { this.texture = texture; this.scale = scale; } @Override - public void doRender(EntityLightningDisc entity, double par2, double par4, double par6, float par8, float par9){ + public void doRender(Entity entity, double par2, double par4, double par6, float par8, float par9){ - GlStateManager.pushMatrix(); - GlStateManager.enableBlend(); - GlStateManager.disableLighting(); + GL11.glPushMatrix(); + GL11.glEnable(GL11.GL_BLEND); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); float yOffset = 0; - GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6); + if(entity.riddenByEntity != null){ + yOffset = entity.riddenByEntity.height/2; + } + + GL11.glTranslatef((float)par2, (float)par4 + yOffset, (float)par6); this.bindTexture(texture); float f6 = 1.0F; float f7 = 0.5F; float f8 = 0.5F; - GlStateManager.rotate(-90, 1, 0, 0); + GL11.glRotatef(-90, 1, 0, 0); - GlStateManager.rotate(entity.ticksExisted*8, 0, 0, 1); + GL11.glRotatef(entity.ticksExisted*8, 0, 0, 1); - GlStateManager.scale(scale, scale, scale); + GL11.glScalef(scale, scale, scale); - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); //tessellator.setColorRGBA_I(k1, 128); - //buffer.normal(0.0F, 1.0F, 0.0F); - buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex(); - buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex(); - buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex(); - buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(0.0F - f8), 0.01, 0, 1); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(0.0F - f8), 0.01, 1, 1); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(1.0F - f8), 0.01, 1, 0); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(1.0F - f8), 0.01, 0, 0); tessellator.draw(); - buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); - //buffer.normal(0.0F, 1.0F, 0.0F); - buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex(); - buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex(); - buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex(); - buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(1.0F - f8), 0.01, 0, 0); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(1.0F - f8), 0.01, 1, 0); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(0.0F - f8), 0.01, 1, 1); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(0.0F - f8), 0.01, 0, 1); tessellator.draw(); - GlStateManager.disableBlend(); - GlStateManager.enableLighting(); - GlStateManager.disableRescaleNormal(); - GlStateManager.popMatrix(); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glPopMatrix(); } @Override - protected ResourceLocation getEntityTexture(EntityLightningDisc entity) { + protected ResourceLocation getEntityTexture(Entity entity) { return null; } diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderLightningPulse.java b/src/main/java/electroblob/wizardry/client/renderer/RenderLightningPulse.java index 2190011a..4f46d325 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderLightningPulse.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderLightningPulse.java @@ -1,71 +1,76 @@ package electroblob.wizardry.client.renderer; import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.entity.construct.EntityLightningPulse; -import net.minecraft.client.renderer.GlStateManager; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.entity.construct.EntityHealAura; +import electroblob.wizardry.entity.construct.EntityMagicConstruct; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.entity.Render; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ResourceLocation; -public class RenderLightningPulse extends Render { +public class RenderLightningPulse extends Render { private final ResourceLocation[] textures = new ResourceLocation[8]; private float scale = 1.0f; - public RenderLightningPulse(RenderManager renderManager, float scale) { - super(renderManager); + public RenderLightningPulse(float scale) { for(int i=0; i { - - private final ResourceLocation texture; +public class RenderMagicArrow extends Render +{ + // This class can now be used to render any projectile; hence this field is no longer static or final. + private ResourceLocation arrowTextures; private boolean blend; private boolean renderEnds; private double length = 8.0, width = 2.0; private int pixelsLong = 16, pixelsWide = 5; - public RenderMagicArrow(RenderManager renderManager, ResourceLocation texture, boolean blend, double length, double width, int pixelsLong, int pixelsWide, boolean renderEnds){ - super(renderManager); - this.texture = texture; + public RenderMagicArrow(ResourceLocation texture, boolean blend, double length, double width, int pixelsLong, int pixelsWide, boolean renderEnds){ + this.arrowTextures = texture; this.blend = blend; this.renderEnds = renderEnds; this.length = length; @@ -35,24 +35,22 @@ public class RenderMagicArrow extends Render { this.pixelsWide = pixelsWide; } - @Override - public void doRender(EntityMagicArrow entity, double par2, double par4, double par6, float par8, float par9){ - + public void renderArrow(Entity entity, double par2, double par4, double par6, float par8, float par9) + { this.bindEntityTexture(entity); - GlStateManager.pushMatrix(); - GlStateManager.disableLighting(); + GL11.glPushMatrix(); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); if(this.blend){ - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); } - GlStateManager.translate((float)par2, (float)par4, (float)par6); - GlStateManager.rotate(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * par9 - 90.0F, 0.0F, 1.0F, 0.0F); - GlStateManager.rotate(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * par9, 0.0F, 0.0F, 1.0F); - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); + GL11.glTranslatef((float)par2, (float)par4, (float)par6); + GL11.glRotatef(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * par9 - 90.0F, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * par9, 0.0F, 0.0F, 1.0F); + Tessellator tessellator = Tessellator.instance; float f2 = 0.0F; float f3 = pixelsLong / 32.0F; float f4 = 0.0F; @@ -63,60 +61,78 @@ public class RenderMagicArrow extends Render { float f9 = (float)10 / 32.0F; float f10 = 0.05625F; float f11 = 0.0f; - GlStateManager.enableRescaleNormal(); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); //f11 = (float)par1EntityArrow.arrowShake - par9; if (f11 > 0.0F) { float f12 = -MathHelper.sin(f11 * 3.0F) * f11; - GlStateManager.rotate(f12, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(f12, 0.0F, 0.0F, 1.0F); } - GlStateManager.rotate(45.0F, 1.0F, 0.0F, 0.0F); - GlStateManager.scale(f10, f10, f10); - GlStateManager.translate(-4.0F, 0.0F, 0.0F); + GL11.glRotatef(45.0F, 1.0F, 0.0F, 0.0F); + GL11.glScalef(f10, f10, f10); + GL11.glTranslatef(-4.0F, 0.0F, 0.0F); GL11.glNormal3f(f10, 0.0F, 0.0F); if(renderEnds){ // Ends - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - buffer.pos(-7.0D, -width, -width).tex((double)f6, (double)f8).endVertex(); - buffer.pos(-7.0D, -width, width).tex((double)f7, (double)f8).endVertex(); - buffer.pos(-7.0D, width, width).tex((double)f7, (double)f9).endVertex(); - buffer.pos(-7.0D, width, -width).tex((double)f6, (double)f9).endVertex(); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(-7.0D, -width, -width, (double)f6, (double)f8); + tessellator.addVertexWithUV(-7.0D, -width, width, (double)f7, (double)f8); + tessellator.addVertexWithUV(-7.0D, width, width, (double)f7, (double)f9); + tessellator.addVertexWithUV(-7.0D, width, -width, (double)f6, (double)f9); tessellator.draw(); GL11.glNormal3f(-f10, 0.0F, 0.0F); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - buffer.pos(-7.0D, width, -width).tex((double)f6, (double)f8).endVertex(); - buffer.pos(-7.0D, width, width).tex((double)f7, (double)f8).endVertex(); - buffer.pos(-7.0D, -width, width).tex((double)f7, (double)f9).endVertex(); - buffer.pos(-7.0D, -width, -width).tex((double)f6, (double)f9).endVertex(); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(-7.0D, width, -width, (double)f6, (double)f8); + tessellator.addVertexWithUV(-7.0D, width, width, (double)f7, (double)f8); + tessellator.addVertexWithUV(-7.0D, -width, width, (double)f7, (double)f9); + tessellator.addVertexWithUV(-7.0D, -width, -width, (double)f6, (double)f9); tessellator.draw(); } for (int i = 0; i < 4; ++i){ // Sides - GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(90.0F, 1.0F, 0.0F, 0.0F); GL11.glNormal3f(0.0F, 0.0F, f10); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - buffer.pos(-length, -width, 0.0D).tex((double)f2, (double)f4).endVertex(); - buffer.pos(length, -width, 0.0D).tex((double)f3, (double)f4).endVertex(); - buffer.pos(length, width, 0.0D).tex((double)f3, (double)f5).endVertex(); - buffer.pos(-length, width, 0.0D).tex((double)f2, (double)f5).endVertex(); + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(-length, -width, 0.0D, (double)f2, (double)f4); + tessellator.addVertexWithUV(length, -width, 0.0D, (double)f3, (double)f4); + tessellator.addVertexWithUV(length, width, 0.0D, (double)f3, (double)f5); + tessellator.addVertexWithUV(-length, width, 0.0D, (double)f2, (double)f5); tessellator.draw(); } if(this.blend){ - GlStateManager.disableBlend(); + GL11.glDisable(GL11.GL_BLEND); } - GlStateManager.disableRescaleNormal(); - GlStateManager.enableLighting(); - GlStateManager.popMatrix(); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glPopMatrix(); } - @Override - protected ResourceLocation getEntityTexture(EntityMagicArrow arrow) + protected ResourceLocation getArrowTextures(Entity par1Entity) { - return texture; + return arrowTextures; + } + + /** + * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. + */ + protected ResourceLocation getEntityTexture(Entity par1Entity) + { + return this.getArrowTextures(par1Entity); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then + * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic + * (Render { - - private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/light_ray.png"); - private static final ResourceLocation texture2 = new ResourceLocation(Wizardry.MODID, "textures/entity/light_aura.png"); +public class RenderMagicLight extends TileEntitySpecialRenderer{ + private static final ResourceLocation texture = new ResourceLocation("wizardry:textures/entity/light_ray.png"); + private static final ResourceLocation texture2 = new ResourceLocation("wizardry:textures/entity/light_aura.png"); + @Override - public void renderTileEntityAt(TileEntityMagicLight tileentity, double x, double y, double z, float f, int destroyStage){ + public void renderTileEntityAt(TileEntity tileentity, double x, double y, + double z, float f) { - GlStateManager.pushMatrix(); + GL11.glPushMatrix(); - GlStateManager.disableCull(); - GlStateManager.enableBlend(); - GlStateManager.shadeModel(GL11.GL_SMOOTH); - GlStateManager.disableLighting(); - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); - RenderHelper.disableStandardItemLighting(); + GL11.glDisable(GL11.GL_CULL_FACE); + GL11.glEnable(GL11.GL_BLEND); + GL11.glShadeModel(GL11.GL_SMOOTH); + GL11.glDisable(GL11.GL_LIGHTING); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); + RenderHelper.disableStandardItemLighting(); + + if(tileentity instanceof TileEntityMagicLight){ + + TileEntityMagicLight timerentity = (TileEntityMagicLight)tileentity; - GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5); + GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5); - if(tileentity.timer < 10){ - GlStateManager.scale((float)tileentity.timer/10, (float)tileentity.timer/10, (float)tileentity.timer/10); - } - if(tileentity.timer > tileentity.maxTimer-10){ - GlStateManager.scale((float)(tileentity.maxTimer-tileentity.timer)/10, (float)(tileentity.maxTimer-tileentity.timer)/10, (float)(tileentity.maxTimer-tileentity.timer)/10); - } + if(timerentity.timer < 10){ + GL11.glScalef((float)timerentity.timer/10, (float)timerentity.timer/10, (float)timerentity.timer/10); + } + if(timerentity.timer > timerentity.maxTimer-10){ + GL11.glScalef((float)(timerentity.maxTimer-timerentity.timer)/10, (float)(timerentity.maxTimer-timerentity.timer)/10, (float)(timerentity.maxTimer-timerentity.timer)/10); + } + + // Renders the aura effect + + Tessellator tessellator = Tessellator.instance; + + GL11.glPushMatrix(); + + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - // Renders the aura effect + // This counteracts the reverse rotation behaviour when in front f5 view. + // Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example. + float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? RenderManager.instance.playerViewX : -RenderManager.instance.playerViewX; + GL11.glRotatef(180.0F - RenderManager.instance.playerViewY, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(yaw, 1.0F, 0.0F, 0.0F); + + tessellator.startDrawingQuads(); - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); - - GlStateManager.pushMatrix(); - - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); - - // This counteracts the reverse rotation behaviour when in front f5 view. - // Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example. - float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? Minecraft.getMinecraft().getRenderManager().playerViewX : -Minecraft.getMinecraft().getRenderManager().playerViewX; - GlStateManager.rotate(180.0F - Minecraft.getMinecraft().getRenderManager().playerViewY, 0.0F, 1.0F, 0.0F); - GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F); - - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - - this.bindTexture(texture2); - - buffer.pos(-0.6, 0.6, 0).tex(0, 0).endVertex(); - buffer.pos(0.6, 0.6, 0).tex(1, 0).endVertex(); - buffer.pos(0.6, -0.6, 0).tex(1, 1).endVertex(); - buffer.pos(-0.6, -0.6, 0).tex(0, 1).endVertex(); - - tessellator.draw(); - - GlStateManager.popMatrix(); - - // Renders the rays - - // For some reason, the old blend function (GL11.GL_SRC_ALPHA, GL11.GL_SRC_ALPHA) caused the innermost - // ends of the rays to appear black, so I have changed it to this, which looks very slightly different. - GlStateManager.blendFunc(GL11.GL_ONE, GL11.GL_SRC_ALPHA); - - this.bindTexture(texture); - - if(tileentity.randomiser.length >= 30){ + this.bindTexture(texture2); + + tessellator.addVertexWithUV(-0.6, 0.6, 0, 0, 0); + tessellator.addVertexWithUV(0.6, 0.6, 0, 1, 0); + tessellator.addVertexWithUV(0.6, -0.6, 0, 1, 1); + tessellator.addVertexWithUV(-0.6, -0.6, 0, 0, 1); + + tessellator.draw(); + + GL11.glPopMatrix(); + + // Renders the rays + + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_SRC_ALPHA); + + this.bindTexture(texture); + for(int j=0; j<30; j++){ - - int sliceAngle = 20 + tileentity.randomiser[j]; - float scale = 0.5f; - - GlStateManager.pushMatrix(); - - GlStateManager.rotate(31*tileentity.randomiser[j], 1, 0, 0); - GlStateManager.rotate(31*tileentity.randomiser2[j], 0, 0, 1); - - /* - * OK, so here are the changes to rendering as far as I know: - * Vertex formats specify how the methods are arranged - * Color has to be called for every vertex, I think. - * The new methods thing is a bit weird, because other than the number of arguments there is - * essentially no difference between pos, tex, color, normal and lightmap. At least they make - * the code more readable. - */ - buffer.begin(5, DefaultVertexFormats.POSITION_TEX_COLOR); - - buffer.pos(0, 0, 0).tex(0, 0).color(255, 255, 255, 0).endVertex(); - buffer.pos(0, 0, 0).tex(0, 1).color(255, 255, 255, 0).endVertex(); - - double x1 = scale*Math.sin((tileentity.timer + 40*j)*(Math.PI/180)); - //double y1 = 0.7*Math.cos((timerentity.timer - 40*j)*(Math.PI/180))*j/10; - double z1 = scale*Math.cos((tileentity.timer + 40*j)*(Math.PI/180)); - - double x2 = scale*Math.sin((tileentity.timer + 40*j - sliceAngle)*(Math.PI/180)); - //double y2 = 0.7*Math.sin((timerentity.timer - 40*j)*(Math.PI/180))*j/10; - double z2 = scale*Math.cos((tileentity.timer + 40*j - sliceAngle)*(Math.PI/180)); - - buffer.pos(x1, 0, z1).tex(1, 0).color(0, 0, 0, 255).endVertex(); - buffer.pos(x2, 0, z2).tex(1, 1).color(0, 0, 0, 255).endVertex(); - - tessellator.draw(); - - GlStateManager.popMatrix(); + int sliceAngle = 20 + timerentity.randomiser[j]; + float scale = 0.5f; + + GL11.glPushMatrix(); + + GL11.glRotatef(31*timerentity.randomiser[j], 1, 0, 0); + GL11.glRotatef(31*timerentity.randomiser2[j], 0, 0, 1); + + tessellator.startDrawing(5); + + tessellator.setColorOpaque_I(16777215); + tessellator.addVertexWithUV(0, 0, 0, 0, 0); + tessellator.addVertexWithUV(0, 0, 0, 0, 1); + + double x1 = scale*Math.sin((timerentity.timer + 40*j)*(Math.PI/180)); + //double y1 = 0.7*Math.cos((timerentity.timer - 40*j)*(Math.PI/180))*j/10; + double z1 = scale*Math.cos((timerentity.timer + 40*j)*(Math.PI/180)); + + double x2 = scale*Math.sin((timerentity.timer + 40*j - sliceAngle)*(Math.PI/180)); + //double y2 = 0.7*Math.sin((timerentity.timer - 40*j)*(Math.PI/180))*j/10; + double z2 = scale*Math.cos((timerentity.timer + 40*j - sliceAngle)*(Math.PI/180)); + + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(x1, 0, z1, 1, 0); + tessellator.addVertexWithUV(x2, 0, z2, 1, 1); + + tessellator.draw(); + + GL11.glPopMatrix(); } } - - GlStateManager.shadeModel(GL11.GL_FLAT); - GlStateManager.enableCull(); - GlStateManager.disableBlend(); - GlStateManager.enableLighting(); - RenderHelper.enableStandardItemLighting(); - - GlStateManager.popMatrix(); + + GL11.glShadeModel(GL11.GL_FLAT); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); + RenderHelper.enableStandardItemLighting(); + + GL11.glPopMatrix(); } } diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderMagicSlime.java b/src/main/java/electroblob/wizardry/client/renderer/RenderMagicSlime.java new file mode 100644 index 00000000..a5eacc93 --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderMagicSlime.java @@ -0,0 +1,95 @@ +package electroblob.wizardry.client.renderer; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.entity.EntityMagicSlime; +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.ResourceLocation; + +@SideOnly(Side.CLIENT) +public class RenderMagicSlime extends RenderLiving +{ + private static final ResourceLocation slimeTextures = new ResourceLocation("textures/entity/slime/slime.png"); + private ModelBase scaleAmount; + + public RenderMagicSlime(ModelBase par1ModelBase, ModelBase par2ModelBase, float par3) + { + super(par1ModelBase, par3); + this.scaleAmount = par2ModelBase; + } + + /** + * Determines whether Slime Render should pass or not. + */ + protected int shouldSlimeRenderPass(EntityMagicSlime par1EntityMagicSlime, int par2, float par3) + { + if (par1EntityMagicSlime.isInvisible()) + { + return 0; + } + else if (par2 == 0) + { + this.setRenderPassModel(this.scaleAmount); + GL11.glEnable(GL11.GL_NORMALIZE); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + return 1; + } + else + { + if (par2 == 1) + { + GL11.glDisable(GL11.GL_BLEND); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + } + + return -1; + } + } + + /** + * sets the scale for the slime based on getSlimeSize in EntityMagicSlime + */ + protected void scaleSlime(EntityMagicSlime par1EntityMagicSlime, float par2) + { + float f1 = (float)par1EntityMagicSlime.getSlimeSize(); + float f2 = (par1EntityMagicSlime.prevSquishFactor + (par1EntityMagicSlime.squishFactor - par1EntityMagicSlime.prevSquishFactor) * par2) / (f1 * 0.5F + 1.0F); + float f3 = 1.0F / (f2 + 1.0F); + GL11.glScalef(f3 * f1, 1.0F / f3 * f1, f3 * f1); + } + + protected ResourceLocation getSlimeTextures(EntityMagicSlime par1EntityMagicSlime) + { + return slimeTextures; + } + + /** + * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: + * entityLiving, partialTickTime + */ + protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float par2) + { + this.scaleSlime((EntityMagicSlime)par1EntityLivingBase, par2); + } + + /** + * Queries whether should render the specified pass or not. + */ + protected int shouldRenderPass(EntityLivingBase par1EntityLivingBase, int par2, float par3) + { + return this.shouldSlimeRenderPass((EntityMagicSlime)par1EntityLivingBase, par2, par3); + } + + /** + * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. + */ + protected ResourceLocation getEntityTexture(Entity par1Entity) + { + return this.getSlimeTextures((EntityMagicSlime)par1Entity); + } +} diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderMeteor.java b/src/main/java/electroblob/wizardry/client/renderer/RenderMeteor.java new file mode 100644 index 00000000..92a578c9 --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderMeteor.java @@ -0,0 +1,75 @@ +package electroblob.wizardry.client.renderer; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.entity.EntityMeteor; +import net.minecraft.block.Block; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.entity.Entity; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; + +@SideOnly(Side.CLIENT) +public class RenderMeteor extends Render +{ + private final RenderBlocks sandRenderBlocks = new RenderBlocks(); + + public RenderMeteor() + { + this.shadowSize = 0.5F; + } + + /** + * The actual render method that is used in doRender + */ + public void doRenderFallingSand(EntityMeteor par1EntityFallingSand, double par2, double par4, double par6, float par8, float par9) + { + World world = par1EntityFallingSand.getWorld(); + Block block = Wizardry.meteor; + GL11.glPushMatrix(); + GL11.glTranslatef((float)par2, (float)par4 + 0.5f, (float)par6); + this.bindEntityTexture(par1EntityFallingSand); + GL11.glDisable(GL11.GL_LIGHTING); + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); + + par1EntityFallingSand.width = 0.98f; + par1EntityFallingSand.height = 0.98f; + + this.sandRenderBlocks.setRenderBoundsFromBlock(block); + this.sandRenderBlocks.renderBlockSandFalling(block, world, MathHelper.floor_double(par1EntityFallingSand.posX), MathHelper.floor_double(par1EntityFallingSand.posY), MathHelper.floor_double(par1EntityFallingSand.posZ), 0); + + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glPopMatrix(); + } + + protected ResourceLocation getFallingSandTextures(EntityMeteor par1Entity) + { + return TextureMap.locationBlocksTexture; + } + + /** + * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. + */ + protected ResourceLocation getEntityTexture(Entity par1Entity) + { + return this.getFallingSandTextures((EntityMeteor)par1Entity); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then + * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic + * (Render { +public class RenderPhoenix extends RenderLiving +{ + private static final ResourceLocation texture = new ResourceLocation("wizardry:textures/entity/phoenix.png"); - private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/phoenix.png"); + /** + * not actually sure this is size, is not used as of now, but the model would be recreated if the value changed and + * it seems a good match for a bat's size + */ + private int renderedPhoenixSize; - public RenderPhoenix(RenderManager renderManager){ - super(renderManager, new ModelPhoenix(), 1.0f); + public RenderPhoenix() + { + super(new ModelPhoenix(), 1.0f); + //this.renderedPhoenixSize = ((ModelPhoenix)this.mainModel).getBatSize(); } - @Override - protected ResourceLocation getEntityTexture(EntityPhoenix entity){ + public void func_82443_a(EntityPhoenix par1EntityPhoenix, double par2, double par4, double par6, float par8, float par9) + { + /* + int i = ((ModelPhoenix)this.mainModel).getBatSize(); + + if (i != this.renderedPhoenixSize) + { + this.renderedPhoenixSize = i; + this.mainModel = new ModelPhoenix(); + } + */ + super.doRender(par1EntityPhoenix, par2, par4, par6, par8, par9); + + } + + protected ResourceLocation getPhoenixTextures(EntityPhoenix par1EntityPhoenix) + { return texture; } - @Override - protected void rotateCorpse(EntityPhoenix par1EntityPhoenix, float par2, float par3, float par4){ - GlStateManager.translate(0.0F, -0.1F, 0.0F); + protected void func_82442_a(EntityPhoenix par1EntityPhoenix, float par2) + { + GL11.glScalef(1.0F, 1.0F, 1.0F); + } + + protected void func_82445_a(EntityPhoenix par1EntityPhoenix, double par2, double par4, double par6) + { + super.renderLivingAt(par1EntityPhoenix, par2, par4, par6); + } + + protected void func_82444_a(EntityPhoenix par1EntityPhoenix, float par2, float par3, float par4) + { + GL11.glTranslatef(0.0F, -0.1F, 0.0F); super.rotateCorpse(par1EntityPhoenix, par2, par3, par4); } - @Override - public void doRender(EntityPhoenix phoenix, double par2, double par4, double par6, float par8, float par9){ + public void doRenderLiving(EntityLiving par1EntityLiving, double par2, double par4, double par6, float par8, float par9) + { + this.func_82443_a((EntityPhoenix)par1EntityLiving, par2, par4, par6, par8, par9); + } + + /** + * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: + * entityLiving, partialTickTime + */ + protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float par2) + { + this.func_82442_a((EntityPhoenix)par1EntityLivingBase, par2); + } + + protected void rotateCorpse(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4) + { + this.func_82444_a((EntityPhoenix)par1EntityLivingBase, par2, par3, par4); + } + + /** + * Sets a simple glTranslate on a LivingEntity. + */ + protected void renderLivingAt(EntityLivingBase par1EntityLivingBase, double par2, double par4, double par6) + { + this.func_82445_a((EntityPhoenix)par1EntityLivingBase, par2, par4, par6); + } + + public void doRenderLiving(EntityLivingBase par1EntityLivingBase, double par2, double par4, double par6, float par8, float par9) + { + this.func_82443_a((EntityPhoenix)par1EntityLivingBase, par2, par4, par6, par8, par9); + } + + /** + * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. + */ + protected ResourceLocation getEntityTexture(Entity par1Entity) + { + return this.getPhoenixTextures((EntityPhoenix)par1Entity); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then + * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic + * (Render { - +public class RenderProjectile extends Render +{ private float scale; private boolean blend = false; private final ResourceLocation texture; - public RenderProjectile(RenderManager renderManager, float scale, ResourceLocation texture, boolean doBlending) + public RenderProjectile(float scale, ResourceLocation texture, boolean doBlending) { - super(renderManager); this.scale = scale; this.texture = texture; this.blend = doBlending; } - @Override - public void doRender(EntityMagicProjectile entity, double par2, double par4, double par6, float par8, float par9){ - - GlStateManager.pushMatrix(); + public void doRender(Entity par1Entity, double par2, double par4, double par6, float par8, float par9) + { + GL11.glPushMatrix(); this.bindTexture(texture); - GlStateManager.translate((float)par2, (float)par4, (float)par6); - GlStateManager.enableRescaleNormal(); + GL11.glTranslatef((float)par2, (float)par4, (float)par6); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); if(blend){ - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); } - GlStateManager.disableLighting(); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); float f2 = this.scale; - GlStateManager.scale(f2 / 1.0F, f2 / 1.0F, f2 / 1.0F); + GL11.glScalef(f2 / 1.0F, f2 / 1.0F, f2 / 1.0F); - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); + Tessellator tessellator = Tessellator.instance; float f3 = 0.0f; float f4 = 1.0f; @@ -62,27 +56,35 @@ public class RenderProjectile extends Render { // This counteracts the reverse rotation behaviour when in front f5 view. // Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example. float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? this.renderManager.playerViewX : -this.renderManager.playerViewX; - GlStateManager.rotate(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); - GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); + GL11.glRotatef(yaw, 1.0F, 0.0F, 0.0F); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); - //buffer.normal(0.0F, 1.0F, 0.0F); - buffer.pos((double)(0.0F - f8), (double)(0.0F - f9), 0.0D).tex((double)f3, (double)f6).endVertex(); - buffer.pos((double)(f7 - f8), (double)(0.0F - f9), 0.0D).tex((double)f4, (double)f6).endVertex(); - buffer.pos((double)(f7 - f8), (double)(1.0F - f9), 0.0D).tex((double)f4, (double)f5).endVertex(); - buffer.pos((double)(0.0F - f8), (double)(1.0F - f9), 0.0D).tex((double)f3, (double)f5).endVertex(); + tessellator.startDrawingQuads(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.addVertexWithUV((double)(0.0F - f8), (double)(0.0F - f9), 0.0D, (double)f3, (double)f6); + tessellator.addVertexWithUV((double)(f7 - f8), (double)(0.0F - f9), 0.0D, (double)f4, (double)f6); + tessellator.addVertexWithUV((double)(f7 - f8), (double)(1.0F - f9), 0.0D, (double)f4, (double)f5); + tessellator.addVertexWithUV((double)(0.0F - f8), (double)(1.0F - f9), 0.0D, (double)f3, (double)f5); tessellator.draw(); - GlStateManager.disableRescaleNormal(); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); if(blend){ - GlStateManager.disableBlend(); + GL11.glDisable(GL11.GL_BLEND); } - GlStateManager.enableLighting(); - GlStateManager.popMatrix(); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glPopMatrix(); } - - @Override - protected ResourceLocation getEntityTexture(EntityMagicProjectile par1Entity){ + + protected ResourceLocation getTextures(Entity par1Entity) + { return texture; } + + /** + * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. + */ + protected ResourceLocation getEntityTexture(Entity par1Entity) + { + return this.getTextures((Entity)par1Entity); + } } diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderShield.java b/src/main/java/electroblob/wizardry/client/renderer/RenderShield.java new file mode 100644 index 00000000..819319ae --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderShield.java @@ -0,0 +1,163 @@ +package electroblob.wizardry.client.renderer; + +import org.lwjgl.opengl.GL11; + +import electroblob.wizardry.entity.EntityShield; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.entity.DataWatcher; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.ResourceLocation; + +public class RenderShield extends Render{ + + private static final ResourceLocation texture = new ResourceLocation("wizardry:textures/entity/shield.png"); + private static final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); + + @Override + public void doRender(Entity entity, double x, double y, double z, + float fa, float fb) { + if(entity instanceof EntityShield){ + + EntityShield shield = (EntityShield)entity; + + GL11.glPushMatrix(); + + GL11.glDisable(GL11.GL_CULL_FACE); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_SRC_ALPHA); + GL11.glShadeModel(GL11.GL_SMOOTH); + //GL11.glDisable(GL11.GL_LIGHTING); + if(Minecraft.getMinecraft().renderViewEntity != shield.player.get() || Minecraft.getMinecraft().gameSettings.thirdPersonView != 0){ + GL11.glDisable(GL11.GL_LIGHTING); + } + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); + //RenderHelper.disableStandardItemLighting(); + + GL11.glTranslated(x, y + 0.3, z); + GL11.glRotatef(-1*shield.rotationYaw, 0, 1, 0); + GL11.glRotatef(shield.rotationPitch, 1, 0, 0); + + Tessellator tessellator = Tessellator.instance; + + this.bindTexture(texture); + + this.renderShield(tessellator, -1); + + // Enchantment effect + + GL11.glPushMatrix(); + + GL11.glDisable(GL11.GL_LIGHTING); + this.bindTexture(RES_ITEM_GLINT); + GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); + float f7 = 0.76F; + GL11.glColor4f(0.5F * f7, 0.25F * f7, 0.8F * f7, 1.0F); + float f8 = 0.125F; + //GL11.glScalef(f8, f8, f8); + float f9 = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F * 0.8f; + //GL11.glTranslatef(f9, 0.0F, 0.0F); + //GL11.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F); + + //this.renderShield(tessellator, f9); + + GL11.glPopMatrix(); + + GL11.glEnable(GL11.GL_LIGHTING); + + GL11.glShadeModel(GL11.GL_FLAT); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glDisable(GL11.GL_BLEND); + //RenderHelper.enableStandardItemLighting(); + + GL11.glPopMatrix(); + } + } + + @Override + protected ResourceLocation getEntityTexture(Entity entity) { + return texture; + } + + private void renderShield(Tessellator tessellator, float textureOffset){ + + double widthOuter = 0.6d; + double heightOuter = 0.7d; + double widthInner = 0.3d; + double heightInner = 0.4d; + double depth = 0.2d; + + double textureSection = 1.0d; + double textureU = 0.0d; + + if(textureOffset != -1){ + textureSection = 0.2d; + textureU = textureOffset; + } + + tessellator.startDrawing(5); + + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(-widthOuter, heightOuter - 0.3, -depth, 0, 0); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(-widthInner, heightInner, 0, textureU, 0.2); + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(-widthOuter + 0.3, heightOuter, -depth, 0, 0); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(-widthInner, heightInner, 0, textureU, 0.2); + + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(widthOuter - 0.3, heightOuter, -depth, 1, 0); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(widthInner, heightInner, 0, textureU + textureSection, 0.2); + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(widthOuter, heightOuter - 0.3, -depth, 1, 0); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(widthInner, heightInner, 0, textureU + textureSection, 0.2); + + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(widthOuter, -heightOuter + 0.3, -depth, 1, 1); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(widthInner, -heightInner, 0, textureU + textureSection, 0.8); + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(widthOuter - 0.3, -heightOuter, -depth, 1, 1); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(widthInner, -heightInner, 0, textureU + textureSection, 0.8); + + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(-widthOuter + 0.3, -heightOuter, -depth, 0, 1); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(-widthInner, -heightInner, 0, textureU, 0.8); + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(-widthOuter, -heightOuter + 0.3, -depth, 0, 1); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(-widthInner, -heightInner, 0, textureU, 0.8); + + tessellator.setColorRGBA(0, 0, 0, 255); + tessellator.addVertexWithUV(-widthOuter, heightOuter - 0.3, -depth, 0, 0); + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(-widthInner, heightInner, 0, textureU, 0.2); + + tessellator.draw(); + + tessellator.startDrawing(5); + + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(-widthInner, heightInner, 0, textureU, 0.2); + + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(widthInner, heightInner, 0, textureU + textureSection, 0.2); + + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(-widthInner, -heightInner, 0, textureU, 0.8); + + tessellator.setColorOpaque(200, 200, 255); + tessellator.addVertexWithUV(widthInner, -heightInner, 0, textureU + textureSection, 0.8); + + tessellator.draw(); + } + +} diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderSigil.java b/src/main/java/electroblob/wizardry/client/renderer/RenderSigil.java index bb33b60d..01490d8a 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderSigil.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderSigil.java @@ -1,88 +1,90 @@ package electroblob.wizardry.client.renderer; import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.construct.EntityHealAura; import electroblob.wizardry.entity.construct.EntityMagicConstruct; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.entity.Render; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.ResourceLocation; -public class RenderSigil extends Render { +public class RenderSigil extends Render { private final ResourceLocation texture; private float scale = 1.0f; private boolean invisibleToEnemies; - public RenderSigil(RenderManager renderManager, ResourceLocation texture, float scale, boolean invisibleToEnemies) { - super(renderManager); + public RenderSigil(ResourceLocation texture, float scale, boolean invisibleToEnemies) { this.texture = texture; this.scale = scale; this.invisibleToEnemies = invisibleToEnemies; } @Override - public void doRender(EntityMagicConstruct entity, double par2, double par4, double par6, float par8, float par9){ + public void doRender(Entity entity, double par2, double par4, double par6, float par8, float par9){ // Makes the sigil invisible to enemies of the player that created it - if(this.invisibleToEnemies){ + if(this.invisibleToEnemies && entity instanceof EntityMagicConstruct){ - if(entity.getCaster() instanceof EntityPlayer - && !WizardryUtilities.isPlayerAlly((EntityPlayer)entity.getCaster(), Minecraft.getMinecraft().thePlayer)){ + EntityMagicConstruct construct = (EntityMagicConstruct)entity; + + if(construct.getCaster() instanceof EntityPlayer + && !WizardryUtilities.isPlayerAlly((EntityPlayer)construct.getCaster(), Minecraft.getMinecraft().thePlayer)){ return; } } - GlStateManager.pushMatrix(); - GlStateManager.enableBlend(); - GlStateManager.disableLighting(); + GL11.glPushMatrix(); + GL11.glEnable(GL11.GL_BLEND); + GL11.glDisable(GL11.GL_LIGHTING); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); float yOffset = 0; - GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6); + if(entity.riddenByEntity != null){ + yOffset = entity.riddenByEntity.height/2; + } + + GL11.glTranslatef((float)par2, (float)par4 + yOffset, (float)par6); this.bindTexture(texture); float f6 = 1.0F; float f7 = 0.5F; float f8 = 0.5F; - GlStateManager.rotate(-90, 1, 0, 0); + GL11.glRotatef(-90, 1, 0, 0); // Healing aura rotates slowly - if(entity instanceof EntityHealAura) GlStateManager.rotate(entity.ticksExisted/3.0f, 0, 0, 1); + if(entity instanceof EntityHealAura) GL11.glRotatef(entity.ticksExisted/3.0f, 0, 0, 1); - GlStateManager.scale(scale, scale, scale); + GL11.glScalef(scale, scale, scale); - Tessellator tessellator = Tessellator.getInstance(); - VertexBuffer buffer = tessellator.getBuffer(); - buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); //tessellator.setColorRGBA_I(k1, 128); - //buffer.normal(0.0F, 1.0F, 0.0F); - buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex(); - buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex(); - buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex(); - buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex(); + tessellator.setNormal(0.0F, 1.0F, 0.0F); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(0.0F - f8), 0.01, 0, 1); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(0.0F - f8), 0.01, 1, 1); + tessellator.addVertexWithUV((double)(f6 - f7), (double)(1.0F - f8), 0.01, 1, 0); + tessellator.addVertexWithUV((double)(0.0F - f7), (double)(1.0F - f8), 0.01, 0, 0); tessellator.draw(); - GlStateManager.disableBlend(); - GlStateManager.enableLighting(); - GlStateManager.disableRescaleNormal(); - GlStateManager.popMatrix(); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glPopMatrix(); } @Override - protected ResourceLocation getEntityTexture(EntityMagicConstruct entity) { + protected ResourceLocation getEntityTexture(Entity entity) { return null; } diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderSilverfishMinion.java b/src/main/java/electroblob/wizardry/client/renderer/RenderSilverfishMinion.java new file mode 100644 index 00000000..340e6fd0 --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderSilverfishMinion.java @@ -0,0 +1,109 @@ +package electroblob.wizardry.client.renderer; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.entity.living.EntitySilverfishMinion; +import net.minecraft.client.model.ModelSilverfish; +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.ResourceLocation; + +@SideOnly(Side.CLIENT) +public class RenderSilverfishMinion extends RenderLiving +{ + private static final ResourceLocation silverfishTextures = new ResourceLocation("textures/entity/silverfish.png"); + private static final String __OBFID = "CL_00001022"; + + public RenderSilverfishMinion() + { + super(new ModelSilverfish(), 0.3F); + } + + protected float getDeathMaxRotation(EntitySilverfishMinion p_77037_1_) + { + return 180.0F; + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then + * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic + * (Render 1.0F) + { + f7 = 1.0F; + } + + GL11.glEnable(GL11.GL_ALPHA_TEST); + //GL11.glEnable(GL11.GL_BLEND); + //GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + this.mainModel.setLivingAnimations(par1EntityLivingBase, f8, f7, par9); + this.renderModel(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + float f9; + int i; + float f10; + float f11; + + /* + for (int j = 0; j < 4; ++j) + { + i = this.shouldRenderPass(par1EntityLivingBase, j, par9); + + if (i > 0) + { + this.renderPassModel.setLivingAnimations(par1EntityLivingBase, f8, f7, par9); + this.renderPassModel.render(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + + if ((i & 240) == 16) + { + this.func_82408_c(par1EntityLivingBase, j, par9); + this.renderPassModel.render(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + } + + if ((i & 15) == 15) + { + f9 = (float)par1EntityLivingBase.ticksExisted + par9; + //this.bindTexture(RES_ITEM_GLINT); + GL11.glEnable(GL11.GL_BLEND); + f10 = 0.5F; + GL11.glColor4f(f10, f10, f10, 1.0F); + GL11.glDepthFunc(GL11.GL_EQUAL); + GL11.glDepthMask(false); + + for (int k = 0; k < 2; ++k) + { + GL11.glDisable(GL11.GL_LIGHTING); + f11 = 0.76F; + GL11.glColor4f(0.5F * f11, 0.25F * f11, 0.8F * f11, 1.0F); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + //GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); + GL11.glMatrixMode(GL11.GL_TEXTURE); + GL11.glLoadIdentity(); + float f12 = f9 * (0.001F + (float)k * 0.003F) * 20.0F; + float f13 = 0.33333334F; + GL11.glScalef(f13, f13, f13); + GL11.glRotatef(30.0F - (float)k * 60.0F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(0.0F, f12, 0.0F); + GL11.glMatrixMode(GL11.GL_MODELVIEW); + this.renderPassModel.render(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + } + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glMatrixMode(GL11.GL_TEXTURE); + GL11.glDepthMask(true); + GL11.glLoadIdentity(); + GL11.glMatrixMode(GL11.GL_MODELVIEW); + GL11.glEnable(GL11.GL_LIGHTING); + //GL11.glDisable(GL11.GL_BLEND); + GL11.glDepthFunc(GL11.GL_LEQUAL); + } + + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_ALPHA_TEST); + } + } +*/ + GL11.glDisable(GL11.GL_BLEND); + + GL11.glDepthMask(true); + //this.renderEquippedItems(par1EntityLivingBase, par9); + float f14 = par1EntityLivingBase.getBrightness(par9); + i = this.getColorMultiplier(par1EntityLivingBase, f14, par9); + OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); + GL11.glDisable(GL11.GL_TEXTURE_2D); + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + + // The red hurt animation. + if ((i >> 24 & 255) > 0 || par1EntityLivingBase.hurtTime > 0 || par1EntityLivingBase.deathTime > 0) + { + GL11.glDisable(GL11.GL_TEXTURE_2D); + GL11.glDisable(GL11.GL_ALPHA_TEST); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDepthFunc(GL11.GL_EQUAL); + + if (par1EntityLivingBase.hurtTime > 0 || par1EntityLivingBase.deathTime > 0) + { + GL11.glColor4f(f14, 0.0F, 0.0F, 0.4F); + this.mainModel.render(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + + for (int l = 0; l < 4; ++l) + { + if (this.inheritRenderPass(par1EntityLivingBase, l, par9) >= 0) + { + GL11.glColor4f(f14, 0.0F, 0.0F, 0.4F); + this.renderPassModel.render(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + } + } + } + + if ((i >> 24 & 255) > 0) + { + f9 = (float)(i >> 16 & 255) / 255.0F; + f10 = (float)(i >> 8 & 255) / 255.0F; + float f15 = (float)(i & 255) / 255.0F; + f11 = (float)(i >> 24 & 255) / 255.0F; + GL11.glColor4f(f9, f10, f15, f11); + this.mainModel.render(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + + for (int i1 = 0; i1 < 4; ++i1) + { + if (this.inheritRenderPass(par1EntityLivingBase, i1, par9) >= 0) + { + GL11.glColor4f(f9, f10, f15, f11); + this.renderPassModel.render(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + } + } + } + + GL11.glDepthFunc(GL11.GL_LEQUAL); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_ALPHA_TEST); + GL11.glEnable(GL11.GL_TEXTURE_2D); + } + + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + + OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); + GL11.glEnable(GL11.GL_TEXTURE_2D); + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glPopMatrix(); + this.passSpecialRender(par1EntityLivingBase, par2, par4, par6); + MinecraftForge.EVENT_BUS.post(new RenderLivingEvent.Post(par1EntityLivingBase, this, par2, par4, par6)); + } + + /** + * Returns a rotation angle that is inbetween two other rotation angles. par1 and par2 are the angles between which + * to interpolate, par3 is probably a float between 0.0 and 1.0 that tells us where "between" the two angles we are. + * Example: par1 = 30, par2 = 50, par3 = 0.5, then return = 40 + */ + private float interpolateRotation(float par1, float par2, float par3) + { + float f3; + + for (f3 = par2 - par1; f3 < -180.0F; f3 += 360.0F) + { + ; + } + + while (f3 >= 180.0F) + { + f3 -= 360.0F; + } + + return par1 + par3 * f3; + } } diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderSpiritWolf.java b/src/main/java/electroblob/wizardry/client/renderer/RenderSpiritWolf.java index e1ffe797..3af0f3d6 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderSpiritWolf.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderSpiritWolf.java @@ -1,35 +1,320 @@ package electroblob.wizardry.client.renderer; -import org.lwjgl.opengl.GL11; - -import electroblob.wizardry.Wizardry; -import net.minecraft.client.model.ModelWolf; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.entity.RenderWolf; -import net.minecraft.entity.passive.EntityWolf; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.entity.living.EntitySpiritWolf; +import net.minecraft.client.model.ModelBase; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.passive.EntitySheep; +import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.client.event.RenderLivingEvent; +import net.minecraftforge.common.MinecraftForge; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; @SideOnly(Side.CLIENT) -public class RenderSpiritWolf extends RenderWolf { - - private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/spirit_wolf.png"); +public class RenderSpiritWolf extends RenderLiving +{ + private static final ResourceLocation wolfTextures = new ResourceLocation("wizardry:textures/entity/spirit_wolf.png"); - public RenderSpiritWolf(RenderManager renderManager, float par3){ - super(renderManager, new ModelWolf(), par3); + public RenderSpiritWolf(ModelBase par1ModelBase, ModelBase par2ModelBase, float par3) + { + super(par1ModelBase, par3); + this.setRenderPassModel(par2ModelBase); } - @Override - protected ResourceLocation getEntityTexture(EntityWolf entity) { - return texture; + protected float getTailRotation(EntitySpiritWolf par1EntitySpiritWolf, float par2) + { + return par1EntitySpiritWolf.getTailRotation(); } + protected int func_82447_a(EntitySpiritWolf par1EntitySpiritWolf, int par2, float par3) + { + float f1; + + if (par2 == 0) + { + //f1 = par1EntitySpiritWolf.getBrightness(par3) * par1EntitySpiritWolf.getShadingWhileShaking(par3); + this.bindTexture(wolfTextures); + this.setRenderPassModel(this.mainModel); + //GL11.glColor3f(f1, f1, f1); + //GL11.glEnable(GL11.GL_NORMALIZE); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + return 1; + } + /* + else if (par2 == 1 && par1EntitySpiritWolf.isTamed()) + { + f1 = par1EntitySpiritWolf.getBrightness(par3) * par1EntitySpiritWolf.getShadingWhileShaking(par3); + this.bindTexture(wolfTextures); + GL11.glColor3f(f1, f1, f1); + return 1; + } + */ + else + { + return -1; + } + } + + protected ResourceLocation func_110914_a(EntitySpiritWolf par1EntitySpiritWolf) + { + return wolfTextures; + } + + /** + * Queries whether should render the specified pass or not. + */ + protected int shouldRenderPass(EntityLivingBase par1EntityLivingBase, int par2, float par3) + { + return this.func_82447_a((EntitySpiritWolf)par1EntityLivingBase, par2, par3); + } + + /** + * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: + * entityLiving, partialTickTime + */ + protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float par2){ + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + } + + // This is overridden to allow transparent stuff to happen. @Override - protected void preRenderCallback(EntityWolf entity, float partialTickTime){ - super.preRenderCallback(entity, partialTickTime); - GlStateManager.enableBlend(); - GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + public void doRender(EntityLivingBase par1EntityLivingBase, double par2, double par4, double par6, float par8, float par9) + { + if (MinecraftForge.EVENT_BUS.post(new RenderLivingEvent.Pre(par1EntityLivingBase, this, par2, par4, par6))) return; + GL11.glPushMatrix(); + GL11.glDisable(GL11.GL_CULL_FACE); + this.mainModel.onGround = this.renderSwingProgress(par1EntityLivingBase, par9); + + if (this.renderPassModel != null) + { + this.renderPassModel.onGround = this.mainModel.onGround; + } + + this.mainModel.isRiding = par1EntityLivingBase.isRiding(); + + if (this.renderPassModel != null) + { + this.renderPassModel.isRiding = this.mainModel.isRiding; + } + + this.mainModel.isChild = par1EntityLivingBase.isChild(); + + if (this.renderPassModel != null) + { + this.renderPassModel.isChild = this.mainModel.isChild; + } + + try + { + float f2 = this.interpolateRotation(par1EntityLivingBase.prevRenderYawOffset, par1EntityLivingBase.renderYawOffset, par9); + float f3 = this.interpolateRotation(par1EntityLivingBase.prevRotationYawHead, par1EntityLivingBase.rotationYawHead, par9); + float f4; + + float f5 = par1EntityLivingBase.prevRotationPitch + (par1EntityLivingBase.rotationPitch - par1EntityLivingBase.prevRotationPitch) * par9; + this.renderLivingAt(par1EntityLivingBase, par2, par4, par6); + f4 = this.handleRotationFloat(par1EntityLivingBase, par9); + this.rotateCorpse(par1EntityLivingBase, f4, f2, par9); + float f6 = 0.0625F; + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + GL11.glScalef(-1.0F, -1.0F, 1.0F); + this.preRenderCallback(par1EntityLivingBase, par9); + GL11.glTranslatef(0.0F, -24.0F * f6 - 0.0078125F, 0.0F); + float f7 = par1EntityLivingBase.prevLimbSwingAmount + (par1EntityLivingBase.limbSwingAmount - par1EntityLivingBase.prevLimbSwingAmount) * par9; + float f8 = par1EntityLivingBase.limbSwing - par1EntityLivingBase.limbSwingAmount * (1.0F - par9); + + if (f7 > 1.0F) + { + f7 = 1.0F; + } + + GL11.glEnable(GL11.GL_ALPHA_TEST); + //GL11.glEnable(GL11.GL_BLEND); + //GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + this.mainModel.setLivingAnimations(par1EntityLivingBase, f8, f7, par9); + this.renderModel(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + float f9; + int i; + float f10; + float f11; + + /* + for (int j = 0; j < 4; ++j) + { + i = this.shouldRenderPass(par1EntityLivingBase, j, par9); + + if (i > 0) + { + this.renderPassModel.setLivingAnimations(par1EntityLivingBase, f8, f7, par9); + this.renderPassModel.render(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + + if ((i & 240) == 16) + { + this.func_82408_c(par1EntityLivingBase, j, par9); + this.renderPassModel.render(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + } + + if ((i & 15) == 15) + { + f9 = (float)par1EntityLivingBase.ticksExisted + par9; + //this.bindTexture(RES_ITEM_GLINT); + GL11.glEnable(GL11.GL_BLEND); + f10 = 0.5F; + GL11.glColor4f(f10, f10, f10, 1.0F); + GL11.glDepthFunc(GL11.GL_EQUAL); + GL11.glDepthMask(false); + + for (int k = 0; k < 2; ++k) + { + GL11.glDisable(GL11.GL_LIGHTING); + f11 = 0.76F; + GL11.glColor4f(0.5F * f11, 0.25F * f11, 0.8F * f11, 1.0F); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + //GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); + GL11.glMatrixMode(GL11.GL_TEXTURE); + GL11.glLoadIdentity(); + float f12 = f9 * (0.001F + (float)k * 0.003F) * 20.0F; + float f13 = 0.33333334F; + GL11.glScalef(f13, f13, f13); + GL11.glRotatef(30.0F - (float)k * 60.0F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(0.0F, f12, 0.0F); + GL11.glMatrixMode(GL11.GL_MODELVIEW); + this.renderPassModel.render(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + } + + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + GL11.glMatrixMode(GL11.GL_TEXTURE); + GL11.glDepthMask(true); + GL11.glLoadIdentity(); + GL11.glMatrixMode(GL11.GL_MODELVIEW); + GL11.glEnable(GL11.GL_LIGHTING); + //GL11.glDisable(GL11.GL_BLEND); + GL11.glDepthFunc(GL11.GL_LEQUAL); + } + + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_ALPHA_TEST); + } + } +*/ + GL11.glDisable(GL11.GL_BLEND); + + GL11.glDepthMask(true); + //this.renderEquippedItems(par1EntityLivingBase, par9); + float f14 = par1EntityLivingBase.getBrightness(par9); + i = this.getColorMultiplier(par1EntityLivingBase, f14, par9); + OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); + GL11.glDisable(GL11.GL_TEXTURE_2D); + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + + // The red hurt animation. + if ((i >> 24 & 255) > 0 || par1EntityLivingBase.hurtTime > 0 || par1EntityLivingBase.deathTime > 0) + { + GL11.glDisable(GL11.GL_TEXTURE_2D); + GL11.glDisable(GL11.GL_ALPHA_TEST); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDepthFunc(GL11.GL_EQUAL); + + if (par1EntityLivingBase.hurtTime > 0 || par1EntityLivingBase.deathTime > 0) + { + GL11.glColor4f(f14, 0.0F, 0.0F, 0.4F); + this.mainModel.render(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + + for (int l = 0; l < 4; ++l) + { + if (this.inheritRenderPass(par1EntityLivingBase, l, par9) >= 0) + { + GL11.glColor4f(f14, 0.0F, 0.0F, 0.4F); + this.renderPassModel.render(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + } + } + } + + if ((i >> 24 & 255) > 0) + { + f9 = (float)(i >> 16 & 255) / 255.0F; + f10 = (float)(i >> 8 & 255) / 255.0F; + float f15 = (float)(i & 255) / 255.0F; + f11 = (float)(i >> 24 & 255) / 255.0F; + GL11.glColor4f(f9, f10, f15, f11); + this.mainModel.render(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + + for (int i1 = 0; i1 < 4; ++i1) + { + if (this.inheritRenderPass(par1EntityLivingBase, i1, par9) >= 0) + { + GL11.glColor4f(f9, f10, f15, f11); + this.renderPassModel.render(par1EntityLivingBase, f8, f7, f4, f3 - f2, f5, f6); + } + } + } + + GL11.glDepthFunc(GL11.GL_LEQUAL); + GL11.glDisable(GL11.GL_BLEND); + GL11.glEnable(GL11.GL_ALPHA_TEST); + GL11.glEnable(GL11.GL_TEXTURE_2D); + } + + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + } + catch (Exception exception) + { + exception.printStackTrace(); + } + + OpenGlHelper.setActiveTexture(OpenGlHelper.lightmapTexUnit); + GL11.glEnable(GL11.GL_TEXTURE_2D); + OpenGlHelper.setActiveTexture(OpenGlHelper.defaultTexUnit); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glPopMatrix(); + this.passSpecialRender(par1EntityLivingBase, par2, par4, par6); + MinecraftForge.EVENT_BUS.post(new RenderLivingEvent.Post(par1EntityLivingBase, this, par2, par4, par6)); + } + + /** + * Returns a rotation angle that is inbetween two other rotation angles. par1 and par2 are the angles between which + * to interpolate, par3 is probably a float between 0.0 and 1.0 that tells us where "between" the two angles we are. + * Example: par1 = 30, par2 = 50, par3 = 0.5, then return = 40 + */ + private float interpolateRotation(float par1, float par2, float par3) + { + float f3; + + for (f3 = par2 - par1; f3 < -180.0F; f3 += 360.0F) + { + ; + } + + while (f3 >= 180.0F) + { + f3 -= 360.0F; + } + + return par1 + par3 * f3; + } + + /** + * Defines what float the third param in setRotationAngles of ModelBase is + */ + protected float handleRotationFloat(EntityLivingBase par1EntityLivingBase, float par2) + { + return this.getTailRotation((EntitySpiritWolf)par1EntityLivingBase, par2); + } + + /** + * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. + */ + protected ResourceLocation getEntityTexture(Entity par1Entity) + { + return this.func_110914_a((EntitySpiritWolf)par1Entity); } } diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderStatue.java b/src/main/java/electroblob/wizardry/client/renderer/RenderStatue.java index 33301d84..948e24f6 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderStatue.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderStatue.java @@ -1,64 +1,196 @@ package electroblob.wizardry.client.renderer; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.HashSet; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import cpw.mods.fml.relauncher.ReflectionHelper; import electroblob.wizardry.tileentity.TileEntityStatue; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.model.ModelBase; import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.entity.RenderZombie; +import net.minecraft.client.renderer.entity.RendererLivingEntity; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.boss.EntityWither; +import net.minecraft.entity.monster.EntityIronGolem; +import net.minecraft.entity.monster.EntityPigZombie; +import net.minecraft.entity.monster.EntityWitch; +import net.minecraft.entity.monster.EntityZombie; +import net.minecraft.entity.passive.EntityHorse; +import net.minecraft.entity.passive.EntityVillager; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ResourceLocation; -public class RenderStatue extends TileEntitySpecialRenderer { +public class RenderStatue extends TileEntitySpecialRenderer { + + private static final ResourceLocation stoneTexture32 = new ResourceLocation("wizardry:textures/entity/stone_statue_32.png"); + private static final ResourceLocation stoneTexture64 = new ResourceLocation("wizardry:textures/entity/stone_statue_64.png"); + + private static final HashSet> entitiesUsing64Texture = new HashSet>(); + + // Reflective method and field accesses; defined here since anything only ever needs to be reflectively accessed once. - private int destroyStage = 0; // Gets set each time a statue is rendered to allow access from the layer renderer + // Since the second argument is never used, it might as well be null. + private static final Method selectZombieModel = ReflectionHelper.findMethod(RenderZombie.class, null, new String[]{"func_82427_a"}, EntityZombie.class); + private static final Method preRenderCallback = ReflectionHelper.findMethod(RendererLivingEntity.class, null, new String[]{"func_77041_b", "preRenderCallback"}, EntityLivingBase.class, float.class); + private static final Method shouldRenderPass = ReflectionHelper.findMethod(RendererLivingEntity.class, null, new String[]{"func_77032_a", "shouldRenderPass"}, EntityLivingBase.class, int.class, float.class); + private static final Method renderEquippedItems = ReflectionHelper.findMethod(RendererLivingEntity.class, null, new String[]{"func_77029_c", "renderEquippedItems"}, EntityLivingBase.class, float.class); + + private static final Field mainModelField = ReflectionHelper.findField(RendererLivingEntity.class, "field_77045_g", "mainModel"); + private static final Field renderPassModelField = ReflectionHelper.findField(RendererLivingEntity.class, "field_77046_h", "renderPassModel"); + + static { + entitiesUsing64Texture.add(EntityZombie.class); + entitiesUsing64Texture.add(EntityPigZombie.class); + entitiesUsing64Texture.add(EntityVillager.class); + entitiesUsing64Texture.add(EntityWitch.class); + entitiesUsing64Texture.add(EntityHorse.class); + entitiesUsing64Texture.add(EntityIronGolem.class); + entitiesUsing64Texture.add(EntityWither.class); + } @Override - public void renderTileEntityAt(TileEntityStatue statue, double x, double y, double z, float partialTicks, int destroyStage){ + public void renderTileEntityAt(TileEntity tileentity, double x, double y, + double z, float partialTickTime) { + + GL11.glPushMatrix(); + // The next line makes stuff render in the same place relative to the world wherever the player is. + GL11.glTranslatef((float)x + 0.5F, (float)y, (float)z + 0.5F); + + if(tileentity instanceof TileEntityStatue){ + + TileEntityStatue statue = (TileEntityStatue)tileentity; + + if(statue.creature != null && statue.position == 1){ + + if(statue.isIce){ + + float yaw = statue.creature.prevRotationYaw; + int i = statue.creature.getBrightnessForRender(0); + + if (statue.creature.isBurning()) + { + i = 15728880; + } + + int j = i % 65536; + int k = i / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)j / 1.0F, (float)k / 1.0F); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + GL11.glRotatef(-yaw, 0F, 1F, 0F); + + RenderManager.instance.renderEntityWithPosYaw(statue.creature, 0, 0, 0, 0, 0); + + }else{ + + GL11.glPushMatrix(); + GL11.glDisable(GL11.GL_CULL_FACE); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + float someScalingFactor = 0.0625f; + + float yaw = statue.creature.prevRotationYaw; + int brightness = statue.creature.getBrightnessForRender(0); + + int j = brightness % 65536; + int k = brightness / 65536; + OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)j / 1.0F, (float)k / 1.0F); + GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); + + GL11.glRotatef(-yaw + 180, 0F, 1F, 0F); + + Render render = RenderManager.instance.getEntityRenderObject(statue.creature); + + if(render instanceof RendererLivingEntity){ + + RendererLivingEntity renderliving = (RendererLivingEntity)render; + + // Reflection. This is... complete madness really, but it works! + // What it effectively does is emulate the doRender method in RendererLivingEntity, but with + // my own control over the textures. + // Edit: Switched over to the forge-supplied ReflectionHelper methods, since these make it a + // lot more concise and easy to read - since they're there, I might as well use them! + // Edit 2: In order for this to work outside the development environment, you need to supply the + // obfuscated (srg) names as well as the mcp ones, unless of course they are the same. + + try { + + // Chooses the appropriate zombie model, normal or villager + // Fixed by moving before the model fields are accessed + if(render instanceof RenderZombie && statue.creature instanceof EntityZombie){ + selectZombieModel.invoke(renderliving, (EntityZombie)statue.creature); + } + + // Turns out that java automatically infers the type parameter T in this method from the type + // I am assigning the returned value to. Neat! + ModelBase mainModel = (ModelBase) mainModelField.get(renderliving); + ModelBase renderPassModel = (ModelBase) renderPassModelField.get(renderliving); + + mainModel.isRiding = statue.creature.isRiding(); + mainModel.isChild = statue.creature.isChild(); + + if(renderPassModel != null){ + renderPassModel.isRiding = statue.creature.isRiding(); + renderPassModel.isChild = statue.creature.isChild(); + } + + if(entitiesUsing64Texture.contains(statue.creature.getClass())){ + Minecraft.getMinecraft().renderEngine.bindTexture(stoneTexture64); + }else{ + Minecraft.getMinecraft().renderEngine.bindTexture(stoneTexture32); + } + + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + GL11.glScalef(-1.0F, -1.0F, 1.0F); + + preRenderCallback.invoke(renderliving, statue.creature, someScalingFactor); + + // Why is this -1.5f? No idea! + GL11.glTranslatef(0, -1.5f, 0); + + GL11.glEnable(GL11.GL_ALPHA_TEST); + + mainModel.render(statue.creature, 0, 0, 0, 0, 0, someScalingFactor); + + for(int i=0; i<4; i++){ + if((Integer)shouldRenderPass.invoke(render, statue.creature, i, someScalingFactor) > 0){ + // Should never be null here since shouldRenderPass returns -1 when it is null, but there's no harm in checking. + if(renderPassModel != null) renderPassModel.render(statue.creature, 0, 0, 0, 0, 0, someScalingFactor); + } + } + + GL11.glDepthMask(true); + + renderEquippedItems.invoke(render, statue.creature, someScalingFactor); + + // 'Pokemon' exception handling... Because why not?! + } catch (Exception e) { + System.err.println("Something went very wrong! Error while rendering petrified creature:"); + e.printStackTrace(); + } + } + + GL11.glDisable(GL11.GL_ALPHA_TEST); + GL11.glDisable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glEnable(GL11.GL_CULL_FACE); + GL11.glPopMatrix(); + + } - // Multiblock support for the breaking animation. The chest has its own way of doing this in - // TileEntityRendererDispatcher, but I don't have access to that. - if(statue.position != 1 && destroyStage >= 0){ - TileEntity tileentity = statue.getWorld().getTileEntity(statue.getPos().down(statue.position-1)); - //System.out.println(tileentity); - if(tileentity instanceof TileEntityStatue){ - // If this is the block breaking animation pass and this isn't the bottom block, divert the call to - // the bottom block. - this.renderTileEntityAt((TileEntityStatue)tileentity, x, y - (statue.position-1), z, partialTicks, destroyStage); } } - - if(statue.creature != null && statue.position == 1){ - - this.destroyStage = destroyStage; - - GlStateManager.pushMatrix(); - // The next line makes stuff render in the same place relative to the world wherever the player is. - GlStateManager.translate((float)x + 0.5F, (float)y, (float)z + 0.5F); - GlStateManager.enableLighting(); - - float yaw = statue.creature.prevRotationYaw; - int i = statue.creature.getBrightnessForRender(0); - - int j = i % 65536; - int k = i / 65536; - OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)j / 1.0F, (float)k / 1.0F); - GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); - - GlStateManager.rotate(-yaw, 0F, 1F, 0F); - // Stops the normal model from rendering. - if(!statue.isIce) statue.creature.setInvisible(true); - // Setting the last parameter to true prevents the debug bounding box from rendering. - // For some reason, passing in the partialTicks causes the entity to spin round really fast - Minecraft.getMinecraft().getRenderManager().doRenderEntity(statue.creature, 0, 0, 0, 0, 0, true); - if(!statue.isIce) statue.creature.setInvisible(false); - - GlStateManager.popMatrix(); - - } - } - - public ResourceLocation getBlockBreakingTexture(){ - return destroyStage < 0 ? null : DESTROY_STAGES[destroyStage]; + GL11.glPopMatrix(); } } diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderTransientPlayer.java b/src/main/java/electroblob/wizardry/client/renderer/RenderTransientPlayer.java new file mode 100644 index 00000000..3fa7aa7c --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderTransientPlayer.java @@ -0,0 +1,90 @@ +package electroblob.wizardry.client.renderer; + +import static net.minecraftforge.client.IItemRenderer.ItemRenderType.EQUIPPED; +import static net.minecraftforge.client.IItemRenderer.ItemRendererHelper.BLOCK_3D; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.block.Block; +import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.model.ModelBiped; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.entity.RenderBiped; +import net.minecraft.client.renderer.entity.RenderPlayer; +import net.minecraft.client.renderer.entity.RendererLivingEntity; +import net.minecraft.client.renderer.tileentity.TileEntitySkullRenderer; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumAction; +import net.minecraft.item.Item; +import net.minecraft.item.ItemArmor; +import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; +import net.minecraft.scoreboard.Score; +import net.minecraft.scoreboard.ScoreObjective; +import net.minecraft.scoreboard.Scoreboard; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.IItemRenderer; +import net.minecraftforge.client.MinecraftForgeClient; +import net.minecraftforge.client.event.RenderPlayerEvent; +import net.minecraftforge.common.MinecraftForge; + +@Deprecated +public class RenderTransientPlayer extends RenderPlayer { + + private static final ResourceLocation steveTextures = new ResourceLocation("textures/entity/steve.png"); + private ModelBiped modelBipedMain; + private ModelBiped modelArmorChestplate; + private ModelBiped modelArmor; + + public RenderTransientPlayer() + { + super(); + this.modelBipedMain = (ModelBiped)this.mainModel; + this.modelArmorChestplate = new ModelBiped(1.0F); + this.modelArmor = new ModelBiped(0.5F); + } + + public void func_130009_a(AbstractClientPlayer par1AbstractClientPlayer, double par2, double par4, double par6, float par8, float par9) + { + float f2 = 1.0F; + GL11.glColor4f(f2, f2, f2, 0.5f); + ItemStack itemstack = par1AbstractClientPlayer.inventory.getCurrentItem(); + this.modelArmorChestplate.heldItemRight = this.modelArmor.heldItemRight = this.modelBipedMain.heldItemRight = itemstack != null ? 1 : 0; + + if (itemstack != null && par1AbstractClientPlayer.getItemInUseCount() > 0) + { + EnumAction enumaction = itemstack.getItemUseAction(); + + if (enumaction == EnumAction.block) + { + this.modelArmorChestplate.heldItemRight = this.modelArmor.heldItemRight = this.modelBipedMain.heldItemRight = 3; + } + else if (enumaction == EnumAction.bow) + { + this.modelArmorChestplate.aimedBow = this.modelArmor.aimedBow = this.modelBipedMain.aimedBow = true; + } + } + + this.modelArmorChestplate.isSneak = this.modelArmor.isSneak = this.modelBipedMain.isSneak = par1AbstractClientPlayer.isSneaking(); + double d3 = par4 - (double)par1AbstractClientPlayer.yOffset; + + if (par1AbstractClientPlayer.isSneaking() && !(par1AbstractClientPlayer instanceof EntityPlayerSP)) + { + d3 -= 0.125D; + } + + super.doRender(par1AbstractClientPlayer, par2, d3, par6, par8, par9); + this.modelArmorChestplate.aimedBow = this.modelArmor.aimedBow = this.modelBipedMain.aimedBow = false; + this.modelArmorChestplate.isSneak = this.modelArmor.isSneak = this.modelBipedMain.isSneak = false; + this.modelArmorChestplate.heldItemRight = this.modelArmor.heldItemRight = this.modelBipedMain.heldItemRight = 0; + MinecraftForge.EVENT_BUS.post(new RenderPlayerEvent.Post(par1AbstractClientPlayer, this, par9)); + } + +} diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderTranslucentItem.java b/src/main/java/electroblob/wizardry/client/renderer/RenderTranslucentItem.java new file mode 100644 index 00000000..7eacf26c --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderTranslucentItem.java @@ -0,0 +1,97 @@ +package electroblob.wizardry.client.renderer; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.IItemRenderer; + +public class RenderTranslucentItem implements IItemRenderer { + + Minecraft mc = Minecraft.getMinecraft(); + + private static final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); + + @Override + public boolean handleRenderType(ItemStack item, ItemRenderType type) { + if(type == ItemRenderType.EQUIPPED_FIRST_PERSON || type == ItemRenderType.EQUIPPED){ + return true; + } + return false; + } + + @Override + public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, + ItemRendererHelper helper) { + return false; + } + + @Override + public void renderItem(ItemRenderType type, ItemStack item, Object... data) { + if(type == ItemRenderType.EQUIPPED_FIRST_PERSON || type == ItemRenderType.EQUIPPED){ + + GL11.glPushMatrix(); + + TextureManager texturemanager = this.mc.getTextureManager(); + IIcon icon = mc.thePlayer.getItemIcon(item, 1); + + if (icon == null) + { + GL11.glPopMatrix(); + return; + } + + texturemanager.bindTexture(texturemanager.getResourceLocation(item.getItemSpriteNumber())); + Tessellator tessellator = Tessellator.instance; + float f = icon.getMinU(); + float f1 = icon.getMaxU(); + float f2 = icon.getMinV(); + float f3 = icon.getMaxV(); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + GL11.glEnable(GL11.GL_BLEND); + ItemRenderer.renderItemIn2D(tessellator, f1, f2, f, f3, icon.getIconWidth(), icon.getIconHeight(), 0.0625F); + + if (item.hasEffect(1)) + { + GL11.glDepthFunc(GL11.GL_EQUAL); + GL11.glDisable(GL11.GL_LIGHTING); + texturemanager.bindTexture(RES_ITEM_GLINT); + GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); + float f7 = 0.76F; + GL11.glColor4f(0.5F * f7, 0.25F * f7, 0.8F * f7, 1.0F); + GL11.glMatrixMode(GL11.GL_TEXTURE); + GL11.glPushMatrix(); + float f8 = 0.125F; + GL11.glScalef(f8, f8, f8); + float f9 = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F * 8.0F; + GL11.glTranslatef(f9, 0.0F, 0.0F); + GL11.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F); + ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + GL11.glScalef(f8, f8, f8); + f9 = (float)(Minecraft.getSystemTime() % 4873L) / 4873.0F * 8.0F; + GL11.glTranslatef(-f9, 0.0F, 0.0F); + GL11.glRotatef(10.0F, 0.0F, 0.0F, 1.0F); + ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); + GL11.glPopMatrix(); + GL11.glMatrixMode(GL11.GL_MODELVIEW); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDepthFunc(GL11.GL_LEQUAL); + } + + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glDisable(GL11.GL_BLEND); + + GL11.glPopMatrix(); + } + } + +} diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderWand.java b/src/main/java/electroblob/wizardry/client/renderer/RenderWand.java new file mode 100644 index 00000000..d248668a --- /dev/null +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderWand.java @@ -0,0 +1,134 @@ +package electroblob.wizardry.client.renderer; + +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.IItemRenderer; + +@Deprecated +public class RenderWand implements IItemRenderer { + + Minecraft mc = Minecraft.getMinecraft(); + + private static final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png"); + private static final ResourceLocation magicEffect = new ResourceLocation("wizardry:textures/entity/aura.png"); + + @Override + public boolean handleRenderType(ItemStack item, ItemRenderType type) { + if(type == ItemRenderType.EQUIPPED_FIRST_PERSON || type == ItemRenderType.EQUIPPED){ + return true; + } + return false; + } + + @Override + public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, + ItemRendererHelper helper) { + return false; + } + + @Override + public void renderItem(ItemRenderType type, ItemStack item, Object... data) { + if(type == ItemRenderType.EQUIPPED_FIRST_PERSON || type == ItemRenderType.EQUIPPED){ + + GL11.glPushMatrix(); + + TextureManager texturemanager = this.mc.getTextureManager(); + IIcon icon = mc.thePlayer.getItemIcon(item, 1); + + if (icon == null) + { + GL11.glPopMatrix(); + return; + } + + texturemanager.bindTexture(texturemanager.getResourceLocation(item.getItemSpriteNumber())); + Tessellator tessellator = Tessellator.instance; + float f = icon.getMinU(); + float f1 = icon.getMaxU(); + float f2 = icon.getMinV(); + float f3 = icon.getMaxV(); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + ItemRenderer.renderItemIn2D(tessellator, f1, f2, f, f3, icon.getIconWidth(), icon.getIconHeight(), 0.0625F); + + if (item.hasEffect(1)) + { + GL11.glDepthFunc(GL11.GL_EQUAL); + GL11.glDisable(GL11.GL_LIGHTING); + texturemanager.bindTexture(RES_ITEM_GLINT); + GL11.glBlendFunc(GL11.GL_SRC_COLOR, GL11.GL_ONE); + float f7 = 0.76F; + GL11.glColor4f(0.5F * f7, 0.25F * f7, 0.8F * f7, 1.0F); + GL11.glMatrixMode(GL11.GL_TEXTURE); + GL11.glPushMatrix(); + float f8 = 0.125F; + GL11.glScalef(f8, f8, f8); + float f9 = (float)(Minecraft.getSystemTime() % 3000L) / 3000.0F * 8.0F; + GL11.glTranslatef(f9, 0.0F, 0.0F); + GL11.glRotatef(-50.0F, 0.0F, 0.0F, 1.0F); + ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); + GL11.glPopMatrix(); + GL11.glPushMatrix(); + GL11.glScalef(f8, f8, f8); + f9 = (float)(Minecraft.getSystemTime() % 4873L) / 4873.0F * 8.0F; + GL11.glTranslatef(-f9, 0.0F, 0.0F); + GL11.glRotatef(10.0F, 0.0F, 0.0F, 1.0F); + ItemRenderer.renderItemIn2D(tessellator, 0.0F, 0.0F, 1.0F, 1.0F, 256, 256, 0.0625F); + GL11.glPopMatrix(); + GL11.glMatrixMode(GL11.GL_MODELVIEW); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glDepthFunc(GL11.GL_LEQUAL); + } + + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + + + Entity entity = (Entity)data[1]; + + // Spell charge-up effect + if(entity instanceof EntityPlayer && ((EntityPlayer)entity).isUsingItem()){ + + //System.out.println(type.toString()); + + GL11.glPushMatrix(); + + //GL11.glEnable(GL11.GL_BLEND); + //GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + GL11.glColor3f(1, 0, 0); + GL11.glRotatef(180, 1, 0, 0); + + //GL11.glRotatef(180.0F - RenderManager.instance.playerViewY, 0.0F, 1.0F, 0.0F); + //GL11.glRotatef(-RenderManager.instance.playerViewX, 1.0F, 0.0F, 0.0F); + + texturemanager.bindTexture(magicEffect); + + tessellator.startDrawingQuads(); + + tessellator.addVertex(0, 0, 0); + tessellator.addVertex(0, 1, 0); + tessellator.addVertex(1, 1, 0); + tessellator.addVertex(1, 0, 0); + + tessellator.draw(); + + //GL11.glDisable(GL11.GL_BLEND); + GL11.glPopMatrix(); + + } + + GL11.glPopMatrix(); + } + } + +} diff --git a/src/main/java/electroblob/wizardry/client/renderer/RenderWizard.java b/src/main/java/electroblob/wizardry/client/renderer/RenderWizard.java index e2043d5b..020aa6e7 100644 --- a/src/main/java/electroblob/wizardry/client/renderer/RenderWizard.java +++ b/src/main/java/electroblob/wizardry/client/renderer/RenderWizard.java @@ -1,34 +1,213 @@ package electroblob.wizardry.client.renderer; -import electroblob.wizardry.Wizardry; +import static net.minecraftforge.client.IItemRenderer.ItemRenderType.EQUIPPED; +import static net.minecraftforge.client.IItemRenderer.ItemRendererHelper.BLOCK_3D; + +import org.lwjgl.opengl.GL11; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import electroblob.wizardry.client.model.ModelWizard; import electroblob.wizardry.entity.living.EntityWizard; +import net.minecraft.block.Block; +import net.minecraft.client.model.ModelVillager; +import net.minecraft.client.renderer.RenderBlocks; import net.minecraft.client.renderer.entity.RenderBiped; -import net.minecraft.client.renderer.entity.RenderManager; -import net.minecraft.client.renderer.entity.layers.LayerBipedArmor; +import net.minecraft.client.renderer.entity.RenderLiving; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.EnumAction; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.client.IItemRenderer; +import net.minecraftforge.client.MinecraftForgeClient; @SideOnly(Side.CLIENT) -public class RenderWizard extends RenderBiped { - +public class RenderWizard extends RenderBiped +{ static final ResourceLocation[] textures = new ResourceLocation[6]; - public RenderWizard(RenderManager renderManager){ - - super(renderManager, new ModelWizard(), 0.5F); - + public RenderWizard() + { + super(new ModelWizard(), 0.5F); for(int i=0;i<6;i++){ - textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/wizard_" + i + ".png"); + textures[i] = new ResourceLocation("wizardry:textures/entity/wizard_" + i + ".png"); } - // Just using the default without overriding models, since the armour sets its own model anyway. - this.addLayer(new LayerBipedArmor(this)); - } - - @Override - protected ResourceLocation getEntityTexture(EntityWizard wizard) { - return textures[wizard.textureIndex]; } + /** + * Determines wether Villager Render pass or not. + */ + protected int shouldVillagerRenderPass(EntityWizard par1EntityWizard, int par2, float par3) + { + return -1; + } + + public void renderVillager(EntityWizard par1EntityWizard, double par2, double par4, double par6, float par8, float par9) + { + super.doRender(par1EntityWizard, par2, par4, par6, par8, par9); + } + + protected ResourceLocation func_110902_a(EntityWizard par1EntityWizard) + { + return textures[par1EntityWizard.textureIndex]; + } + + protected void renderVillagerEquipedItems(EntityWizard par1EntityWizard, float par2) + { + super.renderEquippedItems(par1EntityWizard, par2); + /* + ItemStack itemstack1 = par1EntityWizard.getHeldItem(); + + if (itemstack1 != null) + { + GL11.glPushMatrix(); + this.villagerModel.bipedRightArm.postRender(0.0625F); + GL11.glTranslatef(-0.0625F, 0.5375F, 0.0625F); + + EnumAction enumaction = null; + + float f11; + float f6; + + IItemRenderer customRenderer = MinecraftForgeClient.getItemRenderer(itemstack1, EQUIPPED); + boolean is3D = (customRenderer != null && customRenderer.shouldUseRenderHelper(EQUIPPED, itemstack1, BLOCK_3D)); + boolean isBlock = itemstack1.itemID < Block.blocksList.length && itemstack1.getItemSpriteNumber() == 0; + + if (is3D || (isBlock && RenderBlocks.renderItemIn3d(Block.blocksList[itemstack1.itemID].getRenderType()))) + { + f11 = 0.5F; + GL11.glTranslatef(0.0F, 0.1875F, -0.3125F); + f11 *= 0.75F; + GL11.glRotatef(20.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + GL11.glScalef(-f11, -f11, f11); + } + else if (itemstack1.itemID == Item.bow.itemID) + { + f11 = 0.625F; + GL11.glTranslatef(0.0F, 0.125F, 0.3125F); + GL11.glRotatef(-20.0F, 0.0F, 1.0F, 0.0F); + GL11.glScalef(f11, -f11, f11); + GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + } + else if (Item.itemsList[itemstack1.itemID].isFull3D()) + { + f11 = 0.625F; + + if (Item.itemsList[itemstack1.itemID].shouldRotateAroundWhenRendering()) + { + GL11.glRotatef(180.0F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(0.0F, -0.125F, 0.0F); + } + + GL11.glTranslatef(0.0F, 0.1875F, 0.0F); + GL11.glScalef(f11, -f11, f11); + GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + } + else + { + f11 = 0.375F; + GL11.glTranslatef(0.25F, 0.1875F, -0.1875F); + GL11.glScalef(f11, f11, f11); + GL11.glRotatef(60.0F, 0.0F, 0.0F, 1.0F); + GL11.glRotatef(-90.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(20.0F, 0.0F, 0.0F, 1.0F); + } + + float f12; + float f13; + int j; + + if (itemstack1.getItem().requiresMultipleRenderPasses()) + { + for (j = 0; j < itemstack1.getItem().getRenderPasses(itemstack1.getItemDamage()); ++j) + { + int k = itemstack1.getItem().getColorFromItemStack(itemstack1, j); + f13 = (float)(k >> 16 & 255) / 255.0F; + f12 = (float)(k >> 8 & 255) / 255.0F; + f6 = (float)(k & 255) / 255.0F; + GL11.glColor4f(f13, f12, f6, 1.0F); + this.renderManager.itemRenderer.renderItem(par1EntityWizard, itemstack1, j); + } + } + else + { + j = itemstack1.getItem().getColorFromItemStack(itemstack1, 0); + float f14 = (float)(j >> 16 & 255) / 255.0F; + f13 = (float)(j >> 8 & 255) / 255.0F; + f12 = (float)(j & 255) / 255.0F; + GL11.glColor4f(f14, f13, f12, 1.0F); + this.renderManager.itemRenderer.renderItem(par1EntityWizard, itemstack1, 0); + } + + GL11.glPopMatrix(); + } + */ + } + + protected void preRenderVillager(EntityWizard par1EntityWizard, float par2) + { + float f1 = 0.9375F; + this.shadowSize = 0.5F; + + GL11.glScalef(f1, f1, f1); + } + + public void doRenderLiving(EntityLiving par1EntityLiving, double par2, double par4, double par6, float par8, float par9) + { + this.renderVillager((EntityWizard)par1EntityLiving, par2, par4, par6, par8, par9); + } + + /** + * Allows the render to do any OpenGL state modifications necessary before the model is rendered. Args: + * entityLiving, partialTickTime + */ + protected void preRenderCallback(EntityLivingBase par1EntityLivingBase, float par2) + { + this.preRenderVillager((EntityWizard)par1EntityLivingBase, par2); + } + + /** + * Queries whether should render the specified pass or not. + */ + protected int shouldRenderPass(EntityLivingBase par1EntityLivingBase, int par2, float par3) + { + // TODO: Is this the right method name now? There are several with correct parameters. This one may end up being recursive! + return this.shouldRenderPass((EntityLiving)par1EntityLivingBase, par2, par3); + //return this.shouldVillagerRenderPass((EntityWizard)par1EntityLivingBase, par2, par3); + } + + protected void renderEquippedItems(EntityLivingBase par1EntityLivingBase, float par2) + { + this.renderVillagerEquipedItems((EntityWizard)par1EntityLivingBase, par2); + } + + public void renderPlayer(EntityLivingBase par1EntityLivingBase, double par2, double par4, double par6, float par8, float par9) + { + this.renderVillager((EntityWizard)par1EntityLivingBase, par2, par4, par6, par8, par9); + } + + /** + * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. + */ + protected ResourceLocation getEntityTexture(Entity par1Entity) + { + return this.func_110902_a((EntityWizard)par1Entity); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then + * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic + * (Render +public class RenderWraithMinion extends RenderLiving { - private ResourceLocation texture = new ResourceLocation("textures/entity/blaze.png"); + private ResourceLocation blazeTextures; + private int field_77068_a; - public RenderWraithMinion(RenderManager renderManagerIn) + public RenderWraithMinion(ResourceLocation texture) { - super(renderManagerIn, new ModelBlaze(), 0.5F); + super(new ModelBlaze(), 0.5F); + this.field_77068_a = ((ModelBlaze)this.mainModel).func_78104_a(); + this.blazeTextures = texture; } - @Override - protected ResourceLocation getEntityTexture(EntityBlazeMinion entity) + public void renderBlaze(EntityLiving par1EntityBlazeMinion, double par2, double par4, double par6, float par8, float par9) { - return texture; + int i = ((ModelBlaze)this.mainModel).func_78104_a(); + + if (i != this.field_77068_a) + { + this.field_77068_a = i; + this.mainModel = new ModelBlaze(); + } + + super.doRender(par1EntityBlazeMinion, par2, par4, par6, par8, par9); + } + + protected ResourceLocation getBlazeTextures(EntityLiving par1Entity) + { + return blazeTextures; + } + + public void doRenderLiving(EntityLiving par1EntityLiving, double par2, double par4, double par6, float par8, float par9) + { + this.renderBlaze(par1EntityLiving, par2, par4, par6, par8, par9); + } + + public void renderPlayer(EntityLivingBase par1EntityLivingBase, double par2, double par4, double par6, float par8, float par9) + { + this.renderBlaze((EntityLiving) par1EntityLivingBase, par2, par4, par6, par8, par9); + } + + /** + * Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture. + */ + protected ResourceLocation getEntityTexture(Entity par1Entity) + { + return this.getBlazeTextures((EntityLiving)par1Entity); + } + + /** + * Actually renders the given argument. This is a synthetic bridge method, always casting down its argument and then + * handing it off to a worker function which does the actual work. In all probabilty, the class Render is generic + * (Render getTabCompletionOptions(MinecraftServer server, ICommandSender sender, String[] arguments, BlockPos pos) { + public List addTabCompletionOptions(ICommandSender sender, String[] arguments) { switch(arguments.length){ - case 1: return getListOfStringsMatchingLastWord(arguments, Spell.getSpellNames()); - case 2: return getListOfStringsMatchingLastWord(arguments, server.getAllUsernames()); + case 1: return getListOfStringsMatchingLastWord(arguments, Spell.getUnlocalisedNames()); + case 2: return getListOfStringsMatchingLastWord(arguments, MinecraftServer.getServer().getAllUsernames()); } - return super.getTabCompletionOptions(server, sender, arguments, pos); + return super.addTabCompletionOptions(sender, arguments); } @Override - public void execute(MinecraftServer server, ICommandSender sender, String[] arguments) throws CommandException { + public void processCommand(ICommandSender sender, String[] arguments){ if(arguments.length < 1){ - throw new WrongUsageException("commands.wizardry:cast.usage", Wizardry.settings.castCommandName); + throw new WrongUsageException("commands.cast.usage", Wizardry.castCommandName); }else{ - // ===== Parameter retrieval ===== - int i=0; - EntityPlayerMP caster = null; + EntityPlayerMP entityplayermp = null; try{ - caster = getCommandSenderAsPlayer(sender); + entityplayermp = getCommandSenderAsPlayer(sender); }catch(PlayerNotFoundException exception){ // Nothing here since the player specifying is done later, I just don't want it to throw an exception here. } @@ -81,7 +74,7 @@ public class CommandCastSpell extends CommandBase { Spell spell = Spell.get(arguments[i++]); if(spell == null){ - throw new NumberInvalidException("commands.wizardry:cast.not_found", new Object[]{arguments[i-1]}); + throw new NumberInvalidException("commands.cast.not_found", new Object[]{arguments[i-1]}); } boolean castAsOtherPlayer = false; @@ -90,10 +83,10 @@ public class CommandCastSpell extends CommandBase { try{ // If the second argument is a player and is not the player that gave the command, the spell is cast // as the given player rather than the command sender, and there is a different chat readout. - EntityPlayerMP entityplayermp = getPlayer(server, sender, arguments[i++]); - if(caster != entityplayermp){ + EntityPlayerMP entityplayermp1 = getPlayer(sender, arguments[i++]); + if(entityplayermp != entityplayermp1){ castAsOtherPlayer = true; - caster = entityplayermp; + entityplayermp = entityplayermp1; } }catch(PlayerNotFoundException exception){ // If no player was found, rather than give an error it simply assumes the player was unspecified. @@ -103,56 +96,27 @@ public class CommandCastSpell extends CommandBase { // If, after this point, the player is still null, the sender must be a command block or the console and the // player must not have been specified, meaning an exception should be thrown. - if(caster == null) throw new PlayerNotFoundException("You must specify which player you wish to perform this action on."); - - SpellModifiers modifiers = new SpellModifiers(); - - if(i < arguments.length){ - - // Copied from CommandGive. Why it doesn't just use arguments[i] itself I don't know. - String nbt = getChatComponentFromNthArg(sender, arguments, i++).getUnformattedText(); - - try{ - modifiers = SpellModifiers.fromNBT(JsonToNBT.getTagFromJson(nbt)); - }catch(NBTException nbtexception){ - throw new CommandException("commands.wizardry:cast.tag_error", nbtexception.getMessage()); - } - - for(float multiplier : modifiers.getModifiers().values()){ - if(multiplier < 0){ - throw new NumberInvalidException("commands.generic.double.tooSmall", multiplier, 0); - }else if(multiplier > Wizardry.settings.maxSpellCommandMultiplier){ - throw new NumberInvalidException("commands.generic.double.tooBig", multiplier, Wizardry.settings.maxSpellCommandMultiplier); - } - } - - } + if(entityplayermp == null) throw new PlayerNotFoundException("You must specify which player you wish to perform this action on."); - // ===== Spell casting ===== - - // If anything stops the spell working at this point, nothing else happens. - if(MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Pre(caster, spell, modifiers, Source.COMMAND))){ - displayFailMessage(sender, spell); - return; - } + float damageMultiplier = i < arguments.length ? (float)this.parseDoubleBounded(sender, arguments[i++], 0d, Wizardry.maxSpellCommandMultiplier) : 1; + float rangeMultiplier = i < arguments.length ? (float)this.parseDoubleBounded(sender, arguments[i++], 0d, Wizardry.maxSpellCommandMultiplier) : 1; + float durationMultiplier = i < arguments.length ? (float)this.parseDoubleBounded(sender, arguments[i++], 0d, Wizardry.maxSpellCommandMultiplier) : 1; + float blastMultiplier = i < arguments.length ? (float)this.parseDoubleBounded(sender, arguments[i++], 0d, Wizardry.maxSpellCommandMultiplier) : 1; - WizardData data = WizardData.get((EntityPlayer)caster); - if(spell.isContinuous){ - // Events for continuous spell casting via commands are dealt with in WizardData. + ExtendedPlayer properties = ExtendedPlayer.get((EntityPlayer)entityplayermp); - if(data != null){ - if(data.isCasting()){ - data.stopCastingContinuousSpell(); + if(properties != null){ + if(properties.isCasting()){ + ExtendedPlayer.get((EntityPlayer)entityplayermp).stopCastingContinuousSpell(); }else{ - - data.startCastingContinuousSpell(spell, modifiers); + ExtendedPlayer.get((EntityPlayer)entityplayermp).startCastingContinuousSpell(spell, damageMultiplier, rangeMultiplier, durationMultiplier, blastMultiplier); if(castAsOtherPlayer){ - sender.addChatMessage(new TextComponentTranslation("commands.wizardry:cast.success_remote_continuous", spell.getNameForTranslationFormatted(), caster.getName())); + sender.addChatMessage(new ChatComponentTranslation("commands.cast.success_remote_continuous", spell.getDisplayNameWithFormatting(), entityplayermp.getCommandSenderName())); }else{ - sender.addChatMessage(new TextComponentTranslation("commands.wizardry:cast.success_continuous", spell.getNameForTranslationFormatted())); + sender.addChatMessage(new ChatComponentTranslation("commands.cast.success_continuous", spell.getDisplayNameWithFormatting())); } } @@ -161,36 +125,39 @@ public class CommandCastSpell extends CommandBase { }else{ - if(spell.cast(caster.worldObj, caster, EnumHand.MAIN_HAND, 0, modifiers)){ + if(spell.cast(entityplayermp.worldObj, entityplayermp, 0, damageMultiplier, rangeMultiplier, durationMultiplier, blastMultiplier)){ - MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(caster, spell, modifiers, Source.COMMAND)); + // TODO: In this case, is it more efficient/simpler/better design to just do away with the packet + // optimisation entirely rather than calling sync() for spells which don't send packets? if(spell.doesSpellRequirePacket()){ // Sends a packet to all players in dimension to tell them to spawn particles. // Only sent if the spell succeeded, because if the spell failed, you wouldn't // need to spawn any particles! - IMessage msg = new PacketCastSpell.Message(caster.getEntityId(), null, spell.id(), modifiers); - WizardryPacketHandler.net.sendToDimension(msg, caster.worldObj.provider.getDimension()); + IMessage msg = new PacketCastSpell.Message(entityplayermp.getEntityId(), 0, spell.id(), damageMultiplier, rangeMultiplier, blastMultiplier); + WizardryPacketHandler.net.sendToDimension(msg, entityplayermp.worldObj.provider.dimensionId); } + if(ExtendedPlayer.get((EntityPlayer)entityplayermp) != null){ + ExtendedPlayer.get((EntityPlayer)entityplayermp).discoverSpell(spell); + // If the spell didn't send a packet itself, the extended player needs to be synced so the + // spell discovery updates on the client. + if(!spell.doesSpellRequirePacket()) ExtendedPlayer.get((EntityPlayer)entityplayermp).sync(); + } + if(castAsOtherPlayer){ - sender.addChatMessage(new TextComponentTranslation("commands.wizardry:cast.success_remote", spell.getNameForTranslationFormatted(), caster.getName())); + sender.addChatMessage(new ChatComponentTranslation("commands.cast.success_remote", spell.getDisplayNameWithFormatting(), entityplayermp.getCommandSenderName())); }else{ - sender.addChatMessage(new TextComponentTranslation("commands.wizardry:cast.success", spell.getNameForTranslationFormatted())); + sender.addChatMessage(new ChatComponentTranslation("commands.cast.success", spell.getDisplayNameWithFormatting())); } return; } } - displayFailMessage(sender, spell); + IChatComponent message = new ChatComponentTranslation("commands.cast.fail", spell.getDisplayNameWithFormatting()); + message.getChatStyle().setColor(EnumChatFormatting.RED); + sender.addChatMessage(message); } } - - /** Displays the "Unable to cast [spell]" message in the chat. */ - private void displayFailMessage(ICommandSender sender, Spell spell){ - ITextComponent message = new TextComponentTranslation("commands.wizardry:cast.fail", spell.getNameForTranslationFormatted()); - message.getStyle().setColor(TextFormatting.RED); - sender.addChatMessage(message); - } } diff --git a/src/main/java/electroblob/wizardry/command/CommandDiscoverSpell.java b/src/main/java/electroblob/wizardry/command/CommandDiscoverSpell.java index 85a292fa..f41da141 100644 --- a/src/main/java/electroblob/wizardry/command/CommandDiscoverSpell.java +++ b/src/main/java/electroblob/wizardry/command/CommandDiscoverSpell.java @@ -2,133 +2,133 @@ package electroblob.wizardry.command; import java.util.List; -import electroblob.wizardry.WizardData; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.event.DiscoverSpellEvent; -import electroblob.wizardry.registry.Spells; +import electroblob.wizardry.WizardryRegistry; +import electroblob.wizardry.packet.PacketCastSpell; +import electroblob.wizardry.packet.WizardryPacketHandler; import electroblob.wizardry.spell.Spell; import net.minecraft.command.CommandBase; -import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.command.NumberInvalidException; import net.minecraft.command.PlayerNotFoundException; import net.minecraft.command.WrongUsageException; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.MinecraftServer; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraftforge.common.MinecraftForge; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; +import net.minecraft.util.StatCollector; public class CommandDiscoverSpell extends CommandBase { @Override public String getCommandName(){ - return Wizardry.settings.discoverspellCommandName; + return Wizardry.discoverspellCommandName; } - + @Override public int getRequiredPermissionLevel(){ // I *think* it's something like 0 = everyone, 1 = moderator, 2 = op/admin, 3 = op/console... return 2; } - - /* + @Override - public boolean checkPermission(MinecraftServer server, ICommandSender sender){ + public boolean canCommandSenderUseCommand(ICommandSender sender){ // Only ops (multiplayer) or players with cheats enabled (singleplayer/LAN) can use /discoverspell. - return !(sender instanceof EntityPlayer) || server.getServer().getConfigurationManager().func_152596_g(((EntityPlayer)sender).getGameProfile()); + return !(sender instanceof EntityPlayer) || MinecraftServer.getServer().getConfigurationManager().func_152596_g(((EntityPlayer)sender).getGameProfile()); } - */ + @Override public String getCommandUsage(ICommandSender p_71518_1_){ - // Not ideal, but the way this is implemented means I have no choice. Only used in the help command, so in there - // the custom command name will not display. - return "commands.wizardry:discoverspell.usage"; - //return I18n.format("commands.wizardry:discoverspell.usage", Wizardry.settings.discoverspellCommandName); + return StatCollector.translateToLocalFormatted("commands.discoverspell.usage", Wizardry.discoverspellCommandName); } - + @Override - public List getTabCompletionOptions(MinecraftServer server, ICommandSender sender, String[] arguments, BlockPos pos) { + public List addTabCompletionOptions(ICommandSender sender, String[] arguments) { switch(arguments.length){ - case 1: return getListOfStringsMatchingLastWord(arguments, Spell.getSpellNames()); - case 2: return getListOfStringsMatchingLastWord(arguments, server.getAllUsernames()); + case 1: return getListOfStringsMatchingLastWord(arguments, Spell.getUnlocalisedNames()); + case 2: return getListOfStringsMatchingLastWord(arguments, MinecraftServer.getServer().getAllUsernames()); } - return super.getTabCompletionOptions(server, sender, arguments, pos); + return super.addTabCompletionOptions(sender, arguments); } @Override - public void execute(MinecraftServer server, ICommandSender sender, String[] arguments) throws CommandException { - + public void processCommand(ICommandSender sender, String[] arguments){ + if(arguments.length < 1){ - throw new WrongUsageException("commands.wizardry:discoverspell.usage", Wizardry.settings.discoverspellCommandName); - }else{ - - int i=0; - boolean clear = false; - boolean all = false; - - EntityPlayerMP player = null; - - try{ - player = getCommandSenderAsPlayer(sender); - }catch(PlayerNotFoundException exception){ - // Nothing here since the player specifying is done later, I just don't want it to throw an exception here. - } - - Spell spell = Spells.none; - - if(arguments[i].equals("clear")){ - clear = true; - i++; - }else if(arguments[i].equals("all")){ - all = true; - i++; - }else{ - - spell = Spell.get(arguments[i++]); - - if(spell == null){ - throw new NumberInvalidException("commands.wizardry:discoverspell.not_found", new Object[]{arguments[i-1]}); - } - } - - if(i < arguments.length){ - // If the second argument is a player and is not the player that gave the command, the spell is - // discovered as the given player rather than the command sender. - EntityPlayerMP entityplayermp = getPlayer(server, sender, arguments[i++]); - if(player != entityplayermp){ - player = entityplayermp; - } - } - - // If, after this point, the player is still null, the sender must be a command block or the console and the - // player must not have been specified, meaning an exception should be thrown. - if(player == null) throw new PlayerNotFoundException("You must specify which player you wish to perform this action on."); - - WizardData properties = WizardData.get(player); - - if(properties != null){ - if(clear){ - properties.spellsDiscovered.clear(); - sender.addChatMessage(new TextComponentTranslation("commands.wizardry:discoverspell.clear", player.getName())); - }else if(all){ - properties.spellsDiscovered.addAll(Spell.getSpells(Spell.allSpells)); - sender.addChatMessage(new TextComponentTranslation("commands.wizardry:discoverspell.all", player.getName())); - }else{ - if(properties.hasSpellBeenDiscovered(spell)){ - properties.spellsDiscovered.remove(spell); - sender.addChatMessage(new TextComponentTranslation("commands.wizardry:discoverspell.removespell", spell.getNameForTranslationFormatted(), player.getName())); - }else{ - if(!MinecraftForge.EVENT_BUS.post(new DiscoverSpellEvent(player, spell, DiscoverSpellEvent.Source.COMMAND))){ - properties.discoverSpell(spell); - sender.addChatMessage(new TextComponentTranslation("commands.wizardry:discoverspell.addspell", spell.getNameForTranslationFormatted(), player.getName())); - } - } - } - properties.sync(); - } - } + throw new WrongUsageException("commands.discoverspell.usage", Wizardry.discoverspellCommandName); + }else{ + + int i=0; + boolean clear = false; + boolean all = false; + + EntityPlayerMP entityplayermp = null; + + try{ + entityplayermp = getCommandSenderAsPlayer(sender); + }catch(PlayerNotFoundException exception){ + // Nothing here since the player specifying is done later, I just don't want it to throw an exception here. + } + + Spell spell = WizardryRegistry.none; + + if(arguments[i].equals("clear")){ + clear = true; + i++; + }else if(arguments[i].equals("all")){ + all = true; + i++; + }else{ + + spell = Spell.get(arguments[i++]); + + if(spell == null){ + throw new NumberInvalidException("commands.discoverspell.not_found", new Object[]{arguments[i-1]}); + } + } + + boolean castAsOtherPlayer = false; + + if(i < arguments.length){ + // If the second argument is a player and is not the player that gave the command, the spell is cast + // as the given player rather than the command sender, and there is a different chat readout. + EntityPlayerMP entityplayermp1 = getPlayer(sender, arguments[i++]); + if(entityplayermp != entityplayermp1){ + castAsOtherPlayer = true; + entityplayermp = entityplayermp1; + } + } + + // If, after this point, the player is still null, the sender must be a command block or the console and the + // player must not have been specified, meaning an exception should be thrown. + if(entityplayermp == null) throw new PlayerNotFoundException("You must specify which player you wish to perform this action on."); + + ExtendedPlayer properties = ExtendedPlayer.get(entityplayermp); + + if(properties != null){ + if(clear){ + properties.spellsDiscovered.clear(); + sender.addChatMessage(new ChatComponentTranslation("commands.discoverspell.clear", entityplayermp.getCommandSenderName())); + }else if(all){ + properties.spellsDiscovered.addAll(Spell.getSpells(Spell.allSpells)); + sender.addChatMessage(new ChatComponentTranslation("commands.discoverspell.all", entityplayermp.getCommandSenderName())); + }else{ + if(properties.hasSpellBeenDiscovered(spell)){ + properties.spellsDiscovered.remove(spell); + sender.addChatMessage(new ChatComponentTranslation("commands.discoverspell.removespell", spell.getDisplayNameWithFormatting(), entityplayermp.getCommandSenderName())); + }else{ + properties.discoverSpell(spell); + sender.addChatMessage(new ChatComponentTranslation("commands.discoverspell.addspell", spell.getDisplayNameWithFormatting(), entityplayermp.getCommandSenderName())); + } + } + properties.sync(); + } + } } } diff --git a/src/main/java/electroblob/wizardry/command/CommandSetAlly.java b/src/main/java/electroblob/wizardry/command/CommandSetAlly.java index b566306c..4b20985b 100644 --- a/src/main/java/electroblob/wizardry/command/CommandSetAlly.java +++ b/src/main/java/electroblob/wizardry/command/CommandSetAlly.java @@ -2,11 +2,13 @@ package electroblob.wizardry.command; import java.util.List; -import electroblob.wizardry.WizardData; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.packet.PacketCastSpell; +import electroblob.wizardry.packet.WizardryPacketHandler; +import electroblob.wizardry.spell.Spell; import net.minecraft.command.CommandBase; -import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.command.NumberInvalidException; import net.minecraft.command.PlayerNotFoundException; @@ -14,100 +16,99 @@ import net.minecraft.command.WrongUsageException; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.MinecraftServer; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.util.text.TextFormatting; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; +import net.minecraft.util.StatCollector; public class CommandSetAlly extends CommandBase { @Override public String getCommandName(){ - return Wizardry.settings.allyCommandName; + return Wizardry.allyCommandName; } - + @Override public int getRequiredPermissionLevel(){ // I *think* it's something like 0 = everyone, 1 = moderator, 2 = op/admin, 3 = op/console... return 0; } - + @Override - public boolean checkPermission(MinecraftServer server, ICommandSender p_71519_1_) - { - return true; - } - + public boolean canCommandSenderUseCommand(ICommandSender p_71519_1_) + { + return true; + } + @Override public String getCommandUsage(ICommandSender p_71518_1_){ - // Not ideal, but the way this is implemented means I have no choice. Only used in the help command, so in there - // the custom command name will not display. - return "commands.wizardry:ally.usage"; - //return I18n.format("commands.wizardry:ally.usage", Wizardry.settings.allyCommandName); + return StatCollector.translateToLocalFormatted("commands.ally.usage", Wizardry.allyCommandName); } - + @Override - public List getTabCompletionOptions(MinecraftServer server, ICommandSender sender, String[] arguments, BlockPos pos) { + public List addTabCompletionOptions(ICommandSender sender, String[] arguments) { switch(arguments.length){ - case 1: return getListOfStringsMatchingLastWord(arguments, server.getAllUsernames()); - case 2: return getListOfStringsMatchingLastWord(arguments, server.getAllUsernames()); + case 1: return getListOfStringsMatchingLastWord(arguments, MinecraftServer.getServer().getAllUsernames()); + case 2: return getListOfStringsMatchingLastWord(arguments, MinecraftServer.getServer().getAllUsernames()); } - return super.getTabCompletionOptions(server, sender, arguments, pos); + return super.addTabCompletionOptions(sender, arguments); } @Override - public void execute(MinecraftServer server, ICommandSender sender, String[] arguments) throws CommandException { - + public void processCommand(ICommandSender sender, String[] arguments){ + if(arguments.length < 1){ - throw new WrongUsageException("commands.wizardry:ally.usage", Wizardry.settings.allyCommandName); - }else{ + throw new WrongUsageException("commands.ally.usage", Wizardry.allyCommandName); + }else{ + + EntityPlayerMP allyOf = null; + + try{ + allyOf = getCommandSenderAsPlayer(sender); + }catch(PlayerNotFoundException exception){ + // Nothing here since the player specifying is done later, I just don't want it to throw an exception here. + } + + boolean executeAsOtherPlayer = false; + + EntityPlayerMP ally = getPlayer(sender, arguments[0]); + // Don't want to catch the exception here, because the first player argument is always required. - EntityPlayerMP allyOf = null; - - try{ - allyOf = getCommandSenderAsPlayer(sender); - }catch(PlayerNotFoundException exception){ - // Nothing here since the player specifying is done later, I just don't want it to throw an exception here. - } - - boolean executeAsOtherPlayer = false; - - EntityPlayerMP ally = getPlayer(server, sender, arguments[0]); - // Don't want to catch the exception here, because the first player argument is always required. - - if(arguments.length > 1){ - - allyOf = getPlayer(server, sender, arguments[1]); - // Don't want to catch the exception here either, because there can be no other second argument. - - if(allyOf != sender && sender instanceof EntityPlayer && !WizardryUtilities.isPlayerOp((EntityPlayer)sender, server)){ - // Displays a chat message if a non-op tries to modify another player's allies. - TextComponentTranslation TextComponentTranslation2 = new TextComponentTranslation("commands.wizardry:ally.permission"); - TextComponentTranslation2.getStyle().setColor(TextFormatting.RED); - allyOf.addChatMessage(TextComponentTranslation2); - return; - } - - if(allyOf != sender) executeAsOtherPlayer = true; - } - - // If, after this point, allyOf is still null, the sender must be a command block or the console and two - // players must not have been specified, meaning an exception should be thrown. - if(allyOf == null) throw new PlayerNotFoundException("You must specify which player you wish to perform this action on."); - - if(allyOf == ally) throw new NumberInvalidException("commands.wizardry:ally.self"); - - if(WizardData.get(allyOf) != null){ - String string = WizardData.get(allyOf).toggleAlly(ally) ? "add" : "remove"; - if(executeAsOtherPlayer){ - sender.addChatMessage(new TextComponentTranslation("commands.wizardry:ally." + string + "ally", ally.getName(), allyOf.getName())); - // In this case, the player whose allies have been modified is also notified. - allyOf.addChatMessage(new TextComponentTranslation("item.wand." + string + "ally", ally.getName())); - }else{ - sender.addChatMessage(new TextComponentTranslation("item.wand." + string + "ally", ally.getName())); - } - } - - } + if(arguments.length > 1){ + + allyOf = getPlayer(sender, arguments[1]); + // Don't want to catch the exception here either, because there can be no other second argument. + + // The long-winded statement after the '!' checks if the player is op (multiplayer) or if cheats are enabled for them (singleplayer). + if(allyOf != sender && allyOf instanceof EntityPlayer && !MinecraftServer.getServer().getConfigurationManager().func_152596_g(((EntityPlayer)allyOf).getGameProfile())){ + + ChatComponentTranslation chatcomponenttranslation2 = new ChatComponentTranslation("commands.ally.permission"); + chatcomponenttranslation2.getChatStyle().setColor(EnumChatFormatting.RED); + allyOf.addChatMessage(chatcomponenttranslation2); + return; + } + + if(allyOf != sender) executeAsOtherPlayer = true; + } + + // If, after this point, allyOf is still null, the sender must be a command block or the console and two + // players must not have been specified, meaning an exception should be thrown. + if(allyOf == null) throw new PlayerNotFoundException("You must specify which player you wish to perform this action on."); + + if(allyOf == ally) throw new NumberInvalidException("commands.ally.self"); + + if(ExtendedPlayer.get(allyOf) != null){ + String string = ExtendedPlayer.get(allyOf).toggleAlly(ally) ? "add" : "remove"; + if(executeAsOtherPlayer){ + sender.addChatMessage(new ChatComponentTranslation("commands.ally." + string + "ally", ally.getCommandSenderName(), allyOf.getCommandSenderName())); + // In this case, the player whose allies have been modified is also notified. + allyOf.addChatMessage(new ChatComponentTranslation("item.wand." + string + "ally", ally.getCommandSenderName())); + }else{ + sender.addChatMessage(new ChatComponentTranslation("item.wand." + string + "ally", ally.getCommandSenderName())); + } + } + + } } } diff --git a/src/main/java/electroblob/wizardry/command/CommandViewAllies.java b/src/main/java/electroblob/wizardry/command/CommandViewAllies.java index 257b4b85..ad99b846 100644 --- a/src/main/java/electroblob/wizardry/command/CommandViewAllies.java +++ b/src/main/java/electroblob/wizardry/command/CommandViewAllies.java @@ -1,28 +1,32 @@ package electroblob.wizardry.command; +import java.util.HashSet; import java.util.List; -import java.util.Set; -import electroblob.wizardry.WizardData; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.client.resources.I18n; +import electroblob.wizardry.packet.PacketCastSpell; +import electroblob.wizardry.packet.WizardryPacketHandler; +import electroblob.wizardry.spell.Spell; import net.minecraft.command.CommandBase; -import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; +import net.minecraft.command.NumberInvalidException; import net.minecraft.command.PlayerNotFoundException; +import net.minecraft.command.WrongUsageException; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.MinecraftServer; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.util.text.TextFormatting; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; +import net.minecraft.util.StatCollector; public class CommandViewAllies extends CommandBase { @Override public String getCommandName(){ - return Wizardry.settings.alliesCommandName; + return Wizardry.alliesCommandName; } @Override @@ -32,29 +36,26 @@ public class CommandViewAllies extends CommandBase { } @Override - public boolean checkPermission(MinecraftServer server, ICommandSender p_71519_1_) + public boolean canCommandSenderUseCommand(ICommandSender p_71519_1_) { return true; } @Override public String getCommandUsage(ICommandSender p_71518_1_){ - // Not ideal, but the way this is implemented means I have no choice. Only used in the help command, so in there - // the custom command name will not display. - return "commands.wizardry:allies.usage"; - //return I18n.format("commands.wizardry:allies.usage", Wizardry.settings.alliesCommandName); + return StatCollector.translateToLocalFormatted("commands.allies.usage", Wizardry.alliesCommandName); } @Override - public List getTabCompletionOptions(MinecraftServer server, ICommandSender sender, String[] arguments, BlockPos pos) { + public List addTabCompletionOptions(ICommandSender sender, String[] arguments) { switch(arguments.length){ - case 1: return getListOfStringsMatchingLastWord(arguments, server.getAllUsernames()); + case 1: return getListOfStringsMatchingLastWord(arguments, MinecraftServer.getServer().getAllUsernames()); } - return super.getTabCompletionOptions(server, sender, arguments, pos); + return super.addTabCompletionOptions(sender, arguments); } @Override - public void execute(MinecraftServer server, ICommandSender sender, String[] arguments) throws CommandException { + public void processCommand(ICommandSender sender, String[] arguments){ EntityPlayerMP player = null; @@ -68,14 +69,15 @@ public class CommandViewAllies extends CommandBase { if(arguments.length > 0){ - player = getPlayer(server, sender, arguments[0]); + player = getPlayer(sender, arguments[0]); // Don't want to catch the exception here either, because there can be no other first argument. - if(player != sender && sender instanceof EntityPlayer && !WizardryUtilities.isPlayerOp((EntityPlayer)sender, server)){ - // Displays a chat message if a non-op tries to view another player's allies. - TextComponentTranslation TextComponentTranslation2 = new TextComponentTranslation("commands.wizardry:allies.permission"); - TextComponentTranslation2.getStyle().setColor(TextFormatting.RED); - player.addChatMessage(TextComponentTranslation2); + // The long-winded statement after the '!' checks if the player is op (multiplayer) or if cheats are enabled for them (singleplayer). + if(player != sender && player instanceof EntityPlayer && !MinecraftServer.getServer().getConfigurationManager().func_152596_g(((EntityPlayer)player).getGameProfile())){ + + ChatComponentTranslation chatcomponenttranslation2 = new ChatComponentTranslation("commands.allies.permission"); + chatcomponenttranslation2.getChatStyle().setColor(EnumChatFormatting.RED); + player.addChatMessage(chatcomponenttranslation2); return; } @@ -86,10 +88,10 @@ public class CommandViewAllies extends CommandBase { // player must not have been specified, meaning an exception should be thrown. if(player == null) throw new PlayerNotFoundException("You must specify which player you wish to perform this action on."); - if(WizardData.get(player) != null){ + if(ExtendedPlayer.get(player) != null){ String string = ""; - Set names = WizardData.get(player).allyNames; + HashSet names = ExtendedPlayer.get(player).allyNames; if(!names.isEmpty()){ for(String name : names){ @@ -98,13 +100,13 @@ public class CommandViewAllies extends CommandBase { // Cuts the last " ," off of the string. string = string.substring(0, string.length() - 2); }else{ - string = I18n.format("commands.wizardry:allies.none"); + string = StatCollector.translateToLocal("commands.allies.none"); } if(executeAsOtherPlayer){ - sender.addChatMessage(new TextComponentTranslation("commands.wizardry:allies.list_other", player.getName(), string)); + sender.addChatMessage(new ChatComponentTranslation("commands.allies.list_other", player.getCommandSenderName(), string)); }else{ - sender.addChatMessage(new TextComponentTranslation("commands.wizardry:allies.list", string)); + sender.addChatMessage(new ChatComponentTranslation("commands.allies.list", string)); } } } diff --git a/src/main/java/electroblob/wizardry/constants/Constants.java b/src/main/java/electroblob/wizardry/constants/Constants.java deleted file mode 100644 index 95b79b9c..00000000 --- a/src/main/java/electroblob/wizardry/constants/Constants.java +++ /dev/null @@ -1,44 +0,0 @@ -package electroblob.wizardry.constants; - -import electroblob.wizardry.WizardryEventHandler; - -/** Stores various global constants used in Wizardry. */ -public final class Constants { - - /** The amount of mana each magic crystal is worth */ - public static final int MANA_PER_CRYSTAL = 100; - /** The amount of mana each mana flask can hold */ - public static final int MANA_PER_FLASK = 700; - /** The maximum number of one type of wand upgrade which can be applied to a wand. */ - public static final int UPGRADE_STACK_LIMIT = 3; - /** The fraction by which cooldowns are reduced for each level of cooldown upgrade. */ - public static final float COOLDOWN_REDUCTION_PER_LEVEL = 0.15f; - /** The fraction by which maximum charge is increased for each level of storage upgrade. */ - public static final float STORAGE_INCREASE_PER_LEVEL = 0.15f; - /** The fraction by which damage is increased for each tier of matching wand. */ - public static final float DAMAGE_INCREASE_PER_TIER = 0.15f; - /** The fraction by which costs are reduced for each piece of matching armour. Note that changing this value will not - * affect continuous spells, since they are handled differently. */ - public static final float COST_REDUCTION_PER_ARMOUR = 0.2f; - /** The fraction by which spell duration is increased for each level of duration upgrade. */ - public static final float DURATION_INCREASE_PER_LEVEL = 0.25f; - /** The fraction by which spell range is increased for each level of range upgrade. */ - public static final float RANGE_INCREASE_PER_LEVEL = 0.25f; - /** The fraction by which spell blast radius is increased for each level of range upgrade. */ - public static final float BLAST_RADIUS_INCREASE_PER_LEVEL = 0.25f; - /** The fraction by which movement speed is reduced per level of frost effect. */ - public static final double FROST_SLOWNESS_PER_LEVEL = 0.5; - /** The fraction by which movement speed is reduced per level of decay effect. */ - public static final double DECAY_SLOWNESS_PER_LEVEL = 0.2; - /** The fraction by which dig speed is reduced per level of frost effect. */ - public static final float FROST_FATIGUE_PER_LEVEL = 0.45f; - /** The number of ticks between each mana increase for wands with the condenser upgrade. */ - public static final int CONDENSER_TICK_INTERVAL = 50; - /** The amount of mana given for a kill for each level of siphon upgrade. A random amount from 0 to this number - 1 - * is also added. See {@link WizardryEventHandler#onLivingDeathEvent} for more details. */ - public static final int SIPHON_MANA_PER_LEVEL = 3; - /** The number of ticks between the spawning of patches of decay when an entity has the decay effect. - * Note that decay won't spawn again if something is already standing in it. */ - public static final int DECAY_SPREAD_INTERVAL = 8; - -} diff --git a/src/main/java/electroblob/wizardry/constants/Element.java b/src/main/java/electroblob/wizardry/constants/Element.java deleted file mode 100644 index 48dd01f4..00000000 --- a/src/main/java/electroblob/wizardry/constants/Element.java +++ /dev/null @@ -1,67 +0,0 @@ -package electroblob.wizardry.constants; - -import electroblob.wizardry.Wizardry; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.Style; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -public enum Element { - - /** The 'default' element, with {@link electroblob.wizardry.spell.MagicMissile MagicMissile} being its only spell. */ - MAGIC(new Style().setColor(TextFormatting.GRAY), "simple", Wizardry.MODID), - FIRE(new Style().setColor(TextFormatting.DARK_RED), "fire", Wizardry.MODID), - ICE(new Style().setColor(TextFormatting.AQUA), "ice", Wizardry.MODID), - LIGHTNING(new Style().setColor(TextFormatting.DARK_AQUA), "lightning", Wizardry.MODID), - NECROMANCY(new Style().setColor(TextFormatting.DARK_PURPLE), "necromancy", Wizardry.MODID), - EARTH(new Style().setColor(TextFormatting.DARK_GREEN), "earth", Wizardry.MODID), - SORCERY(new Style().setColor(TextFormatting.GREEN), "sorcery", Wizardry.MODID), - HEALING(new Style().setColor(TextFormatting.YELLOW), "healing", Wizardry.MODID); - - /** Display colour for this element */ - private final Style colour; - /** Unlocalised name for this element */ - private final String unlocalisedName; - /** The {@link ResourceLocation} for this element's 8x8 icon (displayed in the arcane workbench GUI) */ - private final ResourceLocation icon; - - private Element(Style colour, String name, String modid){ - this.colour = colour; - this.unlocalisedName = name; - this.icon = new ResourceLocation(modid, "textures/gui/element_icon_" + unlocalisedName + ".png"); - } - - /** Returns the translated display name of this element, without formatting. */ - @SideOnly(Side.CLIENT) - public String getDisplayName(){ - return net.minecraft.client.resources.I18n.format("element." + getUnlocalisedName()); - } - - /** Returns the {@link Style} object representing the colour of this element. */ - public Style getColour(){ - return colour; - } - - /** Returns the string formatting code which corresponds to the colour of this element. */ - public String getFormattingCode(){ - return colour.getFormattingCode(); - } - - /** Returns the translated display name for wizards of this element, shown in the trading GUI. */ - public ITextComponent getWizardName(){ - return new TextComponentTranslation("element." + getUnlocalisedName() + ".wizard"); - } - - /** Returns this element's unlocalised name. */ - public String getUnlocalisedName(){ - return unlocalisedName; - } - - /** Returns the {@link ResourceLocation} for this element's 8x8 icon (displayed in the arcane workbench GUI). */ - public ResourceLocation getIcon(){ - return icon; - } -} diff --git a/src/main/java/electroblob/wizardry/constants/SpellType.java b/src/main/java/electroblob/wizardry/constants/SpellType.java deleted file mode 100644 index 807d878c..00000000 --- a/src/main/java/electroblob/wizardry/constants/SpellType.java +++ /dev/null @@ -1,23 +0,0 @@ -package electroblob.wizardry.constants; - -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -public enum SpellType { - - ATTACK("attack"), - DEFENCE("defence"), - UTILITY("utility"), - MINION("minion"); - - private final String unlocalisedName; - - SpellType(String name){ - this.unlocalisedName = name; - } - - @SideOnly(Side.CLIENT) - public String getDisplayName(){ - return net.minecraft.client.resources.I18n.format("spelltype." + unlocalisedName); - } -} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/constants/Tier.java b/src/main/java/electroblob/wizardry/constants/Tier.java deleted file mode 100644 index f989b82b..00000000 --- a/src/main/java/electroblob/wizardry/constants/Tier.java +++ /dev/null @@ -1,81 +0,0 @@ -package electroblob.wizardry.constants; - -import java.util.Random; - -import net.minecraft.util.text.Style; -import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -public enum Tier { - - BASIC(700, 3, 12, new Style().setColor(TextFormatting.WHITE), "basic"), - APPRENTICE(1000, 4, 5, new Style().setColor(TextFormatting.AQUA), "apprentice"), - ADVANCED(1500, 5, 2, new Style().setColor(TextFormatting.DARK_BLUE), "advanced"), - MASTER(2500, 6, 1, new Style().setColor(TextFormatting.DARK_PURPLE), "master"); - - /** Maximum mana a wand of this tier can store. */ - public final int maxCharge; - /** Just an ordinal. Shouldn't really be needed but no point changing it now. */ - public final int level; - /** The maximum number of upgrades that can be applied to a wand of this tier. */ - public final int upgradeLimit; - /** The weight given to this tier in the standard weighting. */ - public final int weight; - /** The colour of text associated with this tier. */ - // Changed to a Style object for consistency. - private final Style colour; - - private final String unlocalisedName; - - private Tier(int maxCharge, int upgradeLimit, int weight, Style colour, String name){ - this.maxCharge = maxCharge; - this.level = ordinal(); - this.upgradeLimit = upgradeLimit; - this.weight = weight; - this.colour = colour; - this.unlocalisedName = name; - } - - @SideOnly(Side.CLIENT) - public String getDisplayName() { - return net.minecraft.client.resources.I18n.format("tier." + unlocalisedName); - } - - @SideOnly(Side.CLIENT) - public String getDisplayNameWithFormatting() { - return this.getFormattingCode() + net.minecraft.client.resources.I18n.format("tier." + unlocalisedName); - } - - public String getUnlocalisedName(){ - return unlocalisedName; - } - - public String getFormattingCode(){ - return colour.getFormattingCode(); - } - - /** Returns a random tier based on the standard weighting. Currently, the standard weighting is: Basic (Novice) 60%, - * Apprentice 25%, Advanced 10%, Master 5%. If an array of tiers is given, it picks a tier from the array, with the - * same relative weights for each. For example, if the array contains APPRENTICE and MASTER, then the weighting will - * become: Apprentice 83.3%, Master 16.7%. */ - public static Tier getWeightedRandomTier(Random random, Tier... tiers){ - - if(tiers.length == 0) tiers = values(); - - int totalWeight = 0; - - for(Tier tier : tiers) totalWeight += tier.weight; - - int randomiser = random.nextInt(totalWeight); - int cumulativeWeight = 0; - - for(Tier tier : tiers){ - cumulativeWeight += tier.weight; - if(randomiser < cumulativeWeight) return tier; - } - - // This will never happen, but it might as well be a sensible result. - return tiers[tiers.length-1]; - } -} diff --git a/src/main/java/electroblob/wizardry/enchantment/EnchantmentMagicSword.java b/src/main/java/electroblob/wizardry/enchantment/EnchantmentMagicSword.java index 0aca94ba..a0ece85a 100644 --- a/src/main/java/electroblob/wizardry/enchantment/EnchantmentMagicSword.java +++ b/src/main/java/electroblob/wizardry/enchantment/EnchantmentMagicSword.java @@ -1,17 +1,18 @@ package electroblob.wizardry.enchantment; -import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentDamage; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EnumCreatureAttribute; -import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.ItemAxe; import net.minecraft.item.ItemStack; // This one is for imbued swords. The only reason this is separate is that the way vanilla is written allows me to hook // into the damage increase for melee weapons, meaning I don't have to use events - always handy! -public class EnchantmentMagicSword extends EnchantmentDamage implements Imbuement { +public class EnchantmentMagicSword extends EnchantmentDamage { - public EnchantmentMagicSword() { - super(Enchantment.Rarity.COMMON, 0, EntityEquipmentSlot.MAINHAND); + public EnchantmentMagicSword(int id) { + super(id, 0, 0); // Setting this to null stops the book appearing in the creative inventory this.type = null; } @@ -35,15 +36,17 @@ public class EnchantmentMagicSword extends EnchantmentDamage implements Imbuemen // Returns the number by which the damage should be increased (or something) @Override - public float calcDamageByCreature(int p_152376_1_, EnumCreatureAttribute p_152376_2_) + public float func_152376_a(int p_152376_1_, EnumCreatureAttribute p_152376_2_) { return (float)p_152376_1_ * 1.25F; } - @Override + /** + * Return the name of key in translation table of this enchantment. + */ public String getName() { - return "enchantment." + this.getRegistryName(); + return "enchantment.magic_sword"; } @Override diff --git a/src/main/java/electroblob/wizardry/enchantment/EnchantmentTimed.java b/src/main/java/electroblob/wizardry/enchantment/EnchantmentTimed.java index d30252d1..3041d816 100644 --- a/src/main/java/electroblob/wizardry/enchantment/EnchantmentTimed.java +++ b/src/main/java/electroblob/wizardry/enchantment/EnchantmentTimed.java @@ -1,27 +1,21 @@ package electroblob.wizardry.enchantment; import net.minecraft.enchantment.Enchantment; -import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.enchantment.EnumEnchantmentType; import net.minecraft.item.ItemStack; // This one is for everything other than imbued swords. -public class EnchantmentTimed extends Enchantment implements Imbuement { - - public EnchantmentTimed() { +public class EnchantmentTimed extends Enchantment { + + public EnchantmentTimed(int id) { // Setting enchantment type to null stops the book appearing in the creative inventory - super(Enchantment.Rarity.COMMON, null, new EntityEquipmentSlot[]{EntityEquipmentSlot.MAINHAND}); + super(id, 0, null); } @Override public boolean canApply(ItemStack p_92089_1_){ return false; } - - @Override - public String getName() - { - return "enchantment." + this.getRegistryName(); - } /** * Returns the maximum level that the enchantment can have. diff --git a/src/main/java/electroblob/wizardry/enchantment/Imbuement.java b/src/main/java/electroblob/wizardry/enchantment/Imbuement.java deleted file mode 100644 index ac443d9a..00000000 --- a/src/main/java/electroblob/wizardry/enchantment/Imbuement.java +++ /dev/null @@ -1,131 +0,0 @@ -package electroblob.wizardry.enchantment; - -import java.util.Map; - -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardryEnchantments; -import electroblob.wizardry.spell.FreezingWeapon; -import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.item.EntityItem; -import net.minecraft.entity.projectile.EntityArrow; -import net.minecraft.inventory.ContainerChest; -import net.minecraft.inventory.Slot; -import net.minecraft.item.ItemBow; -import net.minecraft.item.ItemEnchantedBook; -import net.minecraft.item.ItemStack; -import net.minecraftforge.event.entity.EntityJoinWorldEvent; -import net.minecraftforge.event.entity.item.ItemTossEvent; -import net.minecraftforge.event.entity.living.LivingDropsEvent; -import net.minecraftforge.event.entity.player.PlayerContainerEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; - -/** Interface for temporary enchantments that last for a certain duration ('imbuements'). This interface allows - * {@link EnchantmentMagicSword} and {@link EnchantmentTimed} to both be treated as instances of a - * single type, rather than having to deal with each of them separately, - * which would be inefficient and cumbersome (the former of those classes cannot extend the latter because they both - * need to extend different subclasses of {@link net.minecraft.enchantment.Enchantment}). - * @since Wizardry 1.2 */ -@Mod.EventBusSubscriber -public interface Imbuement { - - // This interface has no abstract methods, these handlers are just here for the sake of keeping things organised. - - @SubscribeEvent - public static void onLivingDropsEvent(LivingDropsEvent event){ - // Instantly disenchants an imbued weapon if it is dropped when the player dies. - for(EntityItem item : event.getDrops()){ - removeImbuements(item.getEntityItem()); - } - } - - @SubscribeEvent - public static void onItemTossEvent(ItemTossEvent event){ - // Instantly disenchants an imbued weapon if it is thrown on the ground. - removeImbuements(event.getEntityItem().getEntityItem()); - } - - /** Removes all imbuements from the given itemstack. */ - static void removeImbuements(ItemStack stack){ - if(stack.isItemEnchanted()){ - // No need to check what enchantments the item has, since remove() does nothing if the element does not exist. - Map enchantments = EnchantmentHelper.getEnchantments(stack); - // Removes the magic weapon enchantments from the enchantment map - enchantments.entrySet().removeIf(entry -> entry.getKey() instanceof Imbuement); - // Applies the new enchantment map to the item - EnchantmentHelper.setEnchantments(enchantments, stack); - } - } - - @SubscribeEvent - public static void onPlayerOpenContainerEvent(PlayerContainerEvent event){ - // Brute-force fix to stop enchanted books in dungeon chests from having imbuements on them. - if(event.getContainer() instanceof ContainerChest){ - // Still not sure if it's better to set stacks in slots or modify the itemstack list directly, but I would - // imagine it's the former. - for(Slot slot : event.getContainer().inventorySlots){ - if(slot.getStack() != null && slot.getStack().getItem() instanceof ItemEnchantedBook){ - // We don't care about the level of the enchantments - Map enchantments = EnchantmentHelper.getEnchantments(slot.getStack()); - // Removes all imbuements - if(enchantments.keySet().removeIf(e -> e instanceof Imbuement)){ - // If any imbuements were removed, replaces the enchantments on the book with the new ones, or - // deletes the book entirely if there are none left. - if(enchantments.isEmpty()){ - slot.putStack(null); // NOTE: Will need changing in 1.11 - Wizardry.logger.info("Deleted enchanted book with illegal enchantments"); - }else{ - EnchantmentHelper.setEnchantments(enchantments, slot.getStack()); - Wizardry.logger.info("Removed illegal enchantments from enchanted book"); - } - } - } - } - } - } - - @SubscribeEvent - public static void onEntityJoinWorld(EntityJoinWorldEvent event){ - // Rather long-winded (but necessary) way of getting an arrow just after it has been fired, checking if the bow - // that fired it has the imbuement enchantment, and applying extra damage accordingly. - if(!event.getEntity().worldObj.isRemote && event.getEntity() instanceof EntityArrow){ - - EntityArrow arrow = (EntityArrow)event.getEntity(); - - if(arrow.shootingEntity instanceof EntityLivingBase){ - - EntityLivingBase archer = (EntityLivingBase)arrow.shootingEntity; - - ItemStack bow = archer.getHeldItemMainhand(); - - if(bow == null || !(bow.getItem() instanceof ItemBow)){ - bow = archer.getHeldItemOffhand(); - if(bow == null || !(bow.getItem() instanceof ItemBow)) return; - } - - // Taken directly from ItemBow, so it works exactly the same as the power enchantment. - int level = EnchantmentHelper.getEnchantmentLevel(WizardryEnchantments.magic_bow, bow); - - if(level > 0){ - arrow.setDamage(arrow.getDamage() + (double)level * 0.5D + 0.5D); - } - - if(EnchantmentHelper.getEnchantmentLevel(WizardryEnchantments.flaming_weapon, bow) > 0){ - // Again, this is exactly what happens in ItemBow (flame is flame; level does nothing). - arrow.setFire(100); - } - - level = EnchantmentHelper.getEnchantmentLevel(WizardryEnchantments.freezing_weapon, bow); - - if(level > 0){ - if(arrow.getEntityData() != null){ - arrow.getEntityData().setInteger(FreezingWeapon.FREEZING_ARROW_NBT_KEY, level); - } - } - } - } - } - -} diff --git a/src/main/java/electroblob/wizardry/entity/EntityArc.java b/src/main/java/electroblob/wizardry/entity/EntityArc.java index dc68f0eb..a1f2d0fa 100644 --- a/src/main/java/electroblob/wizardry/entity/EntityArc.java +++ b/src/main/java/electroblob/wizardry/entity/EntityArc.java @@ -1,10 +1,11 @@ package electroblob.wizardry.entity; +import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; import io.netty.buffer.ByteBuf; import net.minecraft.entity.Entity; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.Vec3; import net.minecraft.world.World; -import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; public class EntityArc extends Entity implements IEntityAdditionalSpawnData { @@ -29,12 +30,41 @@ public class EntityArc extends Entity implements IEntityAdditionalSpawnData { this.z2 = z2; this.setPosition(x2, y2, z2); } + + @Deprecated + public void setOffset(double x, double z){ + this.offsetX = x; + this.offsetZ = z; + } @Override public void onUpdate(){ if(this.ticksExisted >= lifetime){ this.setDead(); } + /* Deprecated in favour of IEntityAdditionalSpawnData + if(!this.worldObj.isRemote){ + // Packet building + ByteArrayOutputStream bos = new ByteArrayOutputStream(32); + DataOutputStream outputStream = new DataOutputStream(bos); + try { + outputStream.writeInt(3); //This is the event id. 3 stands for arc render. + outputStream.writeInt(this.entityId); + outputStream.writeDouble(this.x1); + outputStream.writeDouble(this.y1); + outputStream.writeDouble(this.z1); + } catch (Exception ex) { + ex.printStackTrace(); + } + + Packet250CustomPayload packet = new Packet250CustomPayload(); + packet.channel = "WizardryMod"; + packet.data = bos.toByteArray(); + packet.length = bos.size(); + + PacketDispatcher.sendPacketToAllPlayers(packet); + } + */ } protected void entityInit() @@ -48,14 +78,17 @@ public class EntityArc extends Entity implements IEntityAdditionalSpawnData { @Override protected void writeEntityToNBT(NBTTagCompound nbttagcompound) { - // Nothing needed here; arc is merely a graphic effect that only exists for a few ticks; as such there is no need to save it. - } - - @Override - public boolean isInRangeToRenderDist(double distance) { - return true; + //Nothing needed here; arc is merely a graphic effect that only exists for a few ticks; as such there is no need to save it. } + /** + * Checks using a Vec3d to determine if this entity is within range of that vector to be rendered. Args: vec3D + */ + public boolean isInRangeToRenderVec3D(Vec3 par1Vec3) + { + return true; + } + @Override public void writeSpawnData(ByteBuf data) { data.writeDouble(this.x1); diff --git a/src/main/java/electroblob/wizardry/entity/EntityFallingGrass.java b/src/main/java/electroblob/wizardry/entity/EntityFallingGrass.java new file mode 100644 index 00000000..443b11e8 --- /dev/null +++ b/src/main/java/electroblob/wizardry/entity/EntityFallingGrass.java @@ -0,0 +1,93 @@ +package electroblob.wizardry.entity; + +import java.util.Iterator; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockFalling; +import net.minecraft.block.ITileEntityProvider; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.EntityFallingBlock; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; + +public class EntityFallingGrass extends EntityFallingBlock { + + public EntityFallingGrass(World world) { + super(world); + } + + public EntityFallingGrass(World world, double x, double y, double z, + Block block) { + super(world, x, y, z, block); + } + + public EntityFallingGrass(World world, double x, double y, double z, + Block block, int metadata) { + super(world, x, y, z, block, metadata); + } + + @Override + public void onUpdate(){ + + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; + ++this.field_145812_b; + this.motionY -= 0.03999999910593033D; + this.moveEntity(this.motionX, this.motionY, this.motionZ); + this.motionX *= 0.9800000190734863D; + this.motionY *= 0.9800000190734863D; + this.motionZ *= 0.9800000190734863D; + + if (!this.worldObj.isRemote) + { + int i = MathHelper.floor_double(this.posX); + int j = MathHelper.floor_double(this.posY); + int k = MathHelper.floor_double(this.posZ); + + if (this.field_145812_b == 1) + { + if (this.worldObj.getBlock(i, j, k) != Blocks.grass) + { + this.setDead(); + return; + } + + this.worldObj.setBlockToAir(i, j, k); + } + + if (this.onGround) + { + this.motionX *= 0.699999988079071D; + this.motionZ *= 0.699999988079071D; + this.motionY *= -0.5D; + + if (this.worldObj.getBlock(i, j, k) != Blocks.piston_extension) + { + this.setDead(); + + if (this.worldObj.canPlaceEntityOnSide(Blocks.grass, i, j, k, true, 1, (Entity)null, (ItemStack)null) && !BlockFalling.func_149831_e(this.worldObj, i, j - 1, k) && this.worldObj.setBlock(i, j, k, Blocks.grass, this.field_145814_a, 3)) + { + // The stuff in here only related to tile entities, so was removed, but since the enclosing if statement + // involves setting the block it has to stay (and I'm too lazy to rearrange it). + } + } + } + else if (this.field_145812_b > 100 && !this.worldObj.isRemote && (j < 1 || j > 256) || this.field_145812_b > 600) + { + if (this.field_145813_c) + { + this.entityDropItem(new ItemStack(Blocks.grass, 1, Blocks.grass.damageDropped(this.field_145814_a)), 0.0F); + } + + this.setDead(); + } + } + + } +} diff --git a/src/main/java/electroblob/wizardry/entity/EntityMagicSlime.java b/src/main/java/electroblob/wizardry/entity/EntityMagicSlime.java new file mode 100644 index 00000000..d278e525 --- /dev/null +++ b/src/main/java/electroblob/wizardry/entity/EntityMagicSlime.java @@ -0,0 +1,331 @@ +package electroblob.wizardry.entity; + +import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; + +public class EntityMagicSlime extends EntityLiving implements IEntityAdditionalSpawnData +{ + public float squishAmount; + public float squishFactor; + public float prevSquishFactor; + + /** the time between each jump of the slime */ + private int slimeJumpDelay; + + private int lifetime; + + public EntityMagicSlime(World par1World) + { + super(par1World); + this.yOffset = 0.0F; + this.slimeJumpDelay = this.rand.nextInt(20) + 10; + this.setSlimeSize(2); + } + + public EntityMagicSlime(World world, int lifetime){ + this(world); + this.lifetime = lifetime; + } + + protected void entityInit() + { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte)1)); + } + + protected void setSlimeSize(int par1) + { + this.dataWatcher.updateObject(16, new Byte((byte)par1)); + this.setSize(0.6F * (float)par1, 0.6F * (float)par1); + this.setPosition(this.posX, this.posY, this.posZ); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue((double)(par1 * par1)); + this.setHealth(this.getMaxHealth()); + this.experienceValue = par1; + } + + /** + * Returns the size of the slime. + */ + public int getSlimeSize() + { + return this.dataWatcher.getWatchableObjectByte(16); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) + { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setInteger("Size", this.getSlimeSize() - 1); + par1NBTTagCompound.setInteger("lifetime", lifetime); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) + { + super.readEntityFromNBT(par1NBTTagCompound); + this.setSlimeSize(par1NBTTagCompound.getInteger("Size") + 1); + lifetime = par1NBTTagCompound.getInteger("lifetime"); + } + + /** + * Returns the name of a particle effect that may be randomly created by EntitySlime.onUpdate() + */ + protected String getSlimeParticle() + { + return "slime"; + } + + /** + * Returns the name of the sound played when the slime jumps. + */ + protected String getJumpSound() + { + return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small"); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() + { + if(this.ticksExisted > lifetime){ + this.setDead(); + for(int i=0; i<30; i++){ + double x = this.posX - 0.5 + rand.nextDouble(); + double y = this.posY - 0.5 + rand.nextDouble(); + double z = this.posZ - 0.5 + rand.nextDouble(); + this.worldObj.spawnParticle("slime", x, y, z, (x - this.posX)*2, (y - this.posY)*2, (z - this.posZ)*2); + } + this.playSound("mob.slime.attack", 2.5f, 0.6f); + this.playSound("fireworks.blast_far", 1.0f, 0.5f); + } + + // Damages and slows the slime's victim or makes the slime explode if the victim is dead. + if(this.ridingEntity != null && this.ridingEntity instanceof EntityLivingBase && ((EntityLivingBase)this.ridingEntity).getHealth() > 0){ + if(this.ticksExisted % 16 == 1){ + this.ridingEntity.attackEntityFrom(DamageSource.magic, 1); + ((EntityLivingBase)this.ridingEntity).addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 20, 2)); + this.playSound("mob.slime.attack", 1.0f, 1.0f); + this.squishAmount = 0.5F; + } + }else{ + this.setDead(); + for(int i=0; i<30; i++){ + double x = this.posX - 0.5 + rand.nextDouble(); + double y = this.posY - 0.5 + rand.nextDouble(); + double z = this.posZ - 0.5 + rand.nextDouble(); + this.worldObj.spawnParticle("slime", x, y, z, (x - this.posX)*2, (y - this.posY)*2, (z - this.posZ)*2); + } + this.playSound("mob.slime.attack", 2.5f, 0.6f); + this.playSound("fireworks.blast_far", 1.0f, 0.5f); + } + /* No despawn on peaceful. + if (!this.worldObj.isRemote && this.worldObj.difficultySetting == EnumDifficulty.PEACEFUL && this.getSlimeSize() > 0) + { + this.isDead = true; + } + */ + this.squishFactor += (this.squishAmount - this.squishFactor) * 0.5F; + this.prevSquishFactor = this.squishFactor; + boolean flag = this.onGround; + super.onUpdate(); + int i; + + if (this.onGround && !flag) + { + i = this.getSlimeSize(); + + for (int j = 0; j < i * 8; ++j) + { + float f = this.rand.nextFloat() * (float)Math.PI * 2.0F; + float f1 = this.rand.nextFloat() * 0.5F + 0.5F; + float f2 = MathHelper.sin(f) * (float)i * 0.5F * f1; + float f3 = MathHelper.cos(f) * (float)i * 0.5F * f1; + this.worldObj.spawnParticle(this.getSlimeParticle(), this.posX + (double)f2, this.boundingBox.minY, this.posZ + (double)f3, 0.0D, 0.0D, 0.0D); + } + + if (this.makesSoundOnLand()) + { + this.playSound(this.getJumpSound(), this.getSoundVolume(), ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F) / 0.8F); + } + + this.squishAmount = -0.5F; + } + else if (!this.onGround && flag) + { + this.squishAmount = 1.0F; + } + + this.alterSquishAmount(); + + if (this.worldObj.isRemote) + { + i = this.getSlimeSize(); + this.setSize(0.6F * (float)i, 0.6F * (float)i); + } + } + + protected void updateEntityActionState() + { + this.despawnEntity(); + EntityPlayer entityplayer = this.worldObj.getClosestVulnerablePlayerToEntity(this, 16.0D); + + if (entityplayer != null) + { + this.faceEntity(entityplayer, 10.0F, 20.0F); + } + + if (this.onGround && this.slimeJumpDelay-- <= 0) + { + this.slimeJumpDelay = this.getJumpDelay(); + + if (entityplayer != null) + { + this.slimeJumpDelay /= 3; + } + + this.isJumping = true; + + if (this.makesSoundOnJump()) + { + this.playSound(this.getJumpSound(), this.getSoundVolume(), ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 1.0F) * 0.8F); + } + + this.moveStrafing = 1.0F - this.rand.nextFloat() * 2.0F; + this.moveForward = (float)(1 * this.getSlimeSize()); + } + else + { + this.isJumping = false; + + if (this.onGround) + { + this.moveStrafing = this.moveForward = 0.0F; + } + } + } + + protected void alterSquishAmount() + { + this.squishAmount *= 0.6F; + } + + /** + * Gets the amount of time the slime needs to wait between jumps. + */ + protected int getJumpDelay() + { + return this.rand.nextInt(20) + 10; + } + + protected EntityMagicSlime createInstance() + { + return new EntityMagicSlime(this.worldObj); + } + + /** + * Will get destroyed next tick. + */ + public void setDead() + { + int i = this.getSlimeSize(); + + if (!this.worldObj.isRemote && i > 1 && this.getHealth() <= 0.0F) + { + int j = 2 + this.rand.nextInt(3); + + for (int k = 0; k < j; ++k) + { + float f = ((float)(k % 2) - 0.5F) * (float)i / 4.0F; + float f1 = ((float)(k / 2) - 0.5F) * (float)i / 4.0F; + EntityMagicSlime entityslime = this.createInstance(); + entityslime.setSlimeSize(i / 2); + entityslime.setLocationAndAngles(this.posX + (double)f, this.posY + 0.5D, this.posZ + (double)f1, this.rand.nextFloat() * 360.0F, 0.0F); + this.worldObj.spawnEntityInWorld(entityslime); + } + } + + super.setDead(); + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() + { + return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small"); + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() + { + return "mob.slime." + (this.getSlimeSize() > 1 ? "big" : "small"); + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() + { + return -1; + } + + /** + * Returns the volume for the sounds this mob makes. + */ + protected float getSoundVolume() + { + return 0.4F * (float)this.getSlimeSize(); + } + + /** + * The speed it takes to move the entityliving's rotationPitch through the faceEntity method. This is only currently + * use in wolves. + */ + public int getVerticalFaceSpeed() + { + return 0; + } + + /** + * Returns true if the slime makes a sound when it jumps (based upon the slime's size) + */ + protected boolean makesSoundOnJump() + { + return this.getSlimeSize() > 0; + } + + /** + * Returns true if the slime makes a sound when it lands after a jump (based upon the slime's size) + */ + protected boolean makesSoundOnLand() + { + return this.getSlimeSize() > 2; + } + + @Override + public void writeSpawnData(ByteBuf data) { + data.writeInt(lifetime); + } + + @Override + public void readSpawnData(ByteBuf data) { + lifetime = data.readInt(); + } +} diff --git a/src/main/java/electroblob/wizardry/entity/EntityMeteor.java b/src/main/java/electroblob/wizardry/entity/EntityMeteor.java index fce647ce..d48e1512 100644 --- a/src/main/java/electroblob/wizardry/entity/EntityMeteor.java +++ b/src/main/java/electroblob/wizardry/entity/EntityMeteor.java @@ -1,51 +1,80 @@ package electroblob.wizardry.entity; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardryBlocks; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.block.state.IBlockState; +import electroblob.wizardry.WizardryUtilities; +import net.minecraft.block.Block; import net.minecraft.entity.item.EntityFallingBlock; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.MathHelper; +import net.minecraft.util.Vec3; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -public class EntityMeteor extends EntityFallingBlock { +public class EntityMeteor extends EntityFallingBlock +{ + /** How long the block has been falling for. */ + public int fallTime; /** The entity blast multiplier. Only some projectiles cause a blast, which is why this isn't in EntityMagicProjectile. */ public float blastMultiplier; - public EntityMeteor(World world){ - super(world); - // Superconstructor doesn't call this. - this.setSize(0.98F, 0.98F); + public EntityMeteor(World par1World) + { + super(par1World); } - public EntityMeteor(World world, double x, double y, double z, float blastMultiplier){ - super(world, x, y, z, WizardryBlocks.meteor.getDefaultState()); + public EntityMeteor(World par1World, double par2, double par4, double par6, Block block, float blastMultiplier) + { + super(par1World, par2, par4, par6, block); + this.setSize(0.98F, 0.98F); + this.yOffset = this.height / 2.0F; + this.setPosition(par2, par4, par6); + this.motionX = 0.0D; this.motionY = -1.0D; + this.motionZ = 0.0D; + this.prevPosX = par2; + this.prevPosY = par4; + this.prevPosZ = par6; this.setFire(200); this.blastMultiplier = blastMultiplier; } - - @Override - public double getYOffset() { - return this.height / 2.0F; + + /** + * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to + * prevent them from trampling crops + */ + protected boolean canTriggerWalking() + { + return false; } - @Override + protected void entityInit() {} + + /** + * Returns true if other Entities should be prevented from moving through this Entity. + */ + public boolean canBeCollidedWith() + { + return !this.isDead; + } + + /** + * Called to update the entity's position/logic. + */ public void onUpdate(){ if(this.ticksExisted % 16 == 1 && worldObj.isRemote){ - Wizardry.proxy.playMovingSound(this, WizardrySounds.SPELL_LOOP_FIRE, 3.0f, 1.0f, false); + Wizardry.proxy.playMovingSound(this, "wizardry:flameray", 3.0f, 1.0f, false); } - - // You'd think the best way to do this would be to call super and do all the exploding stuff in fall() instead. - // However, for some reason, fallTile is null on the client side, causing an NPE in super.onUpdate() - + /* + if(worldObj.isRemote){ + System.out.println("Client: " + this.posX + ", " + this.posY + ", " + this.posZ); + }else{ + System.out.println("Server: " + this.posX + ", " + this.posY + ", " + this.posZ); + } + */ this.prevPosX = this.posX; this.prevPosY = this.posY; this.prevPosZ = this.posZ; @@ -56,22 +85,26 @@ public class EntityMeteor extends EntityFallingBlock { this.motionY *= 0.9800000190734863D; this.motionZ *= 0.9800000190734863D; - if(!this.worldObj.isRemote){ - - if(this.onGround){ + if (!this.worldObj.isRemote) + { + int i = MathHelper.floor_double(this.posX); + int j = MathHelper.floor_double(this.posY); + int k = MathHelper.floor_double(this.posZ); + if (this.onGround) + { this.motionX *= 0.699999988079071D; this.motionZ *= 0.699999988079071D; this.motionY *= -0.5D; this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, 2.0f*blastMultiplier, true); for(int i1=-3; i1<4; i1++){ for(int j1=-3; j1<4; j1++){ - int y = WizardryUtilities.getNearestFloorLevelB(this.worldObj, new BlockPos(this.posX + i1, this.posY, this.posZ + j1), 7); + int y = WizardryUtilities.getNearestFloorLevelB(this.worldObj, (int)this.posX + i1, (int)this.posY, (int)this.posZ + j1, 7); //System.out.println(y); double dist = this.getDistance((int)this.posX + i1, y, (int)this.posZ + j1); // Randomised with weighting so that the nearer the block the more likely it is to be set on fire. if(y != -1 && rand.nextInt((int)dist*2 + 1) < 3 && dist < 4){ - this.worldObj.setBlockState(new BlockPos(this.posX + i1, y, this.posZ + j1), Blocks.FIRE.getDefaultState()); + this.worldObj.setBlock((int)this.posX + i1, y, (int)this.posZ + j1, Blocks.fire); } } } @@ -80,37 +113,77 @@ public class EntityMeteor extends EntityFallingBlock { } } - @Override - public void fall(float distance, float damageMultiplier){ - // Don't need to do anything here, the meteor should have already exploded. + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) + { + } + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + /* + protected void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) + { + par1NBTTagCompound.setByte("Tile", (byte)this.blockID); + par1NBTTagCompound.setInteger("TileID", this.blockID); + par1NBTTagCompound.setByte("Time", (byte)this.fallTime); + } + */ + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + /* + protected void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) + { + if (par1NBTTagCompound.hasKey("TileID")) + { + this.blockID = par1NBTTagCompound.getInteger("TileID"); + } + else + { + this.blockID = par1NBTTagCompound.getByte("Tile") & 255; + } + + this.fallTime = par1NBTTagCompound.getByte("Time") & 255; + + if (this.blockID == 0) + { + this.blockID = Block.stone.blockID; + } + } +*/ @SideOnly(Side.CLIENT) - @Override - public boolean canRenderOnFire(){ + public float getShadowSize() + { + return 0.0F; + } + + @SideOnly(Side.CLIENT) + public World getWorld() + { + return this.worldObj; + } + + @SideOnly(Side.CLIENT) + + /** + * Return whether this entity should be rendered as on fire. + */ + public boolean canRenderOnFire() + { return true; } - @Override - public IBlockState getBlock(){ - return WizardryBlocks.meteor.getDefaultState(); // For some reason the superclass version returns null on the client + /** + * Checks using a Vec3d to determine if this entity is within range of that vector to be rendered. Args: vec3D + */ + public boolean isInRangeToRenderVec3D(Vec3 par1Vec3) + { + return true; } - - @SideOnly(Side.CLIENT) - @Override - public int getBrightnessForRender(float partialTicks){ - return 15728880; - } - - @Override - public float getBrightness(float partialTicks){ - return 1.0F; - } - - @Override - public boolean isInRangeToRenderDist(double distance){ - return true; - } @Override public void readEntityFromNBT(NBTTagCompound nbttagcompound){ diff --git a/src/main/java/electroblob/wizardry/entity/EntityShield.java b/src/main/java/electroblob/wizardry/entity/EntityShield.java index c884ea07..46f564a6 100644 --- a/src/main/java/electroblob/wizardry/entity/EntityShield.java +++ b/src/main/java/electroblob/wizardry/entity/EntityShield.java @@ -2,16 +2,17 @@ package electroblob.wizardry.entity; import java.lang.ref.WeakReference; -import electroblob.wizardry.WizardData; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.item.ItemWand; -import electroblob.wizardry.registry.WizardrySounds; +import net.minecraft.entity.DataWatcher; import net.minecraft.entity.Entity; import net.minecraft.entity.IProjectile; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; -import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.world.World; +import net.minecraft.world.WorldServer; public class EntityShield extends Entity { @@ -28,10 +29,10 @@ public class EntityShield extends Entity { super(par1World); this.width = 1.2f; this.height = 1.4f; - this.player = new WeakReference(player); + this.player = new WeakReference(player); this.noClip = true; this.setPositionAndRotation(player.posX + player.getLookVec().xCoord, player.posY + 1 + player.getLookVec().yCoord, player.posZ + player.getLookVec().zCoord, player.rotationYawHead, player.rotationPitch); - this.setEntityBoundingBox(new AxisAlignedBB(this.posX - 0.6f, this.posY - 0.7f, this.posZ - 0.6f, this.posX + 0.6f, this.posY + 0.7f, this.posZ + 0.6f)); + this.boundingBox.setBounds(this.posX - 0.6f, this.posY - 0.7f, this.posZ - 0.6f, this.posX + 0.6f, this.posY + 0.7f, this.posZ + 0.6f); } @Override @@ -40,8 +41,8 @@ public class EntityShield extends Entity { EntityPlayer entityplayer = player != null ? player.get() : null; if(entityplayer != null){ this.setPositionAndRotation(entityplayer.posX + entityplayer.getLookVec().xCoord*0.3, entityplayer.posY + 1 + entityplayer.getLookVec().yCoord*0.3, entityplayer.posZ + entityplayer.getLookVec().zCoord*0.3, entityplayer.rotationYawHead, entityplayer.rotationPitch); - if(!entityplayer.isHandActive() || entityplayer.getHeldItem(entityplayer.getActiveHand()) == null || !(entityplayer.getHeldItem(entityplayer.getActiveHand()).getItem() instanceof ItemWand)){ - WizardData.get(entityplayer).shield = null; + if(!entityplayer.isUsingItem() || entityplayer.getHeldItem() == null || !(entityplayer.getHeldItem().getItem() instanceof ItemWand)){ + ExtendedPlayer.get(entityplayer).shield = null; this.setDead(); } }else if(!worldObj.isRemote){ @@ -60,7 +61,7 @@ public class EntityShield extends Entity { public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) { if(par1DamageSource != null && par1DamageSource.getSourceOfDamage() instanceof IProjectile){ - par1DamageSource.getSourceOfDamage().playSound(WizardrySounds.SPELL_DEFLECTION, 0.3f, 1.3f); + worldObj.playSoundAtEntity(par1DamageSource.getSourceOfDamage(), "wizardry:effect", 0.3f, 1.3f); } super.attackEntityFrom(par1DamageSource, par2); return false; @@ -73,7 +74,7 @@ public class EntityShield extends Entity { public AxisAlignedBB getCollisionBox(Entity par1Entity) { - return par1Entity.getEntityBoundingBox(); + return par1Entity.boundingBox; } @Override diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityArrowRain.java b/src/main/java/electroblob/wizardry/entity/construct/EntityArrowRain.java index ddee05da..8191f94b 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityArrowRain.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityArrowRain.java @@ -1,9 +1,7 @@ package electroblob.wizardry.entity.construct; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.projectile.EntityTippedArrow; -import net.minecraft.init.Items; -import net.minecraft.item.ItemStack; +import net.minecraft.entity.projectile.EntityArrow; import net.minecraft.world.World; public class EntityArrowRain extends EntityMagicConstruct { @@ -25,13 +23,13 @@ public class EntityArrowRain extends EntityMagicConstruct { super.onUpdate(); if(!this.worldObj.isRemote){ - EntityTippedArrow arrow = new EntityTippedArrow(worldObj, this.posX + rand.nextDouble()*6 - 3, this.posY + rand.nextDouble()*4 - 2, this.posZ + rand.nextDouble()*6 - 3); + //System.out.println(this.rotationYaw); + EntityArrow arrow = new EntityArrow(worldObj, this.posX + rand.nextDouble()*6 - 3, this.posY + rand.nextDouble()*4 - 2, this.posZ + rand.nextDouble()*6 - 3); arrow.motionX = Math.cos(Math.toRadians(this.rotationYaw + 90)); arrow.motionY = -0.6; arrow.motionZ = Math.sin(Math.toRadians(this.rotationYaw + 90)); arrow.shootingEntity = this.getCaster(); arrow.setDamage(7.0d*damageMultiplier); - arrow.setPotionEffect(new ItemStack(Items.ARROW)); this.worldObj.spawnEntityInWorld(arrow); } } diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityBlackHole.java b/src/main/java/electroblob/wizardry/entity/construct/EntityBlackHole.java index 56f85762..9709d411 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityBlackHole.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityBlackHole.java @@ -2,17 +2,16 @@ package electroblob.wizardry.entity.construct; import java.util.List; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.init.SoundEvents; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.play.server.SPacketEntityVelocity; +import net.minecraft.network.play.server.S12PacketEntityVelocity; import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class EntityBlackHole extends EntityMagicConstruct { @@ -71,15 +70,15 @@ public class EntityBlackHole extends EntityMagicConstruct { // Particle effect. Finishes 40 ticks before the end so the particles disappear at the same time. if(this.ticksExisted + 40 < this.lifetime){ for (int i=0; i<5; i++){ - //this.worldObj.spawnParticle(EnumParticleTypes.PORTAL, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height - 0.75D, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, (this.rand.nextDouble() - 0.5D) * 2.0D, -this.rand.nextDouble(), (this.rand.nextDouble() - 0.5D) * 2.0D); - this.worldObj.spawnParticle(EnumParticleTypes.PORTAL, this.posX, this.posY, this.posZ, (this.rand.nextDouble() - 0.5D) * 4.0D, (this.rand.nextDouble() - 0.5D) * 4.0D - 1, (this.rand.nextDouble() - 0.5D) * 4.0D); + //this.worldObj.spawnParticle("portal", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height - 0.75D, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, (this.rand.nextDouble() - 0.5D) * 2.0D, -this.rand.nextDouble(), (this.rand.nextDouble() - 0.5D) * 2.0D); + this.worldObj.spawnParticle("portal", this.posX, this.posY, this.posZ, (this.rand.nextDouble() - 0.5D) * 4.0D, (this.rand.nextDouble() - 0.5D) * 4.0D - 1, (this.rand.nextDouble() - 0.5D) * 4.0D); } } if(this.lifetime - this.ticksExisted == 75){ - this.playSound(SoundEvents.BLOCK_PORTAL_TRIGGER, 1.5f, 1.0f); + this.worldObj.playSoundAtEntity(this, "portal.trigger", 1.5f, 1.0f); }else if(this.ticksExisted % 80 == 1 && this.ticksExisted + 80 < this.lifetime){ - this.playSound(SoundEvents.BLOCK_PORTAL_AMBIENT, 1.5f, 1.0f); + this.worldObj.playSoundAtEntity(this, "portal.portal", 1.5f, 1.0f); } List targets = WizardryUtilities.getEntitiesWithinRadius(6.0d, this.posX, this.posY, this.posZ, this.worldObj); @@ -111,26 +110,47 @@ public class EntityBlackHole extends EntityMagicConstruct { // Player motion is handled on that player's client so needs packets if(target instanceof EntityPlayerMP){ - ((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target)); + ((EntityPlayerMP)target).playerNetServerHandler.sendPacket(new S12PacketEntityVelocity(target)); } if(this.getDistanceToEntity(target) <= 2){ // Damages the target if it is close enough if(this.getCaster() != null){ - target.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.MAGIC), 2*damageMultiplier); + target.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, getCaster(), DamageType.MAGIC), 2*damageMultiplier); }else{ target.attackEntityFrom(DamageSource.magic, 2*damageMultiplier); } } } + /* + else if(targets.get(i) instanceof EntityItem && !this.worldObj.isRemote){ + EntityItem target = (EntityItem)targets.get(i); + // Sucks the item in + if(this.posX > target.posX && target.motionX < 1){ + target.motionX+=0.1; + }else if(this.posX < target.posX && target.motionX > -1){ + target.motionX-=0.1; + } + if(this.posY > target.posY && target.motionY < 1){ + target.motionY+=0.1; + }else if(this.posY < target.posY && target.motionY > -1){ + target.motionY-=0.1; + } + if(this.posZ > target.posZ && target.motionZ < 1){ + target.motionZ+=0.1; + }else if(this.posZ < target.posZ && target.motionZ > -1){ + target.motionZ-=0.1; + } + } + */ } } } /** - * Checks using a Vec3dd to determine if this entity is within range of that vector to be rendered. Args: Vec3dD + * Checks using a Vec3d to determine if this entity is within range of that vector to be rendered. Args: vec3D */ - public boolean isInRangeToRenderVec3dD(Vec3d par1Vec3d) + public boolean isInRangeToRenderVec3D(Vec3 par1Vec3) { return true; } diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityBlizzard.java b/src/main/java/electroblob/wizardry/entity/construct/EntityBlizzard.java index 342ad185..8012a239 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityBlizzard.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityBlizzard.java @@ -2,14 +2,15 @@ package electroblob.wizardry.entity.construct; import java.util.List; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.potion.PotionEffect; import net.minecraft.util.DamageSource; import net.minecraft.world.World; @@ -31,7 +32,7 @@ public class EntityBlizzard extends EntityMagicConstruct { public void onUpdate(){ if(this.ticksExisted % 120 == 1){ - this.playSound(WizardrySounds.SPELL_LOOP_WIND, 1.0f, 1.0f); + this.playSound("wizardry:wind", 1.0f, 1.0f); } super.onUpdate(); @@ -43,25 +44,32 @@ public class EntityBlizzard extends EntityMagicConstruct { for(EntityLivingBase target : targets){ if(this.isValidTarget(target)){ + + double velX = target.motionX; + double velY = target.motionY; + double velZ = target.motionZ; if(this.getCaster() != null){ - WizardryUtilities.attackEntityWithoutKnockback(target, MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.FROST), 1*damageMultiplier); + target.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, getCaster(), DamageType.FROST), 1*damageMultiplier); }else{ - WizardryUtilities.attackEntityWithoutKnockback(target, DamageSource.magic, 1*damageMultiplier); + target.attackEntityFrom(DamageSource.magic, 1*damageMultiplier); } + + // Removes knockback + target.motionX = velX; + target.motionY = velY; + target.motionZ = velZ; } // All entities are slowed, even the caster (except those immune to frost effects) if(!MagicDamage.isEntityImmune(DamageType.FROST, target)) - target.addPotionEffect(new PotionEffect(WizardryPotions.frost, 20, 0)); + target.addPotionEffect(new PotionEffect(Wizardry.frost.id, 20, 0, true)); } }else{ - // For some reason this number of particles now causes the game to lag significantly, despite it being fine - // in 1.7.10. I thought particles were supposed to be LESS laggy now... - for(int i=1; i<6; i++){ + for(int i=1; i<10; i++){ float brightness = 0.5f + (rand.nextFloat()/2); - Wizardry.proxy.spawnParticle(WizardryParticleType.BLIZZARD, worldObj, this.posX, this.posY + rand.nextDouble()*3, this.posZ, 0, 0, 0, 100, brightness, brightness + 0.1f, 1.0f, false, rand.nextDouble() * 2.5d + 0.5d); - Wizardry.proxy.spawnParticle(WizardryParticleType.BLIZZARD, worldObj, this.posX, this.posY + rand.nextDouble()*3, this.posZ, 0, 0, 0, 100, 1.0f, 1.0f, 1.0f, false, rand.nextDouble() * 2.5d + 0.5d); + Wizardry.proxy.spawnParticle(EnumParticleType.BLIZZARD, worldObj, this.posX, this.posY + rand.nextDouble()*3, this.posZ, 0, 0, 0, 100, brightness, brightness + 0.1f, 1.0f, false, rand.nextDouble() * 2.5d + 0.5d); + Wizardry.proxy.spawnParticle(EnumParticleType.BLIZZARD, worldObj, this.posX, this.posY + rand.nextDouble()*3, this.posZ, 0, 0, 0, 100, 1.0f, 1.0f, 1.0f, false, rand.nextDouble() * 2.5d + 0.5d); } } } diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityBubble.java b/src/main/java/electroblob/wizardry/entity/construct/EntityBubble.java index 620fb9ee..e4198c81 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityBubble.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityBubble.java @@ -2,21 +2,15 @@ package electroblob.wizardry.entity.construct; import java.lang.ref.WeakReference; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.MagicDamage.DamageType; import io.netty.buffer.ByteBuf; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.SoundEvents; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumParticleTypes; import net.minecraft.world.World; -import net.minecraftforge.event.entity.living.LivingAttackEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -@Mod.EventBusSubscriber public class EntityBubble extends EntityMagicConstruct { public boolean isDarkOrb; @@ -49,54 +43,53 @@ public class EntityBubble extends EntityMagicConstruct { super.onUpdate(); // Synchronises the rider field - if((this.rider == null || this.rider.get() == null) && WizardryUtilities.getRider(this) instanceof EntityLivingBase - && !WizardryUtilities.getRider(this).isDead){ - this.rider = new WeakReference((EntityLivingBase) WizardryUtilities.getRider(this)); + if((this.rider == null || this.rider.get() == null) && this.riddenByEntity != null && !this.riddenByEntity.isDead){ + this.rider = new WeakReference(this.riddenByEntity); } // Prevents dismounting - if(WizardryUtilities.getRider(this) == null && this.rider != null && this.rider.get() != null && !this.rider.get().isDead){ - this.rider.get().startRiding(this); + if(this.riddenByEntity == null && this.rider != null && this.rider.get() != null && !this.rider.get().isDead){ + this.rider.get().mountEntity(this); } // Stops the bubble bursting instantly. - if(this.ticksExisted < 1 && !isDarkOrb) ((EntityLivingBase)WizardryUtilities.getRider(this)).hurtTime = 0; + if(this.ticksExisted < 1 && !isDarkOrb) ((EntityLivingBase)this.riddenByEntity).hurtTime = 0; this.moveEntity(0, 0.03, 0); if(isDarkOrb){ - if(WizardryUtilities.getRider(this) != null && this.ticksExisted % 30 == 0){ + if(this.riddenByEntity != null && this.ticksExisted % 30 == 0){ if(this.getCaster() != null){ - WizardryUtilities.getRider(this).attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.MAGIC), 1*damageMultiplier); + this.riddenByEntity.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, getCaster(), DamageType.MAGIC), 1*damageMultiplier); }else{ - WizardryUtilities.getRider(this).attackEntityFrom(DamageSource.magic, 1*damageMultiplier); + this.riddenByEntity.attackEntityFrom(DamageSource.magic, 1*damageMultiplier); } } for(int i=0; i<5; i++){ - this.worldObj.spawnParticle(EnumParticleTypes.PORTAL, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height + 0.5d, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, (this.rand.nextDouble() - 0.5D) * 2.0D, -this.rand.nextDouble(), (this.rand.nextDouble() - 0.5D) * 2.0D); + this.worldObj.spawnParticle("portal", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height + 0.5d, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, (this.rand.nextDouble() - 0.5D) * 2.0D, -this.rand.nextDouble(), (this.rand.nextDouble() - 0.5D) * 2.0D); } if(lifetime - this.ticksExisted == 75){ - this.playSound(SoundEvents.BLOCK_PORTAL_TRIGGER, 1.5f, 1.0f); + this.worldObj.playSoundAtEntity(this, "portal.trigger", 1.5f, 1.0f); }else if(this.ticksExisted % 100 == 1 && this.ticksExisted < 150){ - this.playSound(SoundEvents.BLOCK_PORTAL_AMBIENT, 1.5f, 1.0f); + this.worldObj.playSoundAtEntity(this, "portal.portal", 1.5f, 1.0f); } } // Bubble bursts if the entity is hurt (see event handler) or killed, or if the bubble has existed for more than 10 seconds. - if(WizardryUtilities.getRider(this) == null && this.ticksExisted > 1){ - if(!this.isDarkOrb) this.playSound(SoundEvents.ENTITY_ITEM_PICKUP, 1.5f, 1.0f); + if(this.riddenByEntity == null && this.ticksExisted > 1){ + if(!this.isDarkOrb) this.worldObj.playSoundAtEntity(this, "random.pop", 1.5f, 1.0f); this.setDead(); } } @Override public void despawn(){ - if(WizardryUtilities.getRider(this) != null){ - ((EntityLivingBase)WizardryUtilities.getRider(this)).dismountEntity(this); + if(this.riddenByEntity != null){ + ((EntityLivingBase)this.riddenByEntity).dismountEntity(this); } - if(!this.isDarkOrb) this.playSound(SoundEvents.ENTITY_ITEM_PICKUP, 1.5f, 1.0f); + if(!this.isDarkOrb) this.worldObj.playSoundAtEntity(this, "random.pop", 1.5f, 1.0f); super.despawn(); } @@ -123,15 +116,5 @@ public class EntityBubble extends EntityMagicConstruct { super.readSpawnData(data); this.isDarkOrb = data.readBoolean(); } - - @SubscribeEvent - public static void onLivingAttackEvent(LivingAttackEvent event){ - // Bursts bubble when the creature inside takes damage - if(event.getEntityLiving().getRidingEntity() instanceof EntityBubble && - !((EntityBubble)event.getEntityLiving().getRidingEntity()).isDarkOrb){ - event.getEntityLiving().getRidingEntity().playSound(SoundEvents.ENTITY_ITEM_PICKUP, 1.5f, 1.0f); - event.getEntityLiving().getRidingEntity().setDead(); - } - } } diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityDecay.java b/src/main/java/electroblob/wizardry/entity/construct/EntityDecay.java index f8d33151..710e0b00 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityDecay.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityDecay.java @@ -2,15 +2,13 @@ package electroblob.wizardry.entity.construct; import java.util.List; +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.SoundEvents; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class EntityDecay extends EntityMagicConstruct { @@ -37,22 +35,23 @@ public class EntityDecay extends EntityMagicConstruct { super.onUpdate(); - if(this.rand.nextInt(700) == 0 && this.ticksExisted+100 < LIFETIME) this.playSound(SoundEvents.BLOCK_LAVA_AMBIENT, 0.2F + rand.nextFloat() * 0.2F, 0.6F + rand.nextFloat() * 0.15F); + if(this.rand.nextInt(700) == 0 && this.ticksExisted+100 < LIFETIME) this.playSound("liquid.lava", 0.2F + rand.nextFloat() * 0.2F, 0.6F + rand.nextFloat() * 0.15F); if(!this.worldObj.isRemote){ - List targets = WizardryUtilities.getEntitiesWithinRadius(1.0d, this.posX, this.posY, this.posZ, this.worldObj); - for(EntityLivingBase target : targets){ - if(target != this.getCaster()){ + List targets = WizardryUtilities.getEntitiesWithinRadius(1.0d, this.posX, this.posY, this.posZ, this.worldObj); + for(int i=0; i targets = WizardryUtilities.getEntitiesWithinRadius((this.ticksExisted*speed)+1.5, this.posX, this.posY, this.posZ, worldObj); - + // In this particular instance, the caster is completely unaffected because they will always be in the centre. targets.remove(this.getCaster()); @@ -74,33 +80,21 @@ public class EntityEarthquake extends EntityMagicConstruct { double motionZ = target.motionZ; if(this.isValidTarget(target)){ - target.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, this.getCaster(), DamageType.BLAST), 10*this.damageMultiplier); - target.addPotionEffect(new PotionEffect(MobEffects.WEAKNESS, 400, 1)); + target.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getCaster(), DamageType.BLAST), 10*this.damageMultiplier); + target.addPotionEffect(new PotionEffect(Potion.weakness.id, 400, 1)); } // All targets are thrown, even those immune to the damage, so they don't fall into the ground. target.motionX = motionX; target.motionY = 0.8; // Throws target into the air. target.motionZ = motionZ; - + // Player motion is handled on that player's client so needs packets if(target instanceof EntityPlayerMP){ - ((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target)); + ((EntityPlayerMP)target).playerNetServerHandler.sendPacket(new S12PacketEntityVelocity(target)); } } } - // TODO: Uncomment once 2.1.0 is released -// }else{ -// -// // Constant 15 blocks for now -// List targets = WizardryUtilities.getEntitiesWithinRadius(15, this.posX, this.posY, this.posZ, worldObj, EntityPlayer.class); -// -// float magnitude = 6f * ((float)(this.lifetime - this.ticksExisted))/(float)this.lifetime; -// -// // Makes the screen shake -// for(EntityLivingBase target : targets){ -// target.setAngles(0, this.ticksExisted % 4 < 2 ? magnitude : -magnitude); -// } } } diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityFireRing.java b/src/main/java/electroblob/wizardry/entity/construct/EntityFireRing.java index e2055da5..807fc1be 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityFireRing.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityFireRing.java @@ -2,11 +2,11 @@ package electroblob.wizardry.entity.construct; import java.util.List; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.SoundEvents; import net.minecraft.util.DamageSource; import net.minecraft.world.World; @@ -27,7 +27,7 @@ public class EntityFireRing extends EntityMagicConstruct { public void onUpdate(){ if(this.ticksExisted % 40 == 1){ - this.playSound(SoundEvents.BLOCK_FIRE_AMBIENT, 4.0f, 0.7f); + this.playSound("fire.fire", 4.0f, 0.7f); } super.onUpdate(); @@ -49,7 +49,7 @@ public class EntityFireRing extends EntityMagicConstruct { target.setFire(10); if(this.getCaster() != null){ - target.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.FIRE), 1*damageMultiplier); + target.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, getCaster(), DamageType.FIRE), 1*damageMultiplier); }else{ target.attackEntityFrom(DamageSource.magic, 1*damageMultiplier); } diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityFireSigil.java b/src/main/java/electroblob/wizardry/entity/construct/EntityFireSigil.java index 9913006e..78b6a070 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityFireSigil.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityFireSigil.java @@ -2,13 +2,12 @@ package electroblob.wizardry.entity.construct; import java.util.List; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.SoundEvents; import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumParticleTypes; import net.minecraft.world.World; public class EntityFireSigil extends EntityMagicConstruct { @@ -49,7 +48,7 @@ public class EntityFireSigil extends EntityMagicConstruct { double velY = target.motionY; double velZ = target.motionZ; - target.attackEntityFrom(this.getCaster() != null ? MagicDamage.causeIndirectMagicDamage(this, this.getCaster(), DamageType.FIRE) : DamageSource.magic, 6); + target.attackEntityFrom(this.getCaster() != null ? MagicDamage.causeIndirectEntityMagicDamage(this, this.getCaster(), DamageType.FIRE) : DamageSource.magic, 6); // Removes knockback target.motionX = velX; @@ -57,8 +56,8 @@ public class EntityFireSigil extends EntityMagicConstruct { target.motionZ = velZ; if(!MagicDamage.isEntityImmune(DamageType.FIRE, target)) target.setFire(10); - - this.playSound(SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1); + + worldObj.playAuxSFX(1009, (int)this.posX, (int)this.posY, (int)this.posZ, 0); // The trap is destroyed once triggered. this.setDead(); @@ -67,7 +66,7 @@ public class EntityFireSigil extends EntityMagicConstruct { }else if(this.rand.nextInt(15) == 0){ double radius = 0.5 + rand.nextDouble()*0.3; double angle = rand.nextDouble()*Math.PI*2; - worldObj.spawnParticle(EnumParticleTypes.FLAME, this.posX + radius*Math.cos(angle), this.posY + 0.1, this.posZ + radius*Math.sin(angle), 0, 0, 0); + worldObj.spawnParticle("flame", this.posX + radius*Math.cos(angle), this.posY + 0.1, this.posZ + radius*Math.sin(angle), 0, 0, 0); } } diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityForcefield.java b/src/main/java/electroblob/wizardry/entity/construct/EntityForcefield.java index f0f817eb..d1a5eaae 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityForcefield.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityForcefield.java @@ -2,16 +2,19 @@ package electroblob.wizardry.entity.construct; import java.util.List; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IProjectile; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.network.play.server.SPacketEntityVelocity; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.network.play.server.S12PacketEntityVelocity; +import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; -import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.world.World; public class EntityForcefield extends EntityMagicConstruct { @@ -20,7 +23,7 @@ public class EntityForcefield extends EntityMagicConstruct { super(world); this.height = 6; this.width = 6; - this.setEntityBoundingBox(new AxisAlignedBB(this.posX - 3, this.posY - 3, this.posZ - 3, this.posX + 3, this.posY + 3, this.posZ + 3)); + this.boundingBox.setBounds(this.posX - 3, this.posY - 3, this.posZ - 3, this.posX + 3, this.posY + 3, this.posZ + 3); } public EntityForcefield(World world, double x, double y, double z, EntityLivingBase caster, int lifetime) { @@ -29,7 +32,7 @@ public class EntityForcefield extends EntityMagicConstruct { super(world, x, y-3, z, caster, lifetime, 1.0f); this.height = 6; this.width = 6; - this.setEntityBoundingBox(new AxisAlignedBB(this.posX - 3, this.posY - 3, this.posZ - 3, this.posX + 3, this.posY + 3, this.posZ + 3)); + this.boundingBox.setBounds(this.posX - 3, this.posY - 3, this.posZ - 3, this.posX + 3, this.posY + 3, this.posZ + 3); } public boolean canBeCollidedWith() @@ -39,7 +42,7 @@ public class EntityForcefield extends EntityMagicConstruct { public AxisAlignedBB getCollisionBox(Entity par1Entity) { - return par1Entity.getEntityBoundingBox(); + return par1Entity.boundingBox; } public void onUpdate(){ @@ -54,7 +57,7 @@ public class EntityForcefield extends EntityMagicConstruct { target.addVelocity((target.posX - this.posX)*multiplier, (target.posY - (this.posY + 3))*multiplier, (target.posZ - this.posZ)*multiplier); // Player motion is handled on that player's client so needs packets if(target instanceof EntityPlayerMP){ - ((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target)); + ((EntityPlayerMP)target).playerNetServerHandler.sendPacket(new S12PacketEntityVelocity(target)); } } } @@ -65,18 +68,17 @@ public class EntityForcefield extends EntityMagicConstruct { double yaw = rand.nextDouble()*Math.PI*2; double pitch = (rand.nextDouble()-0.5)*Math.PI; // Generates a spherical pattern of particles - Wizardry.proxy.spawnParticle(WizardryParticleType.BRIGHT_DUST, worldObj, this.posX + radius*Math.cos(yaw)*Math.cos(pitch), this.posY + 3 + radius*Math.sin(pitch), this.posZ + radius*Math.sin(yaw)*Math.cos(pitch), 0, 0, 0, 48 + this.rand.nextInt(12), brightness, brightness, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.BRIGHT_DUST, worldObj, this.posX + radius*Math.cos(yaw)*Math.cos(pitch), this.posY + 3 + radius*Math.sin(pitch), this.posZ + radius*Math.sin(yaw)*Math.cos(pitch), 0, 0, 0, 48 + this.rand.nextInt(12), brightness, brightness, 1.0f); } } } - public boolean attackEntityFrom(DamageSource source, float par2){ - - if(source != null && source.getSourceOfDamage() != null){ - // Now works for any source of damage. - source.getSourceOfDamage().playSound(WizardrySounds.SPELL_DEFLECTION, 0.3f, 1.3f); + public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) + { + if(par1DamageSource != null && par1DamageSource.getSourceOfDamage() instanceof IProjectile){ + worldObj.playSoundAtEntity(par1DamageSource.getSourceOfDamage(), "wizardry:effect", 0.3f, 1.3f); } - super.attackEntityFrom(source, par2); + super.attackEntityFrom(par1DamageSource, par2); return false; } diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityFrostSigil.java b/src/main/java/electroblob/wizardry/entity/construct/EntityFrostSigil.java index f2cb3ffe..d327561c 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityFrostSigil.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityFrostSigil.java @@ -2,13 +2,12 @@ package electroblob.wizardry.entity.construct; import java.util.List; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.EntityLivingBase; import net.minecraft.potion.PotionEffect; import net.minecraft.util.DamageSource; @@ -52,7 +51,7 @@ public class EntityFrostSigil extends EntityMagicConstruct { double velY = target.motionY; double velZ = target.motionZ; - target.attackEntityFrom(this.getCaster() != null ? MagicDamage.causeIndirectMagicDamage(this, this.getCaster(), DamageType.FROST) : DamageSource.magic, 8); + target.attackEntityFrom(this.getCaster() != null ? MagicDamage.causeIndirectEntityMagicDamage(this, this.getCaster(), DamageType.FROST) : DamageSource.magic, 8); // Removes knockback target.motionX = velX; @@ -60,9 +59,9 @@ public class EntityFrostSigil extends EntityMagicConstruct { target.motionZ = velZ; if(!MagicDamage.isEntityImmune(DamageType.FROST, target)) - target.addPotionEffect(new PotionEffect(WizardryPotions.frost, 200, 1)); + target.addPotionEffect(new PotionEffect(Wizardry.frost.id, 200, 1, true)); - this.playSound(WizardrySounds.SPELL_FREEZE, 1.0f, 1.0f); + this.playSound("wizardry:freeze", 1.0f, 1.0f); // The trap is destroyed once triggered. this.setDead(); @@ -71,7 +70,7 @@ public class EntityFrostSigil extends EntityMagicConstruct { }else if(this.rand.nextInt(15) == 0){ double radius = 0.5 + rand.nextDouble()*0.3; double angle = rand.nextDouble()*Math.PI*2; - Wizardry.proxy.spawnParticle(WizardryParticleType.SNOW, worldObj, this.posX + radius*Math.cos(angle), this.posY + 0.1, this.posZ + radius*Math.sin(angle), 0, 0, 0, 40 + rand.nextInt(10)); + Wizardry.proxy.spawnParticle(EnumParticleType.SNOW, worldObj, this.posX + radius*Math.cos(angle), this.posY + 0.1, this.posZ + radius*Math.sin(angle), 0, 0, 0, 40 + rand.nextInt(10)); } } diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityHammer.java b/src/main/java/electroblob/wizardry/entity/construct/EntityHammer.java index 67950d41..04892d8f 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityHammer.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityHammer.java @@ -2,72 +2,80 @@ package electroblob.wizardry.entity.construct; import java.util.List; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.entity.EntityArc; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.block.Block; -import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.EntityTracker; import net.minecraft.entity.effect.EntityLightningBolt; -import net.minecraft.init.SoundEvents; +import net.minecraft.entity.monster.EntityCreeper; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.play.server.S14PacketEntity.S15PacketEntityRelMove; import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.Vec3; import net.minecraft.world.World; +import net.minecraft.world.WorldServer; -public class EntityHammer extends EntityMagicConstruct { - +public class EntityHammer extends EntityMagicConstruct +{ /** How long the hammer has been falling for. */ public int fallTime; - public EntityHammer(World par1World){ + public EntityHammer(World par1World) + { super(par1World); this.setSize(1.0f, 1.9F); this.noClip = false; } - public EntityHammer(World world, double x, double y, double z, EntityLivingBase caster, int lifetime, float damageMultiplier){ + public EntityHammer(World world, double x, double y, double z, EntityLivingBase caster, int lifetime, float damageMultiplier) + { super(world, x, y, z, caster, lifetime, damageMultiplier); - this.setSize(1.0f, 1.9F); + this.setSize(1.1f, 1.9F); this.motionX = 0.0D; this.motionY = 0.0D; this.motionZ = 0.0D; this.noClip = false; } - @Override - public boolean isBurning(){ + /** + * Returns true if the entity is on fire. Used by render to add the fire effect on rendering. + */ + public boolean isBurning() + { return false; } - @Override - public boolean canBeCollidedWith(){ + /** + * Returns true if other Entities should be prevented from moving through this Entity. + */ + public boolean canBeCollidedWith() + { return true; } - - @Override - public AxisAlignedBB getCollisionBoundingBox(){ - return this.getEntityBoundingBox(); - } - @Override + /** + * Called to update the entity's position/logic. + */ public void onUpdate(){ super.onUpdate(); if(this.ticksExisted % 20 == 1 && !this.onGround && worldObj.isRemote){ // Though this sound does repeat, it stops when it hits the ground. - Wizardry.proxy.playMovingSound(this, WizardrySounds.SPELL_LOOP_LIGHTNING, 3.0f, 1.0f, false); + Wizardry.proxy.playMovingSound(this, "wizardry:electricityb", 3.0f, 1.0f, false); } if(this.worldObj.isRemote && this.ticksExisted % 3 == 0){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, worldObj, this.posX - 0.5d + rand.nextDouble(), this.posY + 2*rand.nextDouble(), this.posZ - 0.5d + rand.nextDouble(), 0, 0, 0, 3); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, this.posX - 0.5d + rand.nextDouble(), this.posY + 2*rand.nextDouble(), this.posZ - 0.5d + rand.nextDouble(), 0, 0, 0, 3); } if(!this.worldObj.isRemote){ @@ -101,21 +109,20 @@ public class EntityHammer extends EntityMagicConstruct { if(!worldObj.isRemote){ EntityArc arc = new EntityArc(worldObj); - arc.setEndpointCoords(this.posX, this.posY + this.height - 0.1, this.posZ, + arc.setEndpointCoords(this.posX, this.posY+1, this.posZ, target.posX, target.posY + target.height/2, target.posZ); worldObj.spawnEntityInWorld(arc); }else{ for(int j=0;j<8;j++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, worldObj, target.posX + worldObj.rand.nextFloat() - 0.5, target.getEntityBoundingBox().minY + target.height/2 + worldObj.rand.nextFloat()*2 - 1, target.posZ + worldObj.rand.nextFloat() - 0.5, 0, 0, 0, 3); - worldObj.spawnParticle(EnumParticleTypes.SMOKE_LARGE, target.posX + rand.nextFloat(), target.getEntityBoundingBox().minY + target.height/2 + rand.nextFloat(), target.posZ + rand.nextFloat(), 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, target.posX + worldObj.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(target) + target.height/2 + worldObj.rand.nextFloat()*2 - 1, target.posZ + worldObj.rand.nextFloat() - 0.5, 0, 0, 0, 3); + worldObj.spawnParticle("largesmoke", target.posX + rand.nextFloat(), WizardryUtilities.getEntityFeetPos(target) + target.height/2 + rand.nextFloat(), target.posZ + rand.nextFloat(), 0, 0, 0); } } - target.playSound(WizardrySounds.SPELL_SPARK, 1.0F, rand.nextFloat() * 0.4F + 1.5F); + worldObj.playSoundAtEntity(target, "wizardry:arc", 1.0F, rand.nextFloat() * 0.4F + 1.5F); if(this.getCaster() != null){ - WizardryUtilities.attackEntityWithoutKnockback(target, MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.SHOCK), 6*damageMultiplier); - WizardryUtilities.applyStandardKnockback(this, target); + target.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, getCaster(), DamageType.SHOCK), 6*damageMultiplier); }else{ target.attackEntityFrom(DamageSource.magic, 6*damageMultiplier); } @@ -126,58 +133,96 @@ public class EntityHammer extends EntityMagicConstruct { } } - @Override public void despawn(){ - this.playSound(SoundEvents.ENTITY_GENERIC_EXPLODE, 1.0F, 1.0f); + this.playSound("random.explode", 1.0F, 1.0f); if(this.worldObj.isRemote){ - this.worldObj.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0); + this.worldObj.spawnParticle("largeexplode", this.posX, this.posY, this.posZ, 0, 0, 0); } super.despawn(); } - - @Override - public void fall(float distance, float damageMultiplier) { - + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1){ + if(worldObj.isRemote){ for(int i=0; i<40; i++){ double particleX = this.posX - 1.0d + 2*rand.nextDouble(); double particleZ = this.posZ - 1.0d + 2*rand.nextDouble(); // Roundabout way of getting a block instance for the block the hammer is standing on (if any). - IBlockState block = worldObj.getBlockState(new BlockPos(this.posX, this.posY-2, this.posZ)); + Block block = worldObj.getBlock((int)this.posX, (int)this.posY-2, (int)this.posZ); if(block != null){ - worldObj.spawnParticle(EnumParticleTypes.BLOCK_DUST, particleX, this.posY, particleZ, - particleX - this.posX, 0, particleZ - this.posZ, Block.getStateId(block)); + Wizardry.proxy.spawnDigParticle(worldObj, particleX, this.posY, particleZ, + particleX - this.posX, 0, particleZ - this.posZ, block); } } + }else{ - // Just to check the hammer has actually fallen from the sky, rather than the block under it being broken. + + // For some reason, the hammer falls again on world reload, but only by about 1 block. if(this.fallDistance > 10){ - EntityLightningBolt entitylightning = new EntityLightningBolt(worldObj, this.posX, this.posY, this.posZ, false); + + // For some reason, the hammer 'lands' one block above the ground first time around - on the SERVER as well. + // Edit: not any more, it seems... maybe because the yOffset thing got deleted. + //this.setPosition(this.posX, this.posY-0.8, this.posZ); + + EntityLightningBolt entitylightning = new EntityLightningBolt(worldObj, this.posX, this.posY, this.posZ); worldObj.addWeatherEffect(entitylightning); + + // The last three parameters are the difference in position between server and client. What this is doing + // is essentially hijacking the vanilla packet to force the hammer into the right position. (not sure why, + // but the packet divides these numbers by 32.) + S15PacketEntityRelMove packet = new S15PacketEntityRelMove(this.getEntityId(), (byte)0, (byte)-65, (byte)0); + + if(this.worldObj instanceof WorldServer){ + EntityTracker et = ((WorldServer)this.worldObj).getEntityTracker(); + // This sends a packet to all players tracking the entity. + et.func_151248_b(this, packet); + } + //packet.yPosition = -65; + + //PacketDispatcher.sendPacketToAllAround(this.posX, this.posY, this.posZ, 256, this.dimension, packet); + //PacketDispatcher.sendPacketToAllPlayers(packet); } } } - @Override + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ public void writeEntityToNBT(NBTTagCompound nbttagcompound) { super.writeEntityToNBT(nbttagcompound); nbttagcompound.setByte("Time", (byte)this.fallTime); } - @Override + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ public void readEntityFromNBT(NBTTagCompound nbttagcompound) { super.readEntityFromNBT(nbttagcompound); this.fallTime = nbttagcompound.getByte("Time") & 255; + // Undoes the manual position change on world reload to prevent the hammer being in the ground. + //this.setPosition(this.posX, this.posY+0.8, this.posZ); } - @Override - public boolean isInRangeToRenderDist(double distance) { - return true; + @SideOnly(Side.CLIENT) + public float getShadowSize() + { + return 1.0F; + } + + /** + * Checks using a Vec3d to determine if this entity is within range of that vector to be rendered. Args: vec3D + */ + public boolean isInRangeToRenderVec3D(Vec3 par1Vec3) + { + return true; } } diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityHealAura.java b/src/main/java/electroblob/wizardry/entity/construct/EntityHealAura.java index 34a96dd8..90b63272 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityHealAura.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityHealAura.java @@ -2,12 +2,12 @@ package electroblob.wizardry.entity.construct; import java.util.List; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.EntityLivingBase; import net.minecraft.util.DamageSource; import net.minecraft.world.World; @@ -29,7 +29,7 @@ public class EntityHealAura extends EntityMagicConstruct { public void onUpdate(){ if(this.ticksExisted % 25 == 1){ - this.playSound(WizardrySounds.SPELL_LOOP_SPARKLE, 0.1f, 1.0f); + this.playSound("wizardry:sparkle", 0.1f, 1.0f); } super.onUpdate(); @@ -49,7 +49,7 @@ public class EntityHealAura extends EntityMagicConstruct { double velZ = target.motionZ; if(this.getCaster() != null){ - target.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.RADIANT), 1*damageMultiplier); + target.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, getCaster(), DamageType.RADIANT), 1*damageMultiplier); }else{ target.attackEntityFrom(DamageSource.magic, 1*damageMultiplier); } @@ -69,7 +69,7 @@ public class EntityHealAura extends EntityMagicConstruct { float brightness = 0.5f + (rand.nextFloat()*0.5f); double radius = rand.nextDouble()*2.0; double angle = rand.nextDouble()*Math.PI*2; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, this.posX + radius*Math.cos(angle), this.posY, this.posZ + radius*Math.sin(angle), 0, 0.05f, 0, 48 + this.rand.nextInt(12), 1.0f, 1.0f, brightness); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX + radius*Math.cos(angle), this.posY, this.posZ + radius*Math.sin(angle), 0, 0.05f, 0, 48 + this.rand.nextInt(12), 1.0f, 1.0f, brightness); } } } diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityIceSpike.java b/src/main/java/electroblob/wizardry/entity/construct/EntityIceSpike.java index b314a2cf..f14367d6 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityIceSpike.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityIceSpike.java @@ -1,9 +1,8 @@ package electroblob.wizardry.entity.construct; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.MagicDamage.DamageType; +import electroblob.wizardry.Wizardry; import net.minecraft.entity.EntityLivingBase; import net.minecraft.potion.PotionEffect; import net.minecraft.world.World; @@ -32,14 +31,14 @@ public class EntityIceSpike extends EntityMagicConstruct { this.moveEntity(this.motionX, this.motionY, this.motionZ); - if(lifetime - this.ticksExisted == 30) this.playSound(WizardrySounds.SPELL_ICE, 1, 2); + if(lifetime - this.ticksExisted == 30) this.playSound("wizardry:ice", 1, 2); if(!this.worldObj.isRemote){ - for(Object entity : this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox())){ + for(Object entity : this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox)){ if(entity instanceof EntityLivingBase && this.isValidTarget((EntityLivingBase)entity)){ // Potion effect only gets added if the damage succeeded. if(((EntityLivingBase)entity).attackEntityFrom(MagicDamage.causeDirectMagicDamage(this.getCaster(), DamageType.FROST), 5*this.damageMultiplier)) - ((EntityLivingBase)entity).addPotionEffect(new PotionEffect(WizardryPotions.frost, 100, 0)); + ((EntityLivingBase)entity).addPotionEffect(new PotionEffect(Wizardry.frost.id, 100, 0)); } } } diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityLightningPulse.java b/src/main/java/electroblob/wizardry/entity/construct/EntityLightningPulse.java index 59653c0b..4b167b0a 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityLightningPulse.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityLightningPulse.java @@ -1,6 +1,15 @@ package electroblob.wizardry.entity.construct; +import java.util.List; + +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.DamageSource; import net.minecraft.world.World; public class EntityLightningPulse extends EntityMagicConstruct { diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityLightningSigil.java b/src/main/java/electroblob/wizardry/entity/construct/EntityLightningSigil.java index 8ecb646d..6f490c1e 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityLightningSigil.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityLightningSigil.java @@ -2,16 +2,17 @@ package electroblob.wizardry.entity.construct; import java.util.List; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.entity.EntityArc; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityCreeper; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumParticleTypes; import net.minecraft.world.World; public class EntityLightningSigil extends EntityMagicConstruct { @@ -57,14 +58,14 @@ public class EntityLightningSigil extends EntityMagicConstruct { double velZ = target.motionZ; // Only works if target is actually damaged to account for hurtResistantTime - if(target.attackEntityFrom(getCaster() != null ? MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.SHOCK) : DamageSource.magic, 6)){ + if(target.attackEntityFrom(getCaster() != null ? MagicDamage.causeIndirectEntityMagicDamage(this, getCaster(), DamageType.SHOCK) : DamageSource.magic, 6)){ // Removes knockback target.motionX = velX; target.motionY = velY; target.motionZ = velZ; - this.playSound(WizardrySounds.SPELL_SPARK, 1.0f, 1.0f); + this.playSound("wizardry:arc", 1.0f, 1.0f); // Secondary chaining effect double seekerRange = 5.0d; @@ -84,14 +85,14 @@ public class EntityLightningSigil extends EntityMagicConstruct { worldObj.spawnEntityInWorld(arc); }else{ for(int k=0;k<8;k++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, worldObj, secondaryTarget.posX + worldObj.rand.nextFloat() - 0.5, secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height/2 + worldObj.rand.nextFloat()*2 - 1, secondaryTarget.posZ + worldObj.rand.nextFloat() - 0.5, 0, 0, 0, 3); - worldObj.spawnParticle(EnumParticleTypes.SMOKE_LARGE, secondaryTarget.posX + worldObj.rand.nextFloat() - 0.5, secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height/2 + worldObj.rand.nextFloat()*2 - 1, secondaryTarget.posZ + worldObj.rand.nextFloat() - 0.5, 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, secondaryTarget.posX + worldObj.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(secondaryTarget) + secondaryTarget.height/2 + worldObj.rand.nextFloat()*2 - 1, secondaryTarget.posZ + worldObj.rand.nextFloat() - 0.5, 0, 0, 0, 3); + worldObj.spawnParticle("largesmoke", secondaryTarget.posX + worldObj.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(secondaryTarget) + secondaryTarget.height/2 + worldObj.rand.nextFloat()*2 - 1, secondaryTarget.posZ + worldObj.rand.nextFloat() - 0.5, 0, 0, 0); } } - secondaryTarget.playSound(WizardrySounds.SPELL_SPARK, 1.0F, worldObj.rand.nextFloat() * 0.4F + 1.5F); + worldObj.playSoundAtEntity(secondaryTarget, "wizardry:arc", 1.0F, worldObj.rand.nextFloat() * 0.4F + 1.5F); - secondaryTarget.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.SHOCK), 4); + secondaryTarget.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, getCaster(), DamageType.SHOCK), 4); } } @@ -105,7 +106,7 @@ public class EntityLightningSigil extends EntityMagicConstruct { if(this.worldObj.isRemote && this.rand.nextInt(15) == 0){ double radius = 0.5 + rand.nextDouble()*0.3; double angle = rand.nextDouble()*Math.PI*2; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, worldObj, this.posX + radius*Math.cos(angle), this.posY + 0.1, this.posZ + radius*Math.sin(angle), 0, 0, 0, 3); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, this.posX + radius*Math.cos(angle), this.posY + 0.1, this.posZ + radius*Math.sin(angle), 0, 0, 0, 3); } } diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityMagicConstruct.java b/src/main/java/electroblob/wizardry/entity/construct/EntityMagicConstruct.java index e477f9d5..c523fe55 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityMagicConstruct.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityMagicConstruct.java @@ -3,13 +3,16 @@ package electroblob.wizardry.entity.construct; import java.lang.ref.WeakReference; import java.util.UUID; -import electroblob.wizardry.util.WizardryUtilities; +import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.entity.living.EntitySummonedCreature; import io.netty.buffer.ByteBuf; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; -import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; /** * This class is for all inanimate magical constructs which are not projectiles. It was made from scratch @@ -59,10 +62,10 @@ public abstract class EntityMagicConstruct extends Entity implements IEntityAddi // Overrides the original to stop the entity moving when it intersects stuff. The default arrow does this to allow // it to stick in blocks. @Override - public void setPositionAndRotationDirect(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean teleport) + public void setPositionAndRotation2(double par1, double par3, double par5, float par7, float par8, int par9) { - this.setPosition(x, y, z); - this.setRotation(yaw, pitch); + this.setPosition(par1, par3, par5); + this.setRotation(par7, par8); } public void onUpdate(){ @@ -99,7 +102,8 @@ public abstract class EntityMagicConstruct extends Entity implements IEntityAddi @Override protected void readEntityFromNBT(NBTTagCompound nbttagcompound){ - casterUUID = nbttagcompound.getUniqueId("casterUUID"); + String string = nbttagcompound.getString("casterUUID"); + if(WizardryUtilities.verifyUUIDString(string)) casterUUID = UUID.fromString(string); lifetime = nbttagcompound.getInteger("lifetime"); damageMultiplier = nbttagcompound.getFloat("damageMultiplier"); } @@ -107,7 +111,7 @@ public abstract class EntityMagicConstruct extends Entity implements IEntityAddi @Override protected void writeEntityToNBT(NBTTagCompound nbttagcompound){ if(this.getCaster() != null){ - nbttagcompound.setUniqueId("casterUUID", this.getCaster().getUniqueID()); + nbttagcompound.setString("casterUUID", this.getCaster().getUniqueID().toString()); } nbttagcompound.setInteger("lifetime", lifetime); nbttagcompound.setFloat("damageMultiplier", damageMultiplier); diff --git a/src/main/java/electroblob/wizardry/entity/construct/EntityTornado.java b/src/main/java/electroblob/wizardry/entity/construct/EntityTornado.java index 2e1625a9..8530addf 100644 --- a/src/main/java/electroblob/wizardry/entity/construct/EntityTornado.java +++ b/src/main/java/electroblob/wizardry/entity/construct/EntityTornado.java @@ -2,25 +2,23 @@ package electroblob.wizardry.entity.construct; import java.util.List; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardryAchievements; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import io.netty.buffer.ByteBuf; +import net.minecraft.block.Block; import net.minecraft.block.material.Material; -import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.passive.EntityPig; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.play.server.SPacketEntityVelocity; +import net.minecraft.network.play.server.S12PacketEntityVelocity; import net.minecraft.util.DamageSource; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraftforge.common.BiomeDictionary; public class EntityTornado extends EntityMagicConstruct { @@ -48,16 +46,12 @@ public class EntityTornado extends EntityMagicConstruct { if(this.ticksExisted % 120 == 1 && worldObj.isRemote){ // Repeat is false so that the sound fades out when the tornado does rather than stopping suddenly - Wizardry.proxy.playMovingSound(this, WizardrySounds.SPELL_LOOP_WIND, 1.0f, 1.0f, false); + Wizardry.proxy.playMovingSound(this, "wizardry:wind", 1.0f, 1.0f, false); } this.moveEntity(velX, motionY, velZ); - BlockPos pos = new BlockPos(this); - int y = WizardryUtilities.getNearestFloorLevelC(worldObj, pos.up(3), 5); - pos = new BlockPos(pos.getX(), y, pos.getZ()); - - if(this.worldObj.getBlockState(pos).getMaterial() == Material.LAVA){ + if(this.worldObj.getBlock((int)this.posX, WizardryUtilities.getNearestFloorLevelC(worldObj, (int)this.posX, (int)this.posY + 3, (int)this.posZ, 5) - 1, (int)this.posZ).getMaterial() == Material.lava){ // Fire tornado! this.setFire(5); } @@ -70,7 +64,9 @@ public class EntityTornado extends EntityMagicConstruct { if(this.isValidTarget(target)){ + double velX = target.motionX; double velY = target.motionY; + double velZ = target.motionZ; double dx = this.posX-target.posX > 0? 0.5 - (this.posX-target.posX)/8 : -0.5 - (this.posX-target.posX)/8; double dz = this.posZ-target.posZ > 0? 0.5 - (this.posZ-target.posZ)/8 : -0.5 - (this.posZ-target.posZ)/8; @@ -80,7 +76,7 @@ public class EntityTornado extends EntityMagicConstruct { } if(this.getCaster() != null){ - target.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.MAGIC), 1*damageMultiplier); + target.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, getCaster(), DamageType.MAGIC), 1*damageMultiplier); }else{ target.attackEntityFrom(DamageSource.magic, 1*damageMultiplier); } @@ -91,66 +87,62 @@ public class EntityTornado extends EntityMagicConstruct { // Player motion is handled on that player's client so needs packets if(target instanceof EntityPlayerMP){ - ((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target)); + ((EntityPlayerMP)target).playerNetServerHandler.sendPacket(new S12PacketEntityVelocity(target)); } - // The 'Not Again...' achievement - if(target instanceof EntityPig && WizardryUtilities.getRider(target) instanceof EntityPlayer){ - ((EntityPlayer)WizardryUtilities.getRider(target)).addStat(WizardryAchievements.pig_tornado); + if(target instanceof EntityPig && target.riddenByEntity instanceof EntityPlayer){ + ((EntityPlayer)target.riddenByEntity).triggerAchievement(Wizardry.pigTornado); } } } }else{ for(int i=1; i<10; i++){ - + float brightness = rand.nextFloat()*0.7f; double yPos = rand.nextDouble()*8; int blockX = (int)this.posX - 2 + this.rand.nextInt(4); int blockZ = (int)this.posZ - 2 + this.rand.nextInt(4); + int blockY = WizardryUtilities.getNearestFloorLevelC(worldObj, blockX, (int)this.posY + 3, blockZ, 5) - 1; - BlockPos pos1 = new BlockPos(blockX, this.posY+3, blockZ); - - int blockY = WizardryUtilities.getNearestFloorLevelC(worldObj, pos1, 5) - 1; - - pos1 = new BlockPos(pos1.getX(), blockY, pos1.getZ()); - - IBlockState block = this.worldObj.getBlockState(pos1); + Block block = this.worldObj.getBlock(blockX, blockY, blockZ); + int metadata = this.worldObj.getBlockMetadata(blockX, blockY, blockZ); // If the block it found was air or something it can't pick up, it makes a best guess based on the biome. if(!canTornadoPickUpBitsOf(block)){ - block = worldObj.getBiome(pos1).topBlock; + block = worldObj.getBiomeGenForCoords(blockX, blockZ).topBlock; + metadata = 0; } - Wizardry.proxy.spawnTornadoParticle(worldObj, this.posX, this.posY + yPos, this.posZ, this.velX, this.velZ, yPos/3 + 0.5d, 100, block, pos1); - Wizardry.proxy.spawnTornadoParticle(worldObj, this.posX, this.posY + yPos, this.posZ, this.velX, this.velZ, yPos/3 + 0.5d, 100, block, pos1); + Wizardry.proxy.spawnTornadoParticle(worldObj, this.posX, this.posY + yPos, this.posZ, this.velX, this.velZ, yPos/3 + 0.5d, 100, block, metadata); + Wizardry.proxy.spawnTornadoParticle(worldObj, this.posX, this.posY + yPos, this.posZ, this.velX, this.velZ, yPos/3 + 0.5d, 100, block, metadata); // Sometimes spawns leaf particles if the block is leaves - if(block.getMaterial() == Material.LEAVES && this.rand.nextInt(3) == 0){ + if(block.getMaterial() == Material.leaves && this.rand.nextInt(3) == 0){ double yPos1 = rand.nextDouble()*8; - Wizardry.proxy.spawnParticle(WizardryParticleType.LEAF, worldObj, this.posX + (rand.nextDouble()*2-1)*(yPos1/3 + 0.5d), this.posY + yPos1, this.posZ + (rand.nextDouble()*2-1)*(yPos1/3 + 0.5d), 0, -0.05, 0, 40 + rand.nextInt(10)); + Wizardry.proxy.spawnParticle(EnumParticleType.LEAF, worldObj, this.posX + (rand.nextDouble()*2-1)*(yPos1/3 + 0.5d), this.posY + yPos1, this.posZ + (rand.nextDouble()*2-1)*(yPos1/3 + 0.5d), 0, -0.05, 0, 40 + rand.nextInt(10)); } // Sometimes spawns snow particles if the block is snow - if(block.getMaterial() == Material.SNOW || block.getMaterial() == Material.CRAFTED_SNOW && this.rand.nextInt(3) == 0){ + if(block.getMaterial() == Material.snow || block.getMaterial() == Material.craftedSnow && this.rand.nextInt(3) == 0){ double yPos1 = rand.nextDouble()*8; - Wizardry.proxy.spawnParticle(WizardryParticleType.SNOW, worldObj, this.posX + (rand.nextDouble()*2-1)*(yPos1/3 + 0.5d), this.posY + yPos1, this.posZ + (rand.nextDouble()*2-1)*(yPos1/3 + 0.5d), 0, -0.02, 0, 40 + rand.nextInt(10)); + Wizardry.proxy.spawnParticle(EnumParticleType.SNOW, worldObj, this.posX + (rand.nextDouble()*2-1)*(yPos1/3 + 0.5d), this.posY + yPos1, this.posZ + (rand.nextDouble()*2-1)*(yPos1/3 + 0.5d), 0, -0.02, 0, 40 + rand.nextInt(10)); } } } } - private static boolean canTornadoPickUpBitsOf(IBlockState block){ + private static boolean canTornadoPickUpBitsOf(Block block){ Material material = block.getMaterial(); - return material == Material.CRAFTED_SNOW - || material == Material.GROUND - || material == Material.GRASS - || material == Material.LAVA - || material == Material.SAND - || material == Material.SNOW - || material == Material.WATER - || material == Material.PLANTS - || material == Material.LEAVES - || material == Material.VINE; + return material == Material.craftedSnow + || material == Material.ground + || material == Material.grass + || material == Material.lava + || material == Material.sand + || material == Material.snow + || material == Material.water + || material == Material.plants + || material == Material.leaves + || material == Material.vine; } @Override diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityAIAttackSpell.java b/src/main/java/electroblob/wizardry/entity/living/EntityAIAttackSpell.java deleted file mode 100644 index d6843a66..00000000 --- a/src/main/java/electroblob/wizardry/entity/living/EntityAIAttackSpell.java +++ /dev/null @@ -1,238 +0,0 @@ -package electroblob.wizardry.entity.living; - -import java.util.ArrayList; -import java.util.List; - -import electroblob.wizardry.event.SpellCastEvent; -import electroblob.wizardry.event.SpellCastEvent.Source; -import electroblob.wizardry.packet.PacketNPCCastSpell; -import electroblob.wizardry.packet.WizardryPacketHandler; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.SpellModifiers; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.ai.EntityAIBase; -import net.minecraft.util.EnumHand; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.common.network.NetworkRegistry.TargetPoint; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; - -/** Entity AI class for use by instances of {@link ISpellCaster}. This deals with pathing, the spell casting itself - * and the attack cooldown. Also provides an automatic implementation of continuous spell casting using the methods - * specified in {@code ISpellCaster}; all the entity class needs to do is implement those methods. */ -public class EntityAIAttackSpell extends EntityAIBase { - - /** The entity the AI instance has been applied to. */ - private final EntityLiving attacker; - /** The entity the AI instance has been applied to, but as an ISpellCaster. */ - private final ISpellCaster caster; - /** The tagret to be attacked. */ - private EntityLivingBase target; - /** Decremented each tick while greater than 0. When a spell is cast, this is set to that spell's cooldown plus - * the base cooldown. */ - private int cooldown; - /** The number of ticks between the entity finding a new target and when it first starts attacking, and also the - * amount that is added to the spell's cooldown between casting spells. */ - private final int baseCooldown; - /** Decremented each tick while greater than 0. When a continuous spell is first cast, this is set to - * the value of {@link EntityAIAttackSpell#continuousSpellDuration}. */ - // I think that in this case this is only necessary on the server side. If any inconsistent behaviour - // occurs, look into syncing this as well. - private int continuousSpellTimer; - /** The number of ticks that continuous spells will be cast for before cooling down. */ - private final int continuousSpellDuration; - /** The speed that the entity should move when attacking. Only used when passed into the navigator. */ - private final double speed; - private int seeTime; - private final float maxAttackDistance; - - /** - * Creates a new spell attack AI with the given parameters. - * @param attacker The entity that that uses this AI. - * @param speed The speed that the entity should move when attacking. Only used when passed into the navigator. - * @param maxDistance The maximum distance the entity should be from its target. - * @param baseCooldown The number of ticks between the entity finding a new target and when it first starts attacking, - * and also the amount that is added to the cooldown of the spell that has just been cast. - * @param continuousSpellDuration The number of ticks that continuous spells will be cast for before cooling down. - */ - public EntityAIAttackSpell(ISpellCaster attacker, double speed, float maxDistance, int baseCooldown, int continuousSpellDuration){ - - this.cooldown = -1; - - if(!(attacker instanceof EntityLiving)){ - throw new IllegalArgumentException("Tried to create an EntityAICastSpell for an entity that isn't an EntityLiving"); - }else{ - this.caster = attacker; - this.attacker = (EntityLiving)attacker; - this.baseCooldown = baseCooldown; - this.continuousSpellDuration = continuousSpellDuration; - this.speed = speed; - this.maxAttackDistance = maxDistance * maxDistance; - this.setMutexBits(3); - } - } - - @Override - public boolean shouldExecute(){ - - EntityLivingBase entitylivingbase = this.attacker.getAttackTarget(); - - if(entitylivingbase == null){ - return false; - }else{ - this.target = entitylivingbase; - return true; - } - } - - @Override - public boolean continueExecuting(){ - return this.shouldExecute() || !this.attacker.getNavigator().noPath(); - } - - @Override - public void resetTask(){ - this.target = null; - this.seeTime = 0; - this.cooldown = -1; - this.setContinuousSpellAndNotify(Spells.none, new SpellModifiers()); - this.continuousSpellTimer = 0; - } - - private void setContinuousSpellAndNotify(Spell spell, SpellModifiers modifiers){ - caster.setContinuousSpell(spell); - WizardryPacketHandler.net.sendToAllAround(new PacketNPCCastSpell.Message(attacker.getEntityId(), - target == null ? -1 : target.getEntityId(), EnumHand.MAIN_HAND, spell.id(), modifiers), - // Particles are usually only visible from 16 blocks away, so 128 is more than far enough. - new TargetPoint(attacker.dimension, attacker.posX, attacker.posY, attacker.posZ, 128)); - } - - @Override - public void updateTask(){ - - // Only executed server side. - - double distanceSq = this.attacker.getDistanceSq(this.target.posX, this.target.getEntityBoundingBox().minY, this.target.posZ); - boolean targetIsVisible = this.attacker.getEntitySenses().canSee(this.target); - - if(targetIsVisible){ - ++this.seeTime; - }else{ - this.seeTime = 0; - } - - if(distanceSq <= (double)this.maxAttackDistance && this.seeTime >= 20){ - this.attacker.getNavigator().clearPathEntity(); - }else{ - this.attacker.getNavigator().tryMoveToEntityLiving(this.target, this.speed); - } - - this.attacker.getLookHelper().setLookPositionWithEntity(this.target, 30.0F, 30.0F); - - if(this.continuousSpellTimer > 0){ - - this.continuousSpellTimer--; - - // If the target goes out of range or out of sight... - if(distanceSq > (double)this.maxAttackDistance || !targetIsVisible - // ...or the spell is cancelled via events... - || MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Tick(attacker, caster.getContinuousSpell(), - caster.getModifiers(), Source.NPC, this.continuousSpellDuration - this.continuousSpellTimer)) - // ...or the spell no longer succeeds... - || !caster.getContinuousSpell().cast(attacker.worldObj, attacker, EnumHand.MAIN_HAND, - this.continuousSpellDuration - this.continuousSpellTimer, target, caster.getModifiers()) - // ...or the time has elapsed... - || this.continuousSpellTimer == 0){ - - // ...reset the continuous spell timer and start the cooldown. - this.continuousSpellTimer = 0; - setContinuousSpellAndNotify(Spells.none, new SpellModifiers()); - this.cooldown = this.baseCooldown; - return; - - }else if(this.continuousSpellDuration - this.continuousSpellTimer == 1){ - // On the first tick, if the spell did succeed, fire SpellCastEvent.Post. - MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(attacker, caster.getContinuousSpell(), - caster.getModifiers(), Source.NPC)); - } - - }else if(--this.cooldown == 0){ - - if(distanceSq > (double)this.maxAttackDistance || !targetIsVisible){ - return; - } - - double dx = target.posX - attacker.posX; - double dz = target.posZ - attacker.posZ; - - List spells = new ArrayList(caster.getSpells()); - - if(spells.size() > 0){ - - if(!attacker.worldObj.isRemote){ - - // New way of choosing a spell; keeps trying until one works or all have been tried - - Spell spell; - - while(!spells.isEmpty()){ - - spell = spells.get(attacker.worldObj.rand.nextInt(spells.size())); - - SpellModifiers modifiers = caster.getModifiers(); - - if(spell != null && attemptCastSpell(spell, modifiers)){ - // The spell worked, so we're done! - attacker.rotationYaw = (float)(Math.atan2(dz, dx) * 180.0D / Math.PI) - 90.0F; - return; - }else{ - spells.remove(spell); - } - } - } - } - - }else if(this.cooldown < 0){ - // This should only be reached when the entity first starts attacking. Stops it attacking instantly. - this.cooldown = this.baseCooldown; - } - } - - /** Attempts to cast the given spell (including event firing) and returns true if it succeeded. */ - private boolean attemptCastSpell(Spell spell, SpellModifiers modifiers){ - - // If anything stops the spell working at this point, nothing else happens. - if(MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Pre(attacker, spell, modifiers, Source.NPC))){ - return false; - } - - if(spell.cast(attacker.worldObj, attacker, EnumHand.MAIN_HAND, 0, target, modifiers)){ - - if(spell.isContinuous){ - // -1 because the spell has been cast once already! - this.continuousSpellTimer = this.continuousSpellDuration - 1; - setContinuousSpellAndNotify(spell, modifiers); - - }else{ - - MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(attacker, spell, modifiers, Source.NPC)); - - // For now, the cooldown is just added to the constant base cooldown. I think this - // is a reasonable way of doing things; it's certainly better than before. - this.cooldown = this.baseCooldown + spell.cooldown; - - if(spell.doesSpellRequirePacket()){ - // Sends a packet to all players in dimension to tell them to spawn particles. - IMessage msg = new PacketNPCCastSpell.Message(attacker.getEntityId(), - target.getEntityId(), EnumHand.MAIN_HAND, spell.id(), modifiers); - WizardryPacketHandler.net.sendToDimension(msg, attacker.worldObj.provider.getDimension()); - } - } - - return true; - } - - return false; - } -} diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityAISelectSpell.java b/src/main/java/electroblob/wizardry/entity/living/EntityAISelectSpell.java deleted file mode 100644 index 286dc93c..00000000 --- a/src/main/java/electroblob/wizardry/entity/living/EntityAISelectSpell.java +++ /dev/null @@ -1,14 +0,0 @@ -package electroblob.wizardry.entity.living; - -import net.minecraft.entity.ai.EntityAIBase; - -public class EntityAISelectSpell extends EntityAIBase { - - // TODO: Write this class - - @Override - public boolean shouldExecute(){ - return false; - } - -} diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityBlazeMinion.java b/src/main/java/electroblob/wizardry/entity/living/EntityBlazeMinion.java index 473f30b7..019285d3 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityBlazeMinion.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityBlazeMinion.java @@ -1,160 +1,294 @@ package electroblob.wizardry.entity.living; -import java.lang.ref.WeakReference; -import java.util.UUID; +import java.util.List; -import electroblob.wizardry.Wizardry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.WizardryUtilities; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.EntityAIHurtByTarget; +import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; -import net.minecraft.entity.monster.EntityBlaze; +import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.monster.IMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.entity.projectile.EntitySmallFireball; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; -public class EntityBlazeMinion extends EntityBlaze implements ISummonedCreature { +public class EntityBlazeMinion extends EntitySummonedCreature { + + /** Random offset used in floating behaviour */ + private float heightOffset = 0.5F; - // Field implementations - private int lifetime = 600; - private WeakReference casterReference; - private UUID casterUUID; + /** Ticks until heightOffset is randomized */ + private int heightOffsetUpdateTime; + private int someAttackCounter; - // Setter + getter implementations - @Override public int getLifetime(){ return lifetime; } - @Override public void setLifetime(int lifetime){ this.lifetime = lifetime; } - @Override public WeakReference getCasterReference(){ return casterReference; } - @Override public void setCasterReference(WeakReference reference){ casterReference = reference; } - @Override public UUID getCasterUUID() { return casterUUID; } - @Override public void setCasterUUID(UUID uuid) { this.casterUUID = uuid; } - - /** - * Default shell constructor, only used by client. Lifetime defaults arbitrarily to 600, but this doesn't - * matter because the client side entity immediately gets the lifetime value copied over to it by this class - * anyway. When extending this class, you must override this constructor or Minecraft won't like it, but there's - * no need to do anything inside it other than call super(). - */ public EntityBlazeMinion(World world){ - super(world); - this.experienceValue = 0; - } - - /** - * Set lifetime to -1 to allow this creature to last forever. This constructor should be overridden when - * extending this class (be sure to call super()) so that AI and other things can be added. - */ - public EntityBlazeMinion(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ - super(world); - this.setPosition(x, y, z); - this.casterReference = new WeakReference(caster); - this.experienceValue = 0; - this.lifetime = lifetime; - } - - // EntityBlaze overrides - - // This particular override is pretty standard: let the superclass handle basic AI like swimming, but replace its - // targeting system with one that targets hostile mobs and takes the ADS into account. - @Override - protected void initEntityAI() - { - super.initEntityAI(); - this.targetTasks.taskEntries.clear(); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, - 0, false, true, this.getTargetSelector())); + super(world); } - // Implementations + public EntityBlazeMinion(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ + + super(world, x, y, z, caster, lifetime); + this.isImmuneToFire = true; + // Don't know why these are here; the blaze minion uses the old AI system. + this.tasks.addTask(1, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(2, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 0, false, true, IMob.mobSelector)); + this.experienceValue = 0; + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() + { + return false; + } @Override - public void setRevengeTarget(EntityLivingBase entity){ - if(this.shouldRevengeTarget(entity)) super.setRevengeTarget(entity); - } - - @Override - public void onUpdate(){ - super.onUpdate(); - this.updateDelegate(); - } - - @Override - public void onSpawn(){ - this.spawnParticleEffect(); - } - - @Override - public void onDespawn(){ - this.spawnParticleEffect(); - } - - /** Normally this would be private, but since this class has subclasses with different spawn/despawn particle - * effects, it makes sense to have them override this rather than both onSpawn() and onDespawn(). */ - protected void spawnParticleEffect(){ - if(this.worldObj.isRemote){ - for(int i=0;i<15;i++){ - this.worldObj.spawnParticle(EnumParticleTypes.FLAME, this.posX + this.rand.nextFloat(), this.posY + 1 + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0, 0, 0); - } - } - } - - @Override - public boolean hasParticleEffect() { - return false; - } - - @Override - protected boolean processInteract(EntityPlayer player, EnumHand hand, ItemStack stack) { - // In this case, the delegate method determines whether super is called. - // Rather handily, we can make use of Java's 'stop as soon as you find true' method of evaluating OR statements. - return this.interactDelegate(player, hand, stack) || super.processInteract(player, hand, stack); - } - - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound){ - super.writeEntityToNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound){ - super.readEntityFromNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } - - // Recommended overrides - - @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; } - // This vanilla method has nothing to do with the custom despawn() method. - @Override protected boolean canDespawn(){ return false; } - - @Override - public boolean canAttackClass(Class entityType){ + public boolean hasRangedAttack() { return true; } - @Override - public ITextComponent getDisplayName(){ - if(getCaster() != null){ - return new TextComponentTranslation(NAMEPLATE_TRANSLATION_KEY, getCaster().getName(), - new TextComponentTranslation("entity." + this.getEntityString() + ".name")); - }else{ - return super.getDisplayName(); - } + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(6.0D); + this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(16.0D); + } + + protected void entityInit() + { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte)0)); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() + { + return "mob.blaze.breathe"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() + { + return "mob.blaze.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() + { + return "mob.blaze.death"; + } + + @SideOnly(Side.CLIENT) + public int getBrightnessForRender(float par1) + { + return 15728880; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) + { + return 1.0F; + } + + @Override + public void onSpawn(){ + if(this.worldObj.isRemote){ + for(int i=0;i<15;i++){ + this.worldObj.spawnParticle("flame", this.posX + this.rand.nextFloat(), this.posY + 1 + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0, 0, 0); + } + } + } + + @Override + public void despawn(){ + if(this.worldObj.isRemote){ + for(int i=0;i<15;i++){ + this.worldObj.spawnParticle("flame", this.posX + this.rand.nextFloat(), this.posY + 1 + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0, 0, 0); + } + } + super.despawn(); } - @Override - public boolean hasCustomName(){ - // If this returns true, the renderer will show the nameplate when looking directly at the entity - return Wizardry.settings.showSummonedCreatureNames && getCaster() != null; - } + /** + * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons + * use this to react to sunlight and start to burn. + */ + public void onLivingUpdate() + { + if (!this.worldObj.isRemote) + { + if (this.isWet()) + { + this.attackEntityFrom(DamageSource.drown, 1.0F); + } + + --this.heightOffsetUpdateTime; + + if (this.heightOffsetUpdateTime <= 0) + { + this.heightOffsetUpdateTime = 100; + this.heightOffset = 0.5F + (float)this.rand.nextGaussian() * 3.0F; + } + + if (this.getEntityToAttack() != null && this.getEntityToAttack().posY + (double)this.getEntityToAttack().getEyeHeight() > this.posY + (double)this.getEyeHeight() + (double)this.heightOffset) + { + this.motionY += (0.30000001192092896D - this.motionY) * 0.30000001192092896D; + } + } + + if (this.rand.nextInt(24) == 0) + { + this.worldObj.playSoundEffect(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, "fire.fire", 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F); + } + + if (!this.onGround && this.motionY < 0.0D) + { + this.motionY *= 0.6D; + } + + for (int i = 0; i < 2; ++i) + { + this.worldObj.spawnParticle("largesmoke", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.0D, 0.0D, 0.0D); + } + + super.onLivingUpdate(); + } + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) + { + if (this.attackTime <= 0 && par2 < 2.0F && par1Entity.boundingBox.maxY > this.boundingBox.minY && par1Entity.boundingBox.minY < this.boundingBox.maxY) + { + this.attackTime = 20; + this.attackEntityAsMob(par1Entity); + } + else if (par2 < 30.0F) + { + double d0 = par1Entity.posX - this.posX; + double d1 = par1Entity.boundingBox.minY + (double)(par1Entity.height / 2.0F) - (this.posY + (double)(this.height / 2.0F)); + double d2 = par1Entity.posZ - this.posZ; + + if (this.attackTime == 0) + { + ++this.someAttackCounter; + + if (this.someAttackCounter == 1) + { + this.attackTime = 60; + this.func_70844_e(true); + } + else if (this.someAttackCounter <= 4) + { + this.attackTime = 6; + } + else + { + this.attackTime = 100; + this.someAttackCounter = 0; + this.func_70844_e(false); + } + + if (this.someAttackCounter > 1) + { + float f1 = MathHelper.sqrt_float(par2) * 0.5F; + this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1009, (int)this.posX, (int)this.posY, (int)this.posZ, 0); + + for (int i = 0; i < 1; ++i) + { + // Passing in the caster as the shooter of the fireball seems to cause the fireball to + // instantly disappear, so this has been left out for the time being. + EntitySmallFireball entitysmallfireball = new EntitySmallFireball(this.worldObj, this, d0 + this.rand.nextGaussian() * (double)f1, d1, d2 + this.rand.nextGaussian() * (double)f1); + entitysmallfireball.posX = this.posX; + entitysmallfireball.posZ = this.posZ; + entitysmallfireball.posY = this.posY + (double)(this.height / 2.0F) + 0.5D; + this.worldObj.spawnEntityInWorld(entitysmallfireball); + } + } + } + + this.rotationYaw = (float)(Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F; + this.hasAttacked = true; + } + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) {} + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() + { + return -1; + } + + /** + * Returns true if the entity is on fire. Used by render to add the fire effect on rendering. + */ + public boolean isBurning() + { + return this.func_70845_n(); + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param + * par2 - Level of Looting used to kill this mob. + */ + protected void dropFewItems(boolean par1, int par2) + { + + } + + public boolean func_70845_n() + { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + public void func_70844_e(boolean par1) + { + byte b0 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) + { + b0 = (byte)(b0 | 1); + } + else + { + b0 &= -2; + } + + this.dataWatcher.updateObject(16, Byte.valueOf(b0)); + } + + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() + { + return true; + } } diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityDecoy.java b/src/main/java/electroblob/wizardry/entity/living/EntityDecoy.java index f4d9a423..0727ade8 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityDecoy.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityDecoy.java @@ -1,19 +1,28 @@ package electroblob.wizardry.entity.living; -import java.lang.ref.WeakReference; +import java.util.UUID; +import cpw.mods.fml.common.network.ByteBufUtils; +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.util.WizardryParticleType; +import electroblob.wizardry.WizardryUtilities; import io.netty.buffer.ByteBuf; +import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIControlledByPlayer; +import net.minecraft.entity.ai.EntityAIFollowParent; import net.minecraft.entity.ai.EntityAILookIdle; +import net.minecraft.entity.ai.EntityAIMate; +import net.minecraft.entity.ai.EntityAIPanic; import net.minecraft.entity.ai.EntityAISwimming; +import net.minecraft.entity.ai.EntityAITempt; import net.minecraft.entity.ai.EntityAIWander; import net.minecraft.entity.ai.EntityAIWatchClosest; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.DamageSource; -import net.minecraft.util.text.ITextComponent; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; public class EntityDecoy extends EntitySummonedCreature { @@ -24,66 +33,54 @@ public class EntityDecoy extends EntitySummonedCreature { public EntityDecoy(World world, double x, double y, double z, EntityLivingBase caster, int lifetime) { super(world, x, y, z, caster, lifetime); - this.setAlwaysRenderNameTag(caster instanceof EntityPlayer); - } - - @Override - protected void initEntityAI() { // Decoys just wander around aimlessly, watching anything living. this.tasks.addTask(0, new EntityAISwimming(this)); this.tasks.addTask(1, new EntityAIWander(this, 1.0D)); this.tasks.addTask(2, new EntityAIWatchClosest(this, EntityLivingBase.class, 6.0F)); this.tasks.addTask(3, new EntityAILookIdle(this)); + this.setAlwaysRenderNameTag(caster instanceof EntityPlayer); } @Override - public void onDespawn(){ - super.onDespawn(); + public void despawn(){ + super.despawn(); for(int i=0; i<20; i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.DUST, worldObj, this.posX + (this.rand.nextDouble()-0.5)*this.width, - this.getEntityBoundingBox().minY + this.rand.nextDouble()*this.height, this.posZ + (this.rand.nextDouble()-0.5)*this.width, + Wizardry.proxy.spawnParticle(EnumParticleType.DUST, worldObj, this.posX + (this.rand.nextDouble()-0.5)*this.width, + this.boundingBox.minY + this.rand.nextDouble()*this.height, this.posZ + (this.rand.nextDouble()-0.5)*this.width, 0, 0, 0, 40, 0.2f, 1.0f, 0.8f); } } @Override - public boolean isEntityInvulnerable(DamageSource source){ + public boolean isEntityInvulnerable() { return true; } @Override - public boolean isSneaking(){ - return false; + public ItemStack getHeldItem() { + if(this.getCaster() instanceof EntityPlayer || this.getCaster() == null) return super.getHeldItem(); + // Tricks the renderer into rendering the decoy's arm in the right place. + return this.getCaster().getHeldItem(); } @Override public void onUpdate() { super.onUpdate(); if(this.getCaster() == null || this.getCaster().isDead){ - this.setDead(); - this.onDespawn(); + this.despawn(); } } + @Override + protected boolean isAIEnabled(){ + return true; + } + @Override protected void applyEntityAttributes() { super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.25D); - } - - @Override - public ITextComponent getDisplayName(){ - if(getCaster() instanceof EntityPlayer){ - return this.getCaster().getDisplayName(); - }else{ - return super.getDisplayName(); - } - } - - @Override - public boolean hasCustomName(){ - return getCaster() instanceof EntityPlayer; + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D); } @Override @@ -101,7 +98,7 @@ public class EntityDecoy extends EntitySummonedCreature { public void readSpawnData(ByteBuf data){ super.readSpawnData(data); if(!data.isReadable()) return; - this.setCasterReference(new WeakReference((EntityLivingBase)this.worldObj.getEntityByID(data.readInt()))); + this.setCaster((EntityLivingBase)this.worldObj.getEntityByID(data.readInt())); } } diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityEvilWizard.java b/src/main/java/electroblob/wizardry/entity/living/EntityEvilWizard.java index a6fe6eb5..bcf44643 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityEvilWizard.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityEvilWizard.java @@ -1,122 +1,114 @@ package electroblob.wizardry.entity.living; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Locale; -import com.google.common.base.Predicate; - +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.WizardryRegistry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.item.ItemSpellBook; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.registry.WizardryAchievements; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; +import electroblob.wizardry.packet.PacketCastSpell; +import electroblob.wizardry.packet.WizardryPacketHandler; import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; import io.netty.buffer.ByteBuf; +import net.minecraft.command.IEntitySelector; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityAgeable; import net.minecraft.entity.EntityList; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.IRangedAttackMob; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIArrowAttack; 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.monster.EntityMob; +import net.minecraft.entity.monster.IMob; +import net.minecraft.entity.passive.EntityVillager; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; -import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagInt; -import net.minecraft.network.datasync.DataParameter; -import net.minecraft.network.datasync.DataSerializers; -import net.minecraft.network.datasync.EntityDataManager; -import net.minecraft.pathfinding.PathNavigateGround; +import net.minecraft.nbt.NBTTagIntArray; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumHand; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.SoundEvent; -import net.minecraft.world.DifficultyInstance; +import net.minecraft.village.MerchantRecipe; +import net.minecraft.village.MerchantRecipeList; import net.minecraft.world.World; import net.minecraftforge.common.util.Constants.NBT; -import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; +import net.minecraftforge.oredict.OreDictionary; -public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntityAdditionalSpawnData { - - private EntityAIAttackSpell spellCastingAI = new EntityAIAttackSpell(this, 0.5D, 14.0F, 30, 50); +public class EntityEvilWizard extends EntityMob implements IRangedAttackMob, IEntityAdditionalSpawnData { + + private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 0.5D, 20, 50, 14.0F); public int textureIndex = 0; - + public boolean hasTower = false; + + /** The entity selector passed into the new AI methods. */ + protected IEntitySelector targetSelector; + + /** Index for the heal cooldown field in the datawatcher */ + private static final int healCooldownIndex = 20; + /** Index for the element field in the datawatcher */ + private static final int elementIndex = 16; + + private int[] spells = new int[4]; - /** The entity selector passed into the new AI methods. */ - protected Predicate targetSelector; + public EntityEvilWizard(World par1World) + { + super(par1World); + this.setSize(0.6F, 1.8F); + this.dataWatcher.addObject(healCooldownIndex, 0); + this.getNavigator().setBreakDoors(true); + this.getNavigator().setAvoidsWater(true); + this.tasks.taskEntries.clear(); + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(4, new EntityAIRestrictOpenDoor(this)); + this.tasks.addTask(5, new EntityAIOpenDoor(this, true)); + this.tasks.addTask(6, new EntityAIMoveTowardsRestriction(this, 0.6D)); + this.tasks.addTask(7, new EntityAIWatchClosest2(this, EntityPlayer.class, 3.0F, 1.0F)); + this.tasks.addTask(7, new EntityAIWander(this, 0.6D)); + + this.targetSelector = new IEntitySelector(){ - /** Data parameter for the cooldown time for wizards healing themselves. */ - private static final DataParameter HEAL_COOLDOWN = EntityDataManager.createKey(EntityEvilWizard.class, DataSerializers.VARINT); - /** Data parameter for the wizard's element. */ - private static final DataParameter ELEMENT = EntityDataManager.createKey(EntityEvilWizard.class, DataSerializers.VARINT); - /** The resource location for the evil wizard's loot table. */ - private static final ResourceLocation LOOT_TABLE = new ResourceLocation(Wizardry.MODID, "entities/evil_wizard"); + public boolean isEntityApplicable(Entity entity){ - // Field implementations - private List spells = new ArrayList(4); - private Spell continuousSpell; - - public EntityEvilWizard(World world){ - - super(world); - this.setSize(0.6F, 1.8F); - ((PathNavigateGround)this.getNavigator()).setBreakDoors(true); - - // For some reason this can't be done in initEntityAI - this.tasks.addTask(3, this.spellCastingAI); - - this.detachHome(); - } - - @Override - protected void entityInit(){ - super.entityInit(); - this.dataManager.register(HEAL_COOLDOWN, -1); - this.dataManager.register(ELEMENT, 0); - } - - @Override - protected void initEntityAI(){ - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(4, new EntityAIRestrictOpenDoor(this)); - this.tasks.addTask(5, new EntityAIOpenDoor(this, true)); - this.tasks.addTask(6, new EntityAIMoveTowardsRestriction(this, 0.6D)); - this.tasks.addTask(7, new EntityAIWatchClosest2(this, EntityPlayer.class, 3.0F, 1.0F)); - this.tasks.addTask(7, new EntityAIWander(this, 0.6D)); - - this.targetSelector = new Predicate(){ - - public boolean apply(Entity entity){ - - // If the target is valid and not invisible... - if(entity != null && !entity.isInvisible() && WizardryUtilities.isValidTarget(EntityEvilWizard.this, entity)){ + // If the target is valid... + if(entity != null && WizardryUtilities.isValidTarget(EntityEvilWizard.this, entity)){ //... and is a player, a summoned creature, another (non-evil) wizard ... - if(entity instanceof EntityPlayer || (entity instanceof ISummonedCreature || entity instanceof EntityWizard + if(entity instanceof EntityPlayer || (entity instanceof EntitySummonedCreature || entity instanceof EntityWizard // ... or in the whitelist ... - || Arrays.asList(Wizardry.settings.summonedCreatureTargetsWhitelist).contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))) + || Arrays.asList(Wizardry.summonedCreatureTargetsWhitelist).contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))) // ... and isn't in the blacklist ... - && !Arrays.asList(Wizardry.settings.summonedCreatureTargetsBlacklist).contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))){ + && !Arrays.asList(Wizardry.summonedCreatureTargetsBlacklist).contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))){ // ... it can be attacked. return true; } @@ -125,231 +117,323 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity return false; } }; - - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(0, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, - 0, false, true, this.targetSelector)); - } + + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(0, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, 0, false, true, this.targetSelector)); + + this.tasks.addTask(3, this.aiArrowAttack); + + this.detachHome(); + } + + protected void entityInit(){ + super.entityInit(); + this.dataWatcher.addObject(16, Integer.valueOf(0)); + } - @Override - protected void applyEntityAttributes() - { - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.5D); - this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(30); - } + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.5D); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30); + } - private int getHealCooldown(){ - return this.dataManager.get(HEAL_COOLDOWN); - } - - private void setHealCooldown(int cooldown){ - this.dataManager.set(HEAL_COOLDOWN, cooldown); - } - - public Element getElement(){ - return Element.values()[this.dataManager.get(ELEMENT)]; - } - - public void setElement(Element element){ - this.dataManager.set(ELEMENT, element.ordinal()); - } - - @Override - public List getSpells(){ - return this.spells; - } - - @Override - public SpellModifiers getModifiers(){ - return new SpellModifiers(); - } - - @Override - public void setContinuousSpell(Spell spell){ - this.continuousSpell = spell; - } - - @Override - public Spell getContinuousSpell(){ - return this.continuousSpell; - } - - @Override - public void onLivingUpdate(){ - - super.onLivingUpdate(); - - int healCooldown = this.getHealCooldown(); - - // This is now done slightly differently because isPotionActive doesn't work on client here, meaning that when - // affected with arcane jammer and healCooldown == 0, whilst the wizard didn't actually heal or play the sound, - // the particles still spawned, and since healCooldown wasn't reset they spawned every tick until the arcane - // jammer wore off. - if(healCooldown == 0 && this.getHealth() < this.getMaxHealth() && this.getHealth() > 0 && !this.isPotionActive(WizardryPotions.arcane_jammer)){ - - // Healer wizards use greater heal. - this.heal(this.getElement() == Element.HEALING ? 8 : 4); - this.setHealCooldown(-1); - - // deathTime == 0 checks the wizard isn't currently dying - }else if(healCooldown == -1 && this.deathTime == 0){ - - // Heal particles + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() + { + return true; + } + + @Override + public void onLivingUpdate(){ + + super.onLivingUpdate(); + + int healCooldown = this.dataWatcher.getWatchableObjectInt(healCooldownIndex); + + // This is now done slightly differently because isPotionActive doesn't work on client here, meaning that when + // affected with arcane jammer and healCooldown == 0, whilst the wizard didn't actually heal or play the sound, + // the particles still spawned, and since healCooldown wasn't reset they spawned every tick until the arcane + // jammer wore off. + if(healCooldown == 0 && this.getHealth() < this.getMaxHealth() && this.getHealth() > 0 && !this.isPotionActive(Wizardry.arcaneJammer)){ + + // Healer wizards use greater heal. + this.heal(this.getElement() == EnumElement.HEALING ? 8 : 4); + this.dataWatcher.updateObject(healCooldownIndex, -1); + + // deathTime == 0 checks the wizard isn't currently dying + }else if(healCooldown == -1 && this.deathTime == 0){ + + // Heal particles if(worldObj.isRemote){ for(int i=0; i<10; i++){ double d0 = (double)((float)this.posX + rand.nextFloat()*2 - 1.0F); // Apparently the client side spawns the particles 1 block higher than it should... hence the - 0.5F. double d1 = (double)((float)this.posY - 0.5F + rand.nextFloat()); double d2 = (double)((float)this.posZ + rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, d0, d1, d2, 0, 0.1F, 0, 48 + rand.nextInt(12), 1.0f, 1.0f, 0.3f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, d0, d1, d2, 0, 0.1F, 0, 48 + rand.nextInt(12), 1.0f, 1.0f, 0.3f); } }else{ - if(this.getHealth() < 10){ - // Wizard heals himself more often if he has low health - this.setHealCooldown(150); - }else{ - this.setHealCooldown(400); - } - - this.playSound(WizardrySounds.SPELL_HEAL, 0.7F, rand.nextFloat() * 0.4F + 1.0F); + if(this.getHealth() < 10){ + // Wizard heals himself more often if he has low health + this.dataWatcher.updateObject(healCooldownIndex, 150); + }else{ + this.dataWatcher.updateObject(healCooldownIndex, 400); + } + + worldObj.playSoundAtEntity(this, "wizardry:heal", 0.7F, rand.nextFloat() * 0.4F + 1.0F); } - } - if(healCooldown > 0){ - this.setHealCooldown(healCooldown - 1); - } + } + if(healCooldown > 0){// && !worldObj.isRemote){ + this.dataWatcher.updateObject(healCooldownIndex, healCooldown-1); + } + } + + @Override + public void attackEntityWithRangedAttack(EntityLivingBase target, float f){ + + if(f < 30.0F && !this.isPotionActive(Wizardry.arcaneJammer)){ + + double d0 = target.posX - this.posX; + double d1 = target.boundingBox.minY + (double)(target.height / 2.0F) - (this.posY + (double)(this.height / 2.0F)); + double d2 = target.posZ - this.posZ; + + if (this.attackTime == 0 && spells.length > 0){ + + if(!this.worldObj.isRemote){ + + // New way of choosing a spell; keeps trying until one works or all have been tried + + List spellsArray = new ArrayList(spells.length); + + for(int i=0; i= 4 && Spell.get(stack.getItemDamage()).canBeCastByNPCs()){ - this.spells.set(rand.nextInt(3)+1, Spell.get(stack.getItemDamage())); - return true; - } - } + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound tagcompound) + { + super.readEntityFromNBT(tagcompound); + this.setElement(EnumElement.values()[tagcompound.getInteger("element")]); + this.textureIndex = tagcompound.getInteger("skin"); + this.spells = tagcompound.getIntArray("spells"); + this.hasTower = tagcompound.getBoolean("hasTower"); + } - return false; - } + /** + * Determines if an entity can be despawned, used on idle far away entities + */ + @Override + protected boolean canDespawn(){ + // Evil wizards can only despawn if they don't have a tower (i.e. if they spawned naturally at night) + return !this.hasTower; + } - @Override - public void writeEntityToNBT(NBTTagCompound nbt){ - super.writeEntityToNBT(nbt); - nbt.setInteger("element", this.getElement().ordinal()); - nbt.setInteger("skin", this.textureIndex); - nbt.setTag("spells", WizardryUtilities.listToNBT(spells, spell -> new NBTTagInt(spell.id()))); - nbt.setBoolean("hasTower", this.hasTower); - } + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() + { + return "mob.villager.no"; + } - @Override - public void readEntityFromNBT(NBTTagCompound nbt){ - super.readEntityFromNBT(nbt); - this.setElement(Element.values()[nbt.getInteger("element")]); - this.textureIndex = nbt.getInteger("skin"); - this.spells = (List) WizardryUtilities.NBTToList(nbt.getTagList("spells", NBT.TAG_INT), - (NBTTagInt tag) -> Spell.get(tag.getInt())); - this.hasTower = nbt.getBoolean("hasTower"); - } + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() + { + return "mob.villager.hit"; + } - @Override - protected boolean canDespawn(){ - // Evil wizards can only despawn if they don't have a tower (i.e. if they spawned naturally at night) - return !this.hasTower; - } - - @Override - protected float getSoundPitch(){ - return (this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F + 0.6F; - } + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() + { + return "mob.villager.death"; + } + + public EnumElement getElement(){ + return EnumElement.values()[this.dataWatcher.getWatchableObjectInt(elementIndex)]; + } + + public void setElement(EnumElement element){ + this.dataWatcher.updateObject(elementIndex, Integer.valueOf(element.ordinal())); + } + + @Override + protected void dropFewItems(boolean hitByPlayer, int lootingLevel){ + // Drops 3-5 crystals without looting bonuses + int j = 3 + this.rand.nextInt(3) + this.rand.nextInt(1 + lootingLevel); - @Override - protected SoundEvent getAmbientSound() { - return SoundEvents.ENTITY_WITCH_AMBIENT; - } + for(int k=0; k 0 && rand.nextInt(100) - lootingLevel < 5) this.entityDropItem(new ItemStack(Wizardry.spellBook, 1, this.spells[1 + rand.nextInt(this.spells.length - 1)]), 0); + } - @Override - protected SoundEvent getHurtSound() - { - return SoundEvents.ENTITY_WITCH_HURT; - } + public void onDeath(DamageSource source){ + + super.onDeath(source); + if(source.getEntity() instanceof EntityPlayer){ + ((EntityPlayer)source.getEntity()).triggerAchievement(Wizardry.defeatEvilWizard); + } + } - @Override - protected SoundEvent getDeathSound() - { - return SoundEvents.ENTITY_WITCH_DEATH; - } - - // Although it *looks* like this is still called, in actual fact the only method that calls it is overridden in - // EntityLiving to use the loot table system instead. This has been kept as a fallback in case the loot table is - // not found. - @Override - protected void dropFewItems(boolean hitByPlayer, int lootingLevel){ - // Drops 3-5 crystals without looting bonuses - int j = 3 + this.rand.nextInt(3) + this.rand.nextInt(1 + lootingLevel); - - for(int k=0; k 0 && rand.nextInt(100) - lootingLevel < 5) this.entityDropItem(new ItemStack(WizardryItems.spell_book, 1, this.spells.get(1 + rand.nextInt(this.spells.size() - 1)).id()), 0); - } - - @Override - protected ResourceLocation getLootTable(){ - return LOOT_TABLE; - } - - @Override - public void onDeath(DamageSource source){ - - super.onDeath(source); - if(source.getEntity() instanceof EntityPlayer){ - ((EntityPlayer)source.getEntity()).addStat(WizardryAchievements.defeat_evil_wizard); - } - } - - @Override - public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData data){ - - data = super.onInitialSpawn(difficulty, data); + public IEntityLivingData onSpawnWithEgg(IEntityLivingData par1EntityLivingData) + { + par1EntityLivingData = super.onSpawnWithEgg(par1EntityLivingData); textureIndex = this.rand.nextInt(6); + + if(rand.nextBoolean()){ + this.setElement(EnumElement.values()[rand.nextInt(EnumElement.values().length - 1) + 1]); + }else{ + this.setElement(EnumElement.MAGIC); + } + + EnumElement e = this.getElement(); + + this.setCurrentItemOrArmor(1, new ItemStack(WizardryUtilities.getArmour(e, 3))); + this.setCurrentItemOrArmor(2, new ItemStack(WizardryUtilities.getArmour(e, 2))); + this.setCurrentItemOrArmor(3, new ItemStack(WizardryUtilities.getArmour(e, 1))); + this.setCurrentItemOrArmor(4, new ItemStack(WizardryUtilities.getArmour(e, 0))); + + // This is the tier of the highest tier spell the wizard has. + EnumTier maxTier = EnumTier.BASIC; + + // Default chance is 0.085f, for reference. + this.setEquipmentDropChance(0, 0.1f); + this.setEquipmentDropChance(1, 0.1f); + this.setEquipmentDropChance(2, 0.1f); + this.setEquipmentDropChance(3, 0.1f); + this.setEquipmentDropChance(4, 0.1f); + + // All wizards know magic missile, even if it is disabled. + spells[0] = WizardryRegistry.magicMissile.id(); + + List npcSpells = Spell.getSpells(Spell.npcSpells); + + for(int i=1; i maxTier.ordinal()) maxTier = tier; + + // Finds all the spells of the chosen tier and element + List list = Spell.getSpells(new Spell.TierElementFilter(tier, element)); + // Keeps only spells which can be cast by NPCs + list.retainAll(npcSpells); + // Removes spells that the wizard already has + for(int j=0; j casterReference; - private UUID casterUUID; - - // Setter + getter implementations - @Override public int getLifetime(){ return lifetime; } - @Override public void setLifetime(int lifetime){ this.lifetime = lifetime; } - @Override public WeakReference getCasterReference(){ return casterReference; } - @Override public void setCasterReference(WeakReference reference){ casterReference = reference; } - @Override public UUID getCasterUUID() { return casterUUID; } - @Override public void setCasterUUID(UUID uuid) { this.casterUUID = uuid; } - - /** - * Default shell constructor, only used by client. Lifetime defaults arbitrarily to 600, but this doesn't - * matter because the client side entity immediately gets the lifetime value copied over to it by this class - * anyway. When extending this class, you must override this constructor or Minecraft won't like it, but there's - * no need to do anything inside it other than call super(). - */ public EntityIceGiant(World world){ - super(world); + super(world); this.setSize(1.4F, 2.9F); - this.experienceValue = 0; - } - - /** - * Set lifetime to -1 to allow this creature to last forever. This constructor should be overridden when - * extending this class (be sure to call super()) so that AI and other things can be added. - */ - public EntityIceGiant(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ - super(world); - this.setSize(1.4F, 2.9F); - this.setPosition(x, y, z); - this.casterReference = new WeakReference(caster); - this.experienceValue = 0; - this.lifetime = lifetime; - } + } - @Override - protected void initEntityAI(){ - this.getNavigator().getNodeProcessor().setCanSwim(false); - this.tasks.addTask(1, new EntityAIAttackMelee(this, 1.0D, true)); + public EntityIceGiant(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ + + super(world, x, y, z, caster, lifetime); + this.setSize(1.4F, 2.9F); + this.getNavigator().setAvoidsWater(true); + this.tasks.addTask(1, new EntityAIAttackOnCollide(this, 1.0D, true)); this.tasks.addTask(2, new EntityAIMoveTowardsTarget(this, 0.9D, 32.0F)); - //this.tasks.addTask(4, new EntityAIMoveTowardsRestriction(this, 1.0D)); - //this.tasks.addTask(5, new EntityAIWander(this, 0.6D)); + this.tasks.addTask(3, new EntityAIMoveThroughVillage(this, 0.6D, true)); + this.tasks.addTask(4, new EntityAIMoveTowardsRestriction(this, 1.0D)); + this.tasks.addTask(5, new EntityAIWander(this, 0.6D)); this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F)); this.tasks.addTask(7, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, - 0, false, true, this.getTargetSelector())); - } - - // EntityIronGolem overrides - - @Override protected void updateAITasks(){} // Disables home-checking - @Override public Village getVillage(){ return null; } - @Override public int getHoldRoseTick(){ return 0; } - - // Implementations - - @Override - public void setRevengeTarget(EntityLivingBase entity){ - if(this.shouldRevengeTarget(entity)) super.setRevengeTarget(entity); - } - - @Override - public void onUpdate(){ - super.onUpdate(); - this.updateDelegate(); - } - - @Override - public void onSpawn(){} - - @Override - public void onDespawn(){ - this.playSound(WizardrySounds.SPELL_FREEZE, 1.0f, 1.0f); - if(this.worldObj.isRemote){ - for(int i=0; i<30; i++){ - float brightness = 0.5f + (rand.nextFloat()/2); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, this.worldObj, this.posX-1 + rand.nextDouble()*2, this.posY+ rand.nextDouble()*3, this.posZ-1 + rand.nextDouble()*2, 0, -0.02, 0, 12 + rand.nextInt(8), brightness, brightness + 0.1f, 1.0f); - } - } - } - - @Override - public void onLivingUpdate(){ - - super.onLivingUpdate(); - - if(this.worldObj.isRemote){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SNOW, this.worldObj, this.posX-1 + rand.nextDouble()*2, this.posY+ rand.nextDouble()*3, this.posZ-1 + rand.nextDouble()*2, 0, -0.02, 0, 40 + rand.nextInt(10)); - } + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, 0, false, true, this.targetSelector)); + this.lifetime = lifetime; } - - @Override - public void onSuccessfulAttack(EntityLivingBase target){ - - target.motionY += 0.2; - target.motionX += this.getLookVec().xCoord*0.2; - target.motionZ += this.getLookVec().xCoord*0.2; - - target.addPotionEffect(new PotionEffect(WizardryPotions.frost, 300, 0)); - - this.applyEnchantments(this, target); - this.playSound(SoundEvents.ENTITY_IRONGOLEM_ATTACK, 1.0F, 1.0F); - } + protected void entityInit() + { + super.entityInit(); + } - @Override - public boolean hasParticleEffect() { + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() + { + return true; + } + + @Override + public boolean hasRangedAttack() { return false; } - @Override - protected boolean processInteract(EntityPlayer player, EnumHand hand, ItemStack stack) { - // In this case, the delegate method determines whether super is called. - // Rather handily, we can make use of Java's short-circuiting method of evaluating OR statements. - return this.interactDelegate(player, hand, stack) || super.processInteract(player, hand, stack); + /** + * main AI tick function, replaces updateEntityActionState + */ + protected void updateAITick() + { + if (--this.homeCheckTimer <= 0) + { + this.homeCheckTimer = 70 + this.rand.nextInt(50); + this.villageObj = this.worldObj.villageCollectionObj.findNearestVillage(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ), 32); + + if (this.villageObj == null) + { + this.detachHome(); + } + else + { + ChunkCoordinates chunkcoordinates = this.villageObj.getCenter(); + this.setHomeArea(chunkcoordinates.posX, chunkcoordinates.posY, chunkcoordinates.posZ, (int)((float)this.villageObj.getVillageRadius() * 0.6F)); + } + } + + super.updateAITick(); + } + + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(100.0D); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D); + } + + /** + * Decrements the entity's air supply when underwater + */ + protected int decreaseAirSupply(int par1) + { + return par1; + } + + protected void collideWithEntity(Entity par1Entity) + { + if (par1Entity instanceof IMob && this.getRNG().nextInt(20) == 0) + { + this.setAttackTarget((EntityLivingBase)par1Entity); + } + + super.collideWithEntity(par1Entity); + } + + @Override + public void despawn(){ + this.playSound("wizardry:freeze", 1.0f, 1.0f); + if(this.worldObj.isRemote){ + for(int i=0; i<30; i++){ + float brightness = 0.5f + (rand.nextFloat()/2); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, this.worldObj, this.posX-1 + rand.nextDouble()*2, this.posY+ rand.nextDouble()*3, this.posZ-1 + rand.nextDouble()*2, 0, -0.02, 0, 12 + rand.nextInt(8), brightness, brightness + 0.1f, 1.0f); + } + } + super.despawn(); } - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound){ - super.writeEntityToNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } + /** + * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons + * use this to react to sunlight and start to burn. + */ + public void onLivingUpdate() + { + super.onLivingUpdate(); + + if(this.worldObj.isRemote){ + Wizardry.proxy.spawnParticle(EnumParticleType.SNOW, this.worldObj, this.posX-1 + rand.nextDouble()*2, this.posY+ rand.nextDouble()*3, this.posZ-1 + rand.nextDouble()*2, 0, -0.02, 0, 40 + rand.nextInt(10)); + } + + if (this.attackTimer > 0) + { + --this.attackTimer; + } + + if (this.motionX * this.motionX + this.motionZ * this.motionZ > 2.500000277905201E-7D && this.rand.nextInt(5) == 0) + { + int i = MathHelper.floor_double(this.posX); + int j = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double)this.yOffset); + int k = MathHelper.floor_double(this.posZ); + Block block = this.worldObj.getBlock(i, j, k); - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound){ - super.readEntityFromNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } + if (block.getMaterial() != Material.air) + { + this.worldObj.spawnParticle("blockcrack_" + Block.getIdFromBlock(block) + "_" + this.worldObj.getBlockMetadata(i, j, k), this.posX + ((double)this.rand.nextFloat() - 0.5D) * (double)this.width, this.boundingBox.minY + 0.1D, this.posZ + ((double)this.rand.nextFloat() - 0.5D) * (double)this.width, 4.0D * ((double)this.rand.nextFloat() - 0.5D), 0.5D, ((double)this.rand.nextFloat() - 0.5D) * 4.0D); + } + } + } - // Recommended overrides + /** + * Returns true if this entity can attack entities of the specified class. + */ + public boolean canAttackClass(Class par1Class) + { + return this.isPlayerCreated() && EntityPlayer.class.isAssignableFrom(par1Class) ? false : super.canAttackClass(par1Class); + } - @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 boolean canPickUpLoot(){ return false; } - // This vanilla method has nothing to do with the custom onDespawn() method. - @Override protected boolean canDespawn(){ return false; } + public boolean attackEntityAsMob(Entity par1Entity){ + + this.attackTimer = 10; + this.worldObj.setEntityState(this, (byte)4); + boolean flag = par1Entity.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getCaster(), DamageType.FROST), (float)(7 + this.rand.nextInt(15))); - @Override - public boolean canAttackClass(Class entityType){ - // Returns true unless the given entity type is a flying entity. - return !EntityFlying.class.isAssignableFrom(entityType); - } + if(flag){ + + par1Entity.motionY += 0.2; + par1Entity.motionX += this.getLookVec().xCoord*0.2; + par1Entity.motionZ += this.getLookVec().xCoord*0.2; + + if(par1Entity instanceof EntityLivingBase){ + ((EntityLivingBase) par1Entity).addPotionEffect(new PotionEffect(Wizardry.frost.id, 300, 0)); + } + } - @Override - public ITextComponent getDisplayName(){ - if(getCaster() != null){ - return new TextComponentTranslation(NAMEPLATE_TRANSLATION_KEY, getCaster().getName(), - new TextComponentTranslation("entity." + this.getEntityString() + ".name")); - }else{ - return super.getDisplayName(); - } - } + this.playSound("step.stone", 1.0F, rand.nextFloat() * 0.2F + 0.9F); + return flag; + } - @Override - public boolean hasCustomName(){ - // If this returns true, the renderer will show the nameplate when looking directly at the entity - return Wizardry.settings.showSummonedCreatureNames && getCaster() != null; - } + @SideOnly(Side.CLIENT) + public void handleHealthUpdate(byte par1) + { + if (par1 == 4) + { + this.attackTimer = 10; + this.playSound("wizardry:ice", 1.0F, rand.nextFloat() * 0.1F + 0.2F); + } + else + { + super.handleHealthUpdate(par1); + } + } + + public Village getVillage() + { + return this.villageObj; + } + + @SideOnly(Side.CLIENT) + public int getAttackTimer() + { + return this.attackTimer; + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() + { + return "none"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() + { + return "step.stone"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() + { + return "wizardry:freeze"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) + { + this.playSound(Blocks.ice.stepSound.soundName, 1.0F, 1.0F); + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param + * par2 - Level of Looting used to kill this mob. + */ + protected void dropFewItems(boolean par1, int par2) + { + + } + + public boolean isPlayerCreated() + { + return true; + } } diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityIceWraith.java b/src/main/java/electroblob/wizardry/entity/living/EntityIceWraith.java index fa89a1d0..9b73d298 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityIceWraith.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityIceWraith.java @@ -1,296 +1,279 @@ package electroblob.wizardry.entity.living; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; +import electroblob.wizardry.entity.projectile.EntityIceShard; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; -import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction; +import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAIWander; -import net.minecraft.entity.ai.EntityAIWatchClosest; -import net.minecraft.entity.monster.EntityBlaze; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; -import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.MathHelper; +import net.minecraft.entity.monster.IMob; import net.minecraft.world.World; -public class EntityIceWraith extends EntityBlazeMinion { +public class EntityIceWraith extends EntitySummonedCreature +{ + /** Random offset used in floating behaviour */ + private float heightOffset = 0.5F; - /** The version from EntityLivingBase is only used in onLivingUpdate, so it can safely be copied. */ - private int jumpTicks; + /** ticks until heightOffset is randomized */ + private int heightOffsetUpdateTime; + private int field_70846_g; public EntityIceWraith(World world){ super(world); } public EntityIceWraith(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ + super(world, x, y, z, caster, lifetime); this.isImmuneToFire = false; + this.tasks.addTask(1, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(2, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 0, false, true, IMob.mobSelector)); + this.experienceValue = 0; } - - @Override - protected void initEntityAI(){ - super.initEntityAI(); - this.tasks.taskEntries.clear(); - this.tasks.addTask(4, new AIIceShardAttack(this)); - this.tasks.addTask(5, new EntityAIMoveTowardsRestriction(this, 1.0D)); - this.tasks.addTask(7, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(8, new EntityAILookIdle(this)); + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() + { + return false; } @Override - protected void spawnParticleEffect() { + public boolean hasRangedAttack() { + return true; + } + + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(6.0D); + this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(16.0D); + } + + protected void entityInit() + { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte)0)); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() + { + return "mob.blaze.breathe"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() + { + return "mob.blaze.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() + { + return "mob.blaze.death"; + } + + @SideOnly(Side.CLIENT) + public int getBrightnessForRender(float par1) + { + return 15728880; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) + { + return 1.0F; + } + + @Override + public void onSpawn(){ if(this.worldObj.isRemote){ for(int i=0;i<15;i++){ float brightness = 0.5f + (rand.nextFloat()/2); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, this.posX - 0.5d + rand.nextDouble(), this.posY + this.height/2 - 0.5d + rand.nextDouble(), this.posZ - 0.5d + rand.nextDouble(), 0, 0.05f, 0, 20 + rand.nextInt(10), brightness, brightness + 0.1f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX - 0.5d + rand.nextDouble(), this.posY + this.height/2 - 0.5d + rand.nextDouble(), this.posZ - 0.5d + rand.nextDouble(), 0, 0.05f, 0, 20 + rand.nextInt(10), brightness, brightness + 0.1f, 1.0f); } } } @Override - public void onLivingUpdate(){ - - if(!this.onGround && this.motionY < 0.0D){ - this.motionY *= 0.6D; - } - - if(this.rand.nextInt(24) == 0){ - this.playSound(WizardrySounds.SPELL_LOOP_WIND, 0.3F + this.rand.nextFloat()/4, this.rand.nextFloat() * 0.7F + 1.4F); - } - + public void despawn(){ if(this.worldObj.isRemote){ - for(int i = 0; i < 2; ++i){ - this.worldObj.spawnParticle(EnumParticleTypes.CLOUD, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.0D, 0.0D, 0.0D); + for(int i=0;i<15;i++){ + float brightness = 0.5f + (rand.nextFloat()/2); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX - 0.5d + rand.nextDouble(), this.posY + this.height/2 - 0.5d + rand.nextDouble(), this.posZ - 0.5d + rand.nextDouble(), 0, 0.05f, 0, 20 + rand.nextInt(10), brightness, brightness + 0.1f, 1.0f); + } + } + super.despawn(); + } + + /** + * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons + * use this to react to sunlight and start to burn. + */ + public void onLivingUpdate() + { + + if (!this.worldObj.isRemote) + { + /* + if (this.isWet()) + { + this.attackEntityFrom(DamageSource.drown, 1.0F); + } + */ + + --this.heightOffsetUpdateTime; + + if (this.heightOffsetUpdateTime <= 0) + { + this.heightOffsetUpdateTime = 100; + this.heightOffset = 0.5F + (float)this.rand.nextGaussian() * 3.0F; + } + + if (this.getEntityToAttack() != null && this.getEntityToAttack().posY + (double)this.getEntityToAttack().getEyeHeight() > this.posY + (double)this.getEyeHeight() + (double)this.heightOffset) + { + this.motionY += (0.30000001192092896D - this.motionY) * 0.30000001192092896D; } } - // Replaces super call. - this.livingBaseUpdate(); - } - - /** Copied from {@link EntityLivingBase#onLivingUpdate()}. The only change is removal of the updateElytra() call - * since that's irrelevant here. In actual fact, neither EntityMob nor EntityLiving has any code in its version - * of this method that is of use. This isn't exactly ideal, but it's the lesser of two evils since the - * alternative is copying the entire EntityBlaze class and its renderer. All to remove one particle effect... */ - // ... demonstrating why critical methods should delegate any non-critical functionality (like particles) to - // separate protected methods. - private void livingBaseUpdate(){ - - if (this.jumpTicks > 0) - { - --this.jumpTicks; - } + if (this.rand.nextInt(24) == 0) + { + this.worldObj.playSoundEffect(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, "wizardry:wind", 0.3F + this.rand.nextFloat()/4, this.rand.nextFloat() * 0.7F + 1.4F); + } - if (this.newPosRotationIncrements > 0 && !this.canPassengerSteer()) - { - double d0 = this.posX + (this.interpTargetX - this.posX) / (double)this.newPosRotationIncrements; - double d1 = this.posY + (this.interpTargetY - this.posY) / (double)this.newPosRotationIncrements; - double d2 = this.posZ + (this.interpTargetZ - this.posZ) / (double)this.newPosRotationIncrements; - double d3 = MathHelper.wrapDegrees(this.interpTargetYaw - (double)this.rotationYaw); - this.rotationYaw = (float)((double)this.rotationYaw + d3 / (double)this.newPosRotationIncrements); - this.rotationPitch = (float)((double)this.rotationPitch + (this.interpTargetPitch - (double)this.rotationPitch) / (double)this.newPosRotationIncrements); - --this.newPosRotationIncrements; - this.setPosition(d0, d1, d2); - this.setRotation(this.rotationYaw, this.rotationPitch); - } - else if (!this.isServerWorld()) - { - this.motionX *= 0.98D; - this.motionY *= 0.98D; - this.motionZ *= 0.98D; - } + if (!this.onGround && this.motionY < 0.0D) + { + this.motionY *= 0.6D; + } - if (Math.abs(this.motionX) < 0.003D) - { - this.motionX = 0.0D; - } + for (int i = 0; i < 2; ++i) + { + this.worldObj.spawnParticle("cloud", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.0D, 0.0D, 0.0D); + } - if (Math.abs(this.motionY) < 0.003D) - { - this.motionY = 0.0D; - } - - if (Math.abs(this.motionZ) < 0.003D) - { - this.motionZ = 0.0D; - } - - this.worldObj.theProfiler.startSection("ai"); - - if (this.isMovementBlocked()) - { - this.isJumping = false; - this.moveStrafing = 0.0F; - this.moveForward = 0.0F; - this.randomYawVelocity = 0.0F; - } - else if (this.isServerWorld()) - { - this.worldObj.theProfiler.startSection("newAi"); - this.updateEntityActionState(); - this.worldObj.theProfiler.endSection(); - } - - this.worldObj.theProfiler.endSection(); - this.worldObj.theProfiler.startSection("jump"); - - if (this.isJumping) - { - if (this.isInWater()) - { - this.handleJumpWater(); - } - else if (this.isInLava()) - { - this.handleJumpLava(); - } - else if (this.onGround && this.jumpTicks == 0) - { - this.jump(); - this.jumpTicks = 10; - } - } - else - { - this.jumpTicks = 0; - } - - this.worldObj.theProfiler.endSection(); - this.worldObj.theProfiler.startSection("travel"); - this.moveStrafing *= 0.98F; - this.moveForward *= 0.98F; - this.randomYawVelocity *= 0.9F; - this.moveEntityWithHeading(this.moveStrafing, this.moveForward); - this.worldObj.theProfiler.endSection(); - this.worldObj.theProfiler.startSection("push"); - this.collideWithNearbyEntities(); - this.worldObj.theProfiler.endSection(); + super.onLivingUpdate(); } - @Override - public boolean attackEntityFrom(DamageSource source, float amount){ - // Removes the damage from being wet that applies to blazes by checking if the mob is actually drowning. - if(source == DamageSource.drown && (this.getAir() > 0 || this.isPotionActive(MobEffects.WATER_BREATHING))){ - // In this case, the ice wraith is not actually drowning, so cancel the damage. - return false; - }else{ - return super.attackEntityFrom(source, amount); + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack. + */ + protected void attackEntity(Entity target, float par2) + { + if (this.attackTime <= 0 && par2 < 2.0F && target.boundingBox.maxY > this.boundingBox.minY && target.boundingBox.minY < this.boundingBox.maxY) + { + this.attackTime = 20; + this.attackEntityAsMob(target); + } + else if (par2 < 30.0F) + { + double d0 = target.posX - this.posX; + double d1 = target.boundingBox.minY + (double)(target.height / 2.0F) - (this.posY + (double)(this.height / 2.0F)); + double d2 = target.posZ - this.posZ; + + if (this.attackTime == 0) + { + ++this.field_70846_g; + + if (this.field_70846_g == 1) + { + this.attackTime = 60; + //this.func_70844_e(true); + } + else if (this.field_70846_g <= 4) + { + this.attackTime = 6; + } + else + { + this.attackTime = 100; + this.field_70846_g = 0; + //this.func_70844_e(false); + } + + if (this.field_70846_g > 1) + { + this.playSound("wizardry:ice", 1.0F, rand.nextFloat() * 0.4F + 1.4F); + + EntityIceShard iceshard = new EntityIceShard(this.worldObj, this, target, 2, 4, 1); + iceshard.setShootingEntity(this.getCaster()); + //iceshard.posY = this.posY + (double)(this.height / 2.0F) + 0.5D; + //iceshard.setShootingEntity(this); + this.worldObj.spawnEntityInWorld(iceshard); + } + } + + this.rotationYaw = (float)(Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F; + this.hasAttacked = true; } } - - @Override - public boolean isBurning(){ - // Uses the datawatcher on both sides because fire is private to Entity (and I'm not using reflection here). - // TESTME: This should work, but there may be some issues with updating, so if it doesn't work, copy the - // version from Entity and use reflection to access the fire field. - return this.getFlag(0); - } - /** Copied straight from EntityBlaze.AIFireballAttack, with the only changes being replacement of fireball - * spawning with a one-liner call to WizardryRegistry.iceShard.cast(...) and the removal of redundant local variables. */ - static class AIIceShardAttack extends EntityAIBase { - - private final EntityBlaze blaze; - private int attackStep; - private int attackTime; + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) {} - public AIIceShardAttack(EntityBlaze blazeIn) - { - this.blaze = blazeIn; - this.setMutexBits(3); - } + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() + { + return -1; + } - /** - * Returns whether the EntityAIBase should begin execution. - */ - public boolean shouldExecute() - { - EntityLivingBase entitylivingbase = this.blaze.getAttackTarget(); - return entitylivingbase != null && entitylivingbase.isEntityAlive(); - } + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param + * par2 - Level of Looting used to kill this mob. + */ + protected void dropFewItems(boolean par1, int par2) + { - /** - * Execute a one shot task or start executing a continuous task - */ - public void startExecuting() - { - this.attackStep = 0; - } + } - /** - * Resets the task - */ - public void resetTask() - { - // This might be called setOnFire, but what it really controls is whether the wraith is in attack mode. - this.blaze.setOnFire(false); - } + public boolean func_70845_n() + { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } - /** - * Updates the task - */ - public void updateTask() - { - --this.attackTime; - EntityLivingBase entitylivingbase = this.blaze.getAttackTarget(); - double d0 = this.blaze.getDistanceSqToEntity(entitylivingbase); + public void func_70844_e(boolean par1) + { + byte b0 = this.dataWatcher.getWatchableObjectByte(16); - if (d0 < 4.0D) - { - if (this.attackTime <= 0) - { - this.attackTime = 20; - this.blaze.attackEntityAsMob(entitylivingbase); - } + if (par1) + { + b0 = (byte)(b0 | 1); + } + else + { + b0 &= -2; + } - this.blaze.getMoveHelper().setMoveTo(entitylivingbase.posX, entitylivingbase.posY, entitylivingbase.posZ, 1.0D); - } - else if (d0 < 256.0D) - { - if (this.attackTime <= 0) - { - ++this.attackStep; + this.dataWatcher.updateObject(16, Byte.valueOf(b0)); + } - if (this.attackStep == 1) - { - this.attackTime = 60; - this.blaze.setOnFire(true); - } - else if (this.attackStep <= 4) - { - this.attackTime = 6; - } - else - { - this.attackTime = 100; - this.attackStep = 0; - this.blaze.setOnFire(false); - } - - if(this.attackStep > 1){ - // Proof, if it were at all needed, of the elegance and versatility of the spell system. - Spells.ice_shard.cast(this.blaze.worldObj, this.blaze, EnumHand.MAIN_HAND, 0, entitylivingbase, new SpellModifiers()); - // TODO: Decide if an event should be fired here. I'm guessing no. - } - } - - this.blaze.getLookHelper().setLookPositionWithEntity(entitylivingbase, 10.0F, 10.0F); - } - else - { - this.blaze.getNavigator().clearPathEntity(); - this.blaze.getMoveHelper().setMoveTo(entitylivingbase.posX, entitylivingbase.posY, entitylivingbase.posZ, 1.0D); - } - - super.updateTask(); - } - } + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() + { + return true; + } } diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityLightningWraith.java b/src/main/java/electroblob/wizardry/entity/living/EntityLightningWraith.java index d2287d17..3c139bdd 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityLightningWraith.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityLightningWraith.java @@ -1,180 +1,304 @@ package electroblob.wizardry.entity.living; +import java.util.List; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; +import electroblob.wizardry.entity.EntityArc; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.ai.EntityAIBase; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; -import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction; +import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAIWander; -import net.minecraft.entity.ai.EntityAIWatchClosest; -import net.minecraft.entity.monster.EntityBlaze; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; +import net.minecraft.entity.monster.EntityCreeper; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.monster.IMob; import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumHand; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; -public class EntityLightningWraith extends EntityBlazeMinion { +public class EntityLightningWraith extends EntitySummonedCreature +{ + /** Random offset used in floating behaviour */ + private float heightOffset = 0.5F; + + /** ticks until heightOffset is randomized */ + private int heightOffsetUpdateTime; + private int field_70846_g; public EntityLightningWraith(World world){ super(world); } public EntityLightningWraith(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ + super(world, x, y, z, caster, lifetime); this.isImmuneToFire = false; + this.tasks.addTask(1, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(2, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 0, false, true, IMob.mobSelector)); + this.experienceValue = 0; } - - @Override - protected void initEntityAI(){ - super.initEntityAI(); - this.tasks.taskEntries.clear(); - this.tasks.addTask(4, new AILightningAttack(this)); - this.tasks.addTask(5, new EntityAIMoveTowardsRestriction(this, 1.0D)); - this.tasks.addTask(7, new EntityAIWander(this, 1.0D)); - this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); - this.tasks.addTask(8, new EntityAILookIdle(this)); + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() + { + return false; } @Override - protected void spawnParticleEffect(){ + public boolean hasRangedAttack() { + return true; + } + + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(6.0D); + this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(16.0D); + } + + protected void entityInit() + { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte)0)); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() + { + return "mob.blaze.breathe"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() + { + return "mob.blaze.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() + { + return "mob.blaze.death"; + } + + @SideOnly(Side.CLIENT) + public int getBrightnessForRender(float par1) + { + return 15728880; + } + + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) + { + return 1.0F; + } + + @Override + public void onSpawn(){ if(this.worldObj.isRemote){ for(int i=0;i<15;i++){ float brightness = 0.3f + (rand.nextFloat()/2); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, this.posX - 0.5d + rand.nextDouble(), this.posY + this.height/2 - 0.5d + rand.nextDouble(), this.posZ - 0.5d + rand.nextDouble(), 0, 0.05f, 0, 20 + rand.nextInt(10), brightness, brightness + 0.2f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX - 0.5d + rand.nextDouble(), this.posY + this.height/2 - 0.5d + rand.nextDouble(), this.posZ - 0.5d + rand.nextDouble(), 0, 0.05f, 0, 20 + rand.nextInt(10), brightness, brightness + 0.2f, 1.0f); } } } @Override - public void onLivingUpdate(){ - // Fortunately, lightning wraiths don't replace any of blazes' particle effects or the fire sound, they only - // add the sparks, so it's fine to call super here. - if(worldObj.isRemote){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, worldObj, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0, 0, 3); + public void despawn(){ + if(this.worldObj.isRemote){ + for(int i=0;i<15;i++){ + float brightness = 0.3f + (rand.nextFloat()/2); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX - 0.5d + rand.nextDouble(), this.posY + this.height/2 - 0.5d + rand.nextDouble(), this.posZ - 0.5d + rand.nextDouble(), 0, 0.05f, 0, 20 + rand.nextInt(10), brightness, brightness + 0.2f, 1.0f); + } } + super.despawn(); + } + + /** + * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons + * use this to react to sunlight and start to burn. + */ + public void onLivingUpdate() + { + + if (!this.worldObj.isRemote) + { + /* + if (this.isWet()) + { + this.attackEntityFrom(DamageSource.drown, 1.0F); + } + */ + + --this.heightOffsetUpdateTime; + + if (this.heightOffsetUpdateTime <= 0) + { + this.heightOffsetUpdateTime = 100; + this.heightOffset = 0.5F + (float)this.rand.nextGaussian() * 3.0F; + } + + if (this.getEntityToAttack() != null && this.getEntityToAttack().posY + (double)this.getEntityToAttack().getEyeHeight() > this.posY + (double)this.getEyeHeight() + (double)this.heightOffset) + { + this.motionY += (0.30000001192092896D - this.motionY) * 0.30000001192092896D; + } + } + + if (this.rand.nextInt(24) == 0) + { + this.worldObj.playSoundEffect(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, "fire.fire", 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F); + } + + if (!this.onGround && this.motionY < 0.0D) + { + this.motionY *= 0.6D; + } + + if(worldObj.isRemote){ + for (int i = 0; i < 2; ++i) + { + this.worldObj.spawnParticle("largesmoke", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.0D, 0.0D, 0.0D); + } + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0, 0, 3); + } + super.onLivingUpdate(); } - - @Override - public boolean attackEntityFrom(DamageSource source, float amount){ - // Removes the damage from being wet that applies to blazes by checking if the mob is actually drowning. - if(source == DamageSource.drown && (this.getAir() > 0 || this.isPotionActive(MobEffects.WATER_BREATHING))){ - // In this case, the lightning wraith is not actually drowning, so cancel the damage. - return false; - }else{ - return super.attackEntityFrom(source, amount); + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack. + */ + protected void attackEntity(Entity target, float par2) + { + if (this.attackTime <= 0 && par2 < 2.0F && target.boundingBox.maxY > this.boundingBox.minY && target.boundingBox.minY < this.boundingBox.maxY) + { + this.attackTime = 20; + this.attackEntityAsMob(target); + } + + // Added a range limit. + else if (par2 < 30.0F && this.getDistanceToEntity(target) < 16.0d) + { + double d0 = target.posX - this.posX; + double d1 = target.boundingBox.minY + (double)(target.height / 2.0F) - (this.posY + (double)(this.height / 2.0F)); + double d2 = target.posZ - this.posZ; + + if (this.attackTime == 0) + { + ++this.field_70846_g; + + if (this.field_70846_g == 1) + { + this.attackTime = 60; + //this.func_70844_e(true); + } + else if (this.field_70846_g <= 4) + { + this.attackTime = 6; + } + else + { + this.attackTime = 100; + this.field_70846_g = 0; + //this.func_70844_e(false); + } + + if (this.field_70846_g > 1) + { + float f1 = MathHelper.sqrt_float(par2) * 0.5F; + worldObj.playSoundAtEntity(target, "wizardry:arc", 1.0F, rand.nextFloat() * 0.4F + 1.5F); + + if(!worldObj.isRemote){ + + EntityArc arc = new EntityArc(this.worldObj); + arc.setEndpointCoords(this.posX, this.posY + (double)(this.height / 2.0F) + 0.5D, this.posZ, target.posX, target.posY + target.height/2, target.posZ); + this.worldObj.spawnEntityInWorld(arc); + + target.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getCaster(), DamageType.SHOCK), 5.0f); + + }else{ + // Particle effect + for(int j=0;j<8;j++){ + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, target.posX + rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(target) + target.height*rand.nextFloat(), target.posZ + rand.nextFloat() - 0.5, 0, 0, 0, 3); + worldObj.spawnParticle("largesmoke", target.posX + rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(target) + target.height*rand.nextFloat(), target.posZ + rand.nextFloat() - 0.5, 0, 0, 0); + } + } + } + } + + this.rotationYaw = (float)(Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F; + this.hasAttacked = true; } } - - @Override - public boolean isBurning(){ - // Uses the datawatcher on both sides because fire is private to Entity (and I'm not using reflection here). - // TESTME: This should work, but there may be some issues with updating, so if it doesn't work, copy the - // version from Entity and use reflection to access the fire field. - return this.getFlag(0); - } - - /** Copied straight from EntityBlaze.AIFireballAttack, with the only changes being replacement of fireball - * spawning with a one-liner call to WizardryRegistry.arc.cast(...) and the removal of redundant local variables. */ - static class AILightningAttack extends EntityAIBase { - - private final EntityBlaze blaze; - private int attackStep; - private int attackTime; - public AILightningAttack(EntityBlaze blazeIn) - { - this.blaze = blazeIn; - this.setMutexBits(3); - } + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) {} - /** - * Returns whether the EntityAIBase should begin execution. - */ - public boolean shouldExecute() - { - EntityLivingBase entitylivingbase = this.blaze.getAttackTarget(); - return entitylivingbase != null && entitylivingbase.isEntityAlive(); - } + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() + { + return -1; + } - /** - * Execute a one shot task or start executing a continuous task - */ - public void startExecuting() - { - this.attackStep = 0; - } + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param + * par2 - Level of Looting used to kill this mob. + */ + protected void dropFewItems(boolean par1, int par2) + { - /** - * Resets the task - */ - public void resetTask() - { - // This might be called setOnFire, but what it really controls is whether the wraith is in attack mode. - this.blaze.setOnFire(false); - } + } - /** - * Updates the task - */ - public void updateTask() - { - --this.attackTime; - EntityLivingBase entitylivingbase = this.blaze.getAttackTarget(); - double d0 = this.blaze.getDistanceSqToEntity(entitylivingbase); + public boolean func_70845_n() + { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } - if (d0 < 4.0D) - { - if (this.attackTime <= 0) - { - this.attackTime = 20; - this.blaze.attackEntityAsMob(entitylivingbase); - } + public void func_70844_e(boolean par1) + { + byte b0 = this.dataWatcher.getWatchableObjectByte(16); - this.blaze.getMoveHelper().setMoveTo(entitylivingbase.posX, entitylivingbase.posY, entitylivingbase.posZ, 1.0D); - } - else if (d0 < 256.0D) - { - if (this.attackTime <= 0) - { - ++this.attackStep; + if (par1) + { + b0 = (byte)(b0 | 1); + } + else + { + b0 &= -2; + } - if (this.attackStep == 1) - { - this.attackTime = 60; - this.blaze.setOnFire(true); - } - else if (this.attackStep <= 4) - { - this.attackTime = 6; - } - else - { - this.attackTime = 100; - this.attackStep = 0; - this.blaze.setOnFire(false); - } + this.dataWatcher.updateObject(16, Byte.valueOf(b0)); + } - if(this.attackStep > 1){ - // Proof, if it were at all needed, of the elegance and versatility of the spell system. - Spells.arc.cast(this.blaze.worldObj, this.blaze, EnumHand.MAIN_HAND, 0, entitylivingbase, new SpellModifiers()); - // TODO: Decide if an event should be fired here. I'm guessing no. - } - } - - this.blaze.getLookHelper().setLookPositionWithEntity(entitylivingbase, 10.0F, 10.0F); - } - else - { - this.blaze.getNavigator().clearPathEntity(); - this.blaze.getMoveHelper().setMoveTo(entitylivingbase.posX, entitylivingbase.posY, entitylivingbase.posZ, 1.0D); - } - - super.updateTask(); - } - } + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() + { + return true; + } } diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityMagicSlime.java b/src/main/java/electroblob/wizardry/entity/living/EntityMagicSlime.java deleted file mode 100644 index c6799fcf..00000000 --- a/src/main/java/electroblob/wizardry/entity/living/EntityMagicSlime.java +++ /dev/null @@ -1,177 +0,0 @@ -package electroblob.wizardry.entity.living; - -import java.lang.ref.WeakReference; -import java.util.UUID; - -import javax.annotation.Nullable; - -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.IEntityLivingData; -import net.minecraft.entity.monster.EntitySlime; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; -import net.minecraft.init.SoundEvents; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.potion.PotionEffect; -import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.DifficultyInstance; -import net.minecraft.world.EnumDifficulty; -import net.minecraft.world.World; - -/** As of Wizardry 1.2, this is now an ISummonedCreature like the rest of them, and it extends EntitySlime. */ -public class EntityMagicSlime extends EntitySlime implements ISummonedCreature { - - // Field implementations - private int lifetime = 200; - private WeakReference casterReference; - private UUID casterUUID; - - // Setter + getter implementations - @Override public int getLifetime(){ return lifetime; } - @Override public void setLifetime(int lifetime){ this.lifetime = lifetime; } - @Override public WeakReference getCasterReference(){ return casterReference; } - @Override public void setCasterReference(WeakReference reference){ casterReference = reference; } - @Override public UUID getCasterUUID() { return casterUUID; } - @Override public void setCasterUUID(UUID uuid) { this.casterUUID = uuid; } - - public EntityMagicSlime(World world){ - super(world); - this.setSlimeSize(2); // Needs to be called before setting the experience value to 0 - this.experienceValue = 0; - } - - /** - * Creates a new magic slime with the given caster and lifetime, riding the given target. - * @param world The world that the slime is in. - * @param caster The entity that created the slime. - * @param target The slime's victim. The slime will automatically start riding this entity. - * @param lifetime The number of ticks before the slime bursts. - */ - public EntityMagicSlime(World world, EntityLivingBase caster, EntityLivingBase target, int lifetime){ - super(world); - this.setPosition(target.posX, target.posY, target.posZ); - this.startRiding(target); - this.casterReference = new WeakReference(caster); - this.setSlimeSize(2); // Needs to be called before setting the experience value to 0 - this.experienceValue = 0; - this.lifetime = lifetime; - } - - // EntitySlime overrides - - @Override - protected void initEntityAI(){} // Has no AI! - - @Override - protected void dealDamage(EntityLivingBase entity){} // Handles damage itself - - @Override - public void setDead(){ - // Restores behaviour from Entity, replacing slime splitting behaviour. - this.isDead = true; - // Makes sure that the undoing in onUpdate won't undo this. For some reason, EntitySlime sets isDead directly - // to do the peaceful despawning, which seems odd but is actually rather handy! - this.setHealth(0); - // Bursting effect - for(int i=0; i<30; i++){ - double x = this.posX - 0.5 + rand.nextDouble(); - double y = this.posY - 0.5 + rand.nextDouble(); - double z = this.posZ - 0.5 + rand.nextDouble(); - this.worldObj.spawnParticle(EnumParticleTypes.SLIME, x, y, z, (x - this.posX)*2, (y - this.posY)*2, (z - this.posZ)*2); - } - this.playSound(SoundEvents.ENTITY_SLIME_ATTACK, 2.5f, 0.6f); - this.playSound(SoundEvents.ENTITY_FIREWORK_BLAST_FAR, 1.0f, 0.5f); - } - - @Override - public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata){ - // Removes size randomisation - IEntityLivingData data = super.onInitialSpawn(difficulty, livingdata); - this.setSlimeSize(2); - return data; - } - - @Override - public boolean attackEntityFrom(DamageSource source, float amount){ - // Immune to suffocation - return source == DamageSource.inWall ? false : super.attackEntityFrom(source, amount); - } - - // Implementations - - @Override - public void setRevengeTarget(EntityLivingBase entity){ - if(this.shouldRevengeTarget(entity)) super.setRevengeTarget(entity); - } - - @Override - public void onUpdate(){ - - super.onUpdate(); - // Undoes the despawning on peaceful behaviour. I don't think there's anything in super.onUpdate that sets - // isDead other than that, but it's better to do a quick sanity check just to be sure. - if(this.isDead && worldObj.getDifficulty() == EnumDifficulty.PEACEFUL && this.getHealth() > 0) this.isDead = false; - // Bursts instantly rather than doing the falling over animation. - if(this.getHealth() <= 0) this.setDead(); - - this.updateDelegate(); - - // Damages and slows the slime's victim or makes the slime explode if the victim is dead. - if(this.getRidingEntity() != null && this.getRidingEntity() instanceof EntityLivingBase && ((EntityLivingBase)this.getRidingEntity()).getHealth() > 0){ - if(this.ticksExisted % 16 == 1){ - this.getRidingEntity().attackEntityFrom(DamageSource.magic, 1); - ((EntityLivingBase)this.getRidingEntity()).addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, 20, 2)); - this.playSound(SoundEvents.ENTITY_SLIME_ATTACK, 1.0f, 1.0f); - this.squishAmount = 0.5F; - } - }else{ - this.setDead(); - } - } - - @Override - public void onSpawn(){} - - @Override - public void onDespawn(){} - - @Override - public boolean hasParticleEffect() { - return false; - } - - @Override - protected boolean processInteract(EntityPlayer player, EnumHand hand, ItemStack stack) { - // In this case, the delegate method determines whether super is called. - // Rather handily, we can make use of Java's short-circuiting method of evaluating OR statements. - return this.interactDelegate(player, hand, stack) || super.processInteract(player, hand, stack); - } - - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound){ - super.writeEntityToNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound){ - super.readEntityFromNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } - - // Recommended overrides - - @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 boolean canPickUpLoot(){ return false; } - // This vanilla method has nothing to do with the custom onDespawn() method. - @Override protected boolean canDespawn(){ return false; } - -} diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityPhoenix.java b/src/main/java/electroblob/wizardry/entity/living/EntityPhoenix.java index 5d72f26e..8aeb1ff9 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityPhoenix.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityPhoenix.java @@ -1,189 +1,417 @@ package electroblob.wizardry.entity.living; -import java.util.Collections; import java.util.List; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IRangedAttackMob; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIArrowAttack; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAIWatchClosest; -import net.minecraft.init.SoundEvents; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.SoundEvent; -import net.minecraft.util.math.BlockPos; +import net.minecraft.entity.monster.EntityCreeper; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.monster.IMob; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -public class EntityPhoenix extends EntitySummonedCreature implements ISpellCaster { +public class EntityPhoenix extends EntitySummonedCreature implements IRangedAttackMob +{ + /** Random offset used in floating behaviour */ + private float heightOffset = 0.5F; private double AISpeed = 0.5; - // Can attack for 7 seconds, then must cool down for 3. - private EntityAIAttackSpell spellAttackAI = new EntityAIAttackSpell(this, AISpeed, 15f, 60, 140); - - private Spell continuousSpell; - - private static final List attack = Collections.singletonList(Spells.flame_ray); + /** ticks until heightOffset is randomized */ + private int heightOffsetUpdateTime; + private int field_70846_g; + + private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, AISpeed, 1, 1, 15.0F); public EntityPhoenix(World world){ super(world); } public EntityPhoenix(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ + super(world, x, y, z, caster, lifetime); this.isImmuneToFire = true; this.height = 2.0f; - // For some reason this can't be in initEntityAI - this.tasks.addTask(1, this.spellAttackAI); - } - - @Override - protected void initEntityAI(){ - this.tasks.addTask(0, new EntityAIWatchClosest(this, EntityLivingBase.class, 0)); + this.tasks.addTask(1, this.aiArrowAttack); //this.tasks.addTask(2, new EntityAIWander(this, AISpeed)); this.tasks.addTask(3, new EntityAILookIdle(this)); //this.targetTasks.addTask(0, new EntityAIMoveTowardsTarget(this, 1, 10)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, - 0, false, true, this.getTargetSelector())); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, 0, false, true, this.targetSelector)); this.setAIMoveSpeed((float)AISpeed); + + this.experienceValue = 0; + + // Prevents the phoenix from attacking instantly on spawn. + this.attackTime = 60; } - - @Override - public List getSpells(){ - return attack; - } - @Override - public SpellModifiers getModifiers(){ - return new SpellModifiers(); - } - - @Override - public Spell getContinuousSpell(){ - return continuousSpell; - } - - @Override - public void setContinuousSpell(Spell spell){ - continuousSpell = spell; - } + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() + { + return true; + } @Override public boolean hasRangedAttack() { return true; } - - @Override - // Makes the flames come from the phoenix's head rather than its body - public float getEyeHeight(){ - return 2.1f; - } - @Override - protected void applyEntityAttributes(){ + protected void applyEntityAttributes() + { super.applyEntityAttributes(); - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(6.0D); - this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(30.0D); - this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(30.0D); + this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(6.0D); + this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(30.0D); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0D); + //this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(3.0d); + } + + protected void entityInit() + { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte)0)); + this.dataWatcher.addObject(20, new Byte((byte)0)); + this.dataWatcher.addObject(21, new Integer(0)); } - @Override - protected SoundEvent getAmbientSound(){ - return SoundEvents.ENTITY_BLAZE_AMBIENT; + /** + * (Copied from EntityWither) Returns the target entity ID if present, or -1 if not + */ + public int getTargetId() + { + return this.dataWatcher.getWatchableObjectInt(21); } - @Override - protected SoundEvent getHurtSound(){ - return SoundEvents.ENTITY_BLAZE_HURT; + public void setTargetId(int id) + { + this.dataWatcher.updateObject(21, Integer.valueOf(id)); } - @Override - protected SoundEvent getDeathSound(){ - return SoundEvents.ENTITY_BLAZE_DEATH; + /** Retrieves the attacking boolean from the datawatcher. */ + public boolean getIsAttacking() + { + return (this.dataWatcher.getWatchableObjectByte(20) & 1) != 0; + } + + /** Sets the attacking boolean in the datawatcher. */ + public void setAttacking(boolean par1) + { + byte b0 = this.dataWatcher.getWatchableObjectByte(20); + + if (par1) + { + b0 = (byte)(b0 | 1); + } + else + { + b0 &= -2; + } + + this.dataWatcher.updateObject(20, Byte.valueOf(b0)); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() + { + return "mob.blaze.breathe"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() + { + return "mob.blaze.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() + { + return "mob.blaze.death"; } - @Override @SideOnly(Side.CLIENT) - public int getBrightnessForRender(float par1){ + public int getBrightnessForRender(float par1) + { return 15728880; } - @Override - public float getBrightness(float par1){ + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) + { return 1.0F; } @Override public void onSpawn(){ - this.spawnParticleEffect(); - } - - @Override - public void onDespawn(){ - this.spawnParticleEffect(); - } - - private void spawnParticleEffect(){ if(this.worldObj.isRemote){ for(int i=0;i<15;i++){ - this.worldObj.spawnParticle(EnumParticleTypes.FLAME, this.posX + this.rand.nextFloat(), this.posY + 1 + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0, 0, 0); + this.worldObj.spawnParticle("flame", this.posX + this.rand.nextFloat(), this.posY + 1 + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0, 0, 0); } } } - @Override - public void onLivingUpdate(){ - + @Override + public void despawn(){ + if(this.worldObj.isRemote){ + for(int i=0;i<15;i++){ + this.worldObj.spawnParticle("flame", this.posX + this.rand.nextFloat(), this.posY + 1 + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0, 0, 0); + } + } + super.despawn(); + } + + /** + * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons + * use this to react to sunlight and start to burn. + */ + public void onLivingUpdate() + { // Makes the phoenix hover. - int floorLevel = WizardryUtilities.getNearestFloorLevel(worldObj, new BlockPos(this), 4); - - if(this.posY - floorLevel > 3){ + if(this.posY - WizardryUtilities.getNearestFloorLevel(worldObj, (int)this.posX, (int)this.posY, (int)this.posZ, 4) > 3){ this.motionY = -0.1; - }else if(this.posY - floorLevel < 2){ + }else if(this.posY - WizardryUtilities.getNearestFloorLevel(worldObj, (int)this.posX, (int)this.posY, (int)this.posZ, 4) < 2){ this.motionY = 0.1; }else{ this.motionY = 0.0; } // Living sound - if(this.rand.nextInt(24) == 0){ - this.playSound(SoundEvents.BLOCK_FIRE_AMBIENT, 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F); + if (this.rand.nextInt(24) == 0) + { + this.worldObj.playSoundEffect(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, "fire.fire", 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F); } // Flapping sound effect if(this.ticksExisted % 22 == 0){ - this.playSound(SoundEvents.ENTITY_ENDERDRAGON_FLAP, 1.0F, 1.0f); + this.worldObj.playSoundAtEntity(this, "mob.enderdragon.wings", 1.0F, 1.0f); } - for(int i=0; i<2; i++){ - this.worldObj.spawnParticle(EnumParticleTypes.FLAME, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.height/2 + this.rand.nextDouble() * (double)this.height/2, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.0D, -0.1D, 0.0D); + for (int i = 0; i < 2; ++i) + { + this.worldObj.spawnParticle("flame", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.height/2 + this.rand.nextDouble() * (double)this.height/2, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.0D, -0.1D, 0.0D); } + + // Attack particles (flame ray) + if(this.worldObj.isRemote && this.getIsAttacking()){ + + Entity target = this.worldObj.getEntityByID(this.getTargetId()); + + if(target != null){ + + //Vec3 look = this.getLookVec(); + + // This bit does a normalised vector towards the target. + double x = (target.posX - this.posX)/this.getDistanceToEntity(target); //-MathHelper.sin((float)Math.toRadians(this.rotationYawHead)); + double y = ((WizardryUtilities.getEntityFeetPos(target) + target.height/2) - (this.posY + this.getEyeHeight()))/this.getDistanceToEntity(target); //-MathHelper.sin((float)Math.toRadians(this.rotationPitch)); + double z = (target.posZ - this.posZ)/this.getDistanceToEntity(target); //MathHelper.cos((float)Math.toRadians(this.rotationYawHead)); + + for(int i=0; i<20; i++){ + // Starts a little bit forwards so it looks like it comes from the mouth + double x1 = this.posX + this.getLookVec().xCoord*0.7 + x*i/2 + rand.nextFloat()*0.2 - 0.1f; + double y1 = this.posY + 1.75 + y*i/2 + rand.nextFloat()/5 - 0.1f; + double z1 = this.posZ + this.getLookVec().zCoord*0.7 + z*i/2 + rand.nextFloat()*0.2 - 0.1f; + Wizardry.proxy.spawnParticle(EnumParticleType.MAGIC_FIRE, this.worldObj, x1, y1, z1, x, y, z, (int)(2.0D / (Math.random() * 0.8D + 0.2D)), 2, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.MAGIC_FIRE, this.worldObj, x1, y1, z1, x, y, z, (int)(2.0D / (Math.random() * 0.8D + 0.2D)), 2, 0, 0); + } + + } + } + + // 3 second cooldown after target is killed; otherwise it instantly shoots the next one which looks a bit odd. + if(this.getAttackTarget() != null && this.getAttackTarget().deathTime > 0){ + this.attackTime = 60; + } + + // This is set to false after each update so that it only becomes true if attackEntity is called. + if(this.getIsAttacking()) this.setAttacking(false); // Adding this allows the phoenix to attack despite being in the air. However, for some strange reason // it will only attack when within about 3 blocks of the ground. Any higher and it just sits there, not even - // attempting to find targets. + // attempting to find targets. Even weirder, it seems to be aiming a) in a different place to the particles + // and b) not always at the target. Edit: that last bit is fixed for now. this.onGround = true; super.onLivingUpdate(); } - - @Override - public void fall(float distance, float damageMultiplier){} // Immune to fall damage + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack. + */ + protected void attackEntity(Entity target, float par2) + { + this.setAttacking(true); + this.setTargetId(target.getEntityId()); + + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(this.worldObj, this, 10); + + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ + + EntityLivingBase entity = (EntityLivingBase) rayTrace.entityHit; + + if(!MagicDamage.isEntityImmune(DamageType.FIRE, entity)){ + entity.setFire(10); + // This motion stuff removes knockback, which is desirable for continuous spells. + double motionX = entity.motionX; + double motionY = entity.motionY; + double motionZ = entity.motionZ; + + entity.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getCaster(), DamageType.FIRE), 3.0f); + + entity.motionX = motionX; + entity.motionY = motionY; + entity.motionZ = motionZ; + } + } + if(this.ticksExisted % 16 == 0){ + this.worldObj.playSoundAtEntity(this, "wizardry:flameray", 0.5F, 1.0f); + } + } + @Override + public void attackEntityWithRangedAttack(EntityLivingBase entitylivingbase, float f) { + + // Can attack for 7 seconds, then must cool down for 3. + if(this.attackTime > 0 && this.attackTime <= 60) return; + + // I can't get the raytracing method to work at the moment so it auto-aims instead. Not ideal since there is + // essentially no escape, but it is the best I can do. + + // Edit: Then again, it is quite cool! And hey, it's a master spell. + + this.setAttacking(true); + this.attackTime = 200; + this.setTargetId(entitylivingbase.getEntityId()); + + EntityLivingBase entity = entitylivingbase; + + if(!MagicDamage.isEntityImmune(DamageType.FIRE, entity)){ + + entity.setFire(10); + + // This motion stuff removes knockback, which is desirable for continuous spells. + double motionX = entity.motionX; + double motionY = entity.motionY; + double motionZ = entity.motionZ; + + entity.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getCaster(), DamageType.FIRE), 3.0f); + + entity.motionX = motionX; + entity.motionY = motionY; + entity.motionZ = motionZ; + } + + if(this.ticksExisted % 16 == 0){ + this.worldObj.playSoundAtEntity(this, "wizardry:flameray", 0.5F, 1.0f); + } + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity isn't interested in attacking + * (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() + { + List entities = WizardryUtilities.getEntitiesWithinRadius(16, this.posX, this.posY, this.posZ, this.worldObj); + Entity entity = null; + + for(int i=0;i this.getDistanceToEntity((Entity)entities.get(i))){ + // Decides if new entity is a valid target. + if(entities.get(i) instanceof EntityMob && this.canEntityBeSeen((Entity)entities.get(i))){ + entity = (Entity)entities.get(i); + } + } + } + + return entity; + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) {} + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() + { + return -1; + } + + /** + * Returns true if the entity is on fire. Used by render to add the fire effect on rendering. + */ public boolean isBurning() { return false; } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param + * par2 - Level of Looting used to kill this mob. + */ + protected void dropFewItems(boolean par1, int par2) + { + + } + + public boolean func_70845_n() + { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + public void func_70844_e(boolean par1) + { + byte b0 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) + { + b0 = (byte)(b0 | 1); + } + else + { + b0 &= -2; + } + + this.dataWatcher.updateObject(16, Byte.valueOf(b0)); + } + + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() + { + return true; + } } diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityShadowWraith.java b/src/main/java/electroblob/wizardry/entity/living/EntityShadowWraith.java index 000ba391..cf5d524a 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityShadowWraith.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityShadowWraith.java @@ -1,60 +1,57 @@ package electroblob.wizardry.entity.living; -import java.util.Collections; import java.util.List; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.entity.projectile.EntityDarknessOrb; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAIWander; -import net.minecraft.init.MobEffects; -import net.minecraft.init.SoundEvents; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.monster.IMob; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.SoundEvent; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -public class EntityShadowWraith extends EntitySummonedCreature implements ISpellCaster { - - // TODO: This currently doesn't fly like it used to. Should it, or does it not matter? - - private double AISpeed = 1.0; - - private EntityAIAttackSpell spellAttackAI = new EntityAIAttackSpell(this, AISpeed, 15f, 30, 0); - - private static final List attack = Collections.singletonList(Spells.darkness_orb); +public class EntityShadowWraith extends EntitySummonedCreature +{ + /** Random offset used in floating behaviour */ + private float heightOffset = 0.5F; + + /** ticks until heightOffset is randomized */ + private int heightOffsetUpdateTime; + private int field_70846_g; public EntityShadowWraith(World world){ super(world); } public EntityShadowWraith(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ + super(world, x, y, z, caster, lifetime); - // For some reason this can't be in initEntityAI - this.tasks.addTask(0, this.spellAttackAI); - } - - @Override - protected void initEntityAI(){ - - this.tasks.addTask(1, new EntityAIAttackMelee(this, AISpeed, false)); - this.tasks.addTask(2, new EntityAIWander(this, AISpeed)); - this.tasks.addTask(3, new EntityAILookIdle(this)); + this.isImmuneToFire = false; + this.tasks.addTask(1, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(2, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, - 0, false, true, this.getTargetSelector())); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 0, false, true, IMob.mobSelector)); + this.experienceValue = 0; + } - this.setAIMoveSpeed((float)AISpeed); + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() + { + return false; } @Override @@ -62,63 +59,61 @@ public class EntityShadowWraith extends EntitySummonedCreature implements ISpell return true; } - @Override - public List getSpells(){ - return attack; - } - - @Override - public SpellModifiers getModifiers(){ - return new SpellModifiers(); - } - - @Override - public Spell getContinuousSpell(){ - return Spells.none; - } - - @Override - public void setContinuousSpell(Spell spell){ - // Doesn't use continuous spells. - } - - @Override - protected void applyEntityAttributes(){ + protected void applyEntityAttributes() + { super.applyEntityAttributes(); - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(6.0D); - this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(AISpeed); - this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(30.0D); - this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(16.0D); + this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(6.0D); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(3.0d); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0d); + this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(16.0D); } @Override public boolean isPotionApplicable(PotionEffect potion){ - return potion.getPotion() == MobEffects.WITHER ? false : super.isPotionApplicable(potion); + return potion.getPotionID() == Potion.wither.id ? false : super.isPotionApplicable(potion); } - @Override - protected SoundEvent getAmbientSound(){ - return SoundEvents.ENTITY_BLAZE_AMBIENT; - } + protected void entityInit() + { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte)0)); + } - @Override - protected SoundEvent getHurtSound(){ - return SoundEvents.ENTITY_BLAZE_HURT; - } + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() + { + return "mob.blaze.breathe"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() + { + return "mob.blaze.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() + { + return "mob.blaze.death"; + } - @Override - protected SoundEvent getDeathSound(){ - return SoundEvents.ENTITY_BLAZE_DEATH; - } - - @Override @SideOnly(Side.CLIENT) - public int getBrightnessForRender(float partialTicks){ + public int getBrightnessForRender(float par1) + { return 15728880; } - @Override - public float getBrightness(float partialTicks){ + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) + { return 1.0F; } @@ -127,39 +122,148 @@ public class EntityShadowWraith extends EntitySummonedCreature implements ISpell if(this.worldObj.isRemote){ for(int i=0;i<15;i++){ float brightness = rand.nextFloat()*0.4f; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, this.posX - 0.5d + rand.nextDouble(), this.posY + this.height/2 - 0.5d + rand.nextDouble(), this.posZ - 0.5d + rand.nextDouble(), 0, 0.05f, 0, 20 + rand.nextInt(10), brightness, 0.0f, brightness); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX - 0.5d + rand.nextDouble(), this.posY + this.height/2 - 0.5d + rand.nextDouble(), this.posZ - 0.5d + rand.nextDouble(), 0, 0.05f, 0, 20 + rand.nextInt(10), brightness, 0.0f, brightness); } } } - @Override - public void onLivingUpdate(){ + /** + * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons + * use this to react to sunlight and start to burn. + */ + public void onLivingUpdate() + { + if (!this.worldObj.isRemote) + { + /* + if (this.isWet()) + { + this.attackEntityFrom(DamageSource.drown, 1.0F); + } + */ - if(this.rand.nextInt(24) == 0){ - this.playSound(SoundEvents.BLOCK_PORTAL_AMBIENT, 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F); + --this.heightOffsetUpdateTime; + + if (this.heightOffsetUpdateTime <= 0) + { + this.heightOffsetUpdateTime = 100; + this.heightOffset = 0.5F + (float)this.rand.nextGaussian() * 3.0F; + } + + if (this.getEntityToAttack() != null && this.getEntityToAttack().posY + (double)this.getEntityToAttack().getEyeHeight() > this.posY + (double)this.getEyeHeight() + (double)this.heightOffset) + { + this.motionY += (0.30000001192092896D - this.motionY) * 0.30000001192092896D; + } } - // Slow fall - if(!this.onGround && this.motionY < 0.0D){ + if (this.rand.nextInt(24) == 0) + { + this.worldObj.playSoundEffect(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, "portal.portal", 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F); + } + + if (!this.onGround && this.motionY < 0.0D) + { this.motionY *= 0.6D; } if(worldObj.isRemote){ - for(int i=0; i<2; i++){ - worldObj.spawnParticle(EnumParticleTypes.PORTAL, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0, 0); - worldObj.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0, 0); + for (int i = 0; i < 2; ++i) + { + worldObj.spawnParticle("portal", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0, 0); + worldObj.spawnParticle("largesmoke", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0, 0); float brightness = rand.nextFloat()*0.2f; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0.05f, 0, 20 + rand.nextInt(10), brightness, 0.0f, brightness); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, worldObj, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0.05f, 0, 20 + rand.nextInt(10), brightness, 0.0f, brightness); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, worldObj, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); } } super.onLivingUpdate(); } - - @Override - public void fall(float distance, float damageMultiplier){ - // Immune to fall damage. + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) + { + if (this.attackTime <= 0 && par2 < 2.0F && par1Entity.boundingBox.maxY > this.boundingBox.minY && par1Entity.boundingBox.minY < this.boundingBox.maxY) + { + this.attackTime = 20; + this.attackEntityAsMob(par1Entity); + } + else if (par2 < 30.0F) + { + double dx = par1Entity.posX - this.posX; + double dy = par1Entity.boundingBox.minY + (double)(par1Entity.height / 2.0F) - (this.posY + (double)(this.height / 2.0F)); + double dz = par1Entity.posZ - this.posZ; + + if (this.attackTime == 0) + { + this.playSound("mob.wither.shoot", 1.0F, 0.4F / (rand.nextFloat() * 0.4F + 0.8F)); + + EntityDarknessOrb darknessorb = new EntityDarknessOrb(this.worldObj, this.getCaster()); + darknessorb.setPosition(this.posX + this.getLookVec().xCoord, this.posY, this.posZ + this.getLookVec().zCoord); + + darknessorb.directTowards(par1Entity, 0.5f); + + darknessorb.posY = this.posY + (double)(this.height / 2.0F) + 0.5D; + this.worldObj.spawnEntityInWorld(darknessorb); + + this.attackTime = 50; + } + + this.rotationYaw = (float)(Math.atan2(dz, dx) * 180.0D / Math.PI) - 90.0F; + this.hasAttacked = true; + } + } + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) {} + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() + { + return -1; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param + * par2 - Level of Looting used to kill this mob. + */ + protected void dropFewItems(boolean par1, int par2) + { + + } + + public boolean func_70845_n() + { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + public void func_70844_e(boolean par1) + { + byte b0 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) + { + b0 = (byte)(b0 | 1); + } + else + { + b0 &= -2; + } + + this.dataWatcher.updateObject(16, Byte.valueOf(b0)); + } + + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() + { + return true; } - } diff --git a/src/main/java/electroblob/wizardry/entity/living/EntitySilverfishMinion.java b/src/main/java/electroblob/wizardry/entity/living/EntitySilverfishMinion.java index 2a8f237e..eda2251e 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntitySilverfishMinion.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntitySilverfishMinion.java @@ -1,183 +1,268 @@ package electroblob.wizardry.entity.living; -import java.lang.ref.WeakReference; -import java.util.UUID; +import java.util.List; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.util.WizardryParticleType; -import net.minecraft.entity.EntityFlying; +import electroblob.wizardry.WizardryUtilities; +import net.minecraft.block.Block; +import net.minecraft.block.BlockSilverfish; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.ai.EntityAIAttackMelee; -import net.minecraft.entity.ai.EntityAIHurtByTarget; -import net.minecraft.entity.ai.EntityAINearestAttackableTarget; -import net.minecraft.entity.ai.EntityAISwimming; -import net.minecraft.entity.monster.EntitySilverfish; +import net.minecraft.entity.EnumCreatureAttribute; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.monster.EntityMob; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -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.DamageSource; +import net.minecraft.util.EntityDamageSource; +import net.minecraft.util.Facing; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; -public class EntitySilverfishMinion extends EntitySilverfish implements ISummonedCreature { +public class EntitySilverfishMinion extends EntitySummonedCreature +{ + /** A cooldown before this entity will search for another Silverfish to join them in battle. */ + private int allySummonCooldown; + private static final String __OBFID = "CL_00001696"; - // Field implementations - private int lifetime = 600; - private WeakReference casterReference; - private UUID casterUUID; - - // Setter + getter implementations - @Override public int getLifetime(){ return lifetime; } - @Override public void setLifetime(int lifetime){ this.lifetime = lifetime; } - @Override public WeakReference getCasterReference(){ return casterReference; } - @Override public void setCasterReference(WeakReference reference){ casterReference = reference; } - @Override public UUID getCasterUUID() { return casterUUID; } - @Override public void setCasterUUID(UUID uuid) { this.casterUUID = uuid; } - - /** - * Default shell constructor, only used by client. Lifetime defaults arbitrarily to 600, but this doesn't - * matter because the client side entity immediately gets the lifetime value copied over to it by this class - * anyway. When extending this class, you must override this constructor or Minecraft won't like it, but there's - * no need to do anything inside it other than call super(). - */ public EntitySilverfishMinion(World world){ super(world); - this.experienceValue = 0; + } + + public EntitySilverfishMinion(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ + + super(world, x, y, z, caster, lifetime); + this.setSize(0.3F, 0.7F); + } + + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(8.0D); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.6000000238418579D); + this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(1.0D); + this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(8.0D); + } + + @Override + public boolean hasRangedAttack() { + return false; } /** - * Set lifetime to -1 to allow this creature to last forever. This constructor should be overridden when - * extending this class (be sure to call super()) so that AI and other things can be added. + * returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to + * prevent them from trampling crops */ - public EntitySilverfishMinion(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ - super(world); - this.setPosition(x, y, z); - this.casterReference = new WeakReference(caster); - this.experienceValue = 0; - this.lifetime = lifetime; - } - - // EntitySilverfish overrides - @Override - protected void initEntityAI() + protected boolean canTriggerWalking() { - // Super not called because we don't want AISummonSilverfish or AIHideInStone - this.tasks.addTask(1, new EntityAISwimming(this)); - this.tasks.addTask(4, new EntityAIAttackMelee(this, 1.0D, false)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, - 0, false, true, this.getTargetSelector())); - } - - // Implementations - - @Override - public void setRevengeTarget(EntityLivingBase entity){ - if(this.shouldRevengeTarget(entity)) super.setRevengeTarget(entity); + return false; } - @Override - public void onUpdate(){ - super.onUpdate(); - this.updateDelegate(); + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() + { + return "mob.silverfish.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() + { + return "mob.silverfish.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() + { + return "mob.silverfish.kill"; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource p_70097_1_, float p_70097_2_) + { + if (this.isEntityInvulnerable()) + { + return false; + } + else + { + if (this.allySummonCooldown <= 0 && (p_70097_1_ instanceof EntityDamageSource || p_70097_1_ == DamageSource.magic)) + { + this.allySummonCooldown = 20; + } + + return super.attackEntityFrom(p_70097_1_, p_70097_2_); + } + } + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack. + */ + protected void attackEntity(Entity p_70785_1_, float p_70785_2_) + { + if (this.attackTime <= 0 && p_70785_2_ < 1.2F && p_70785_1_.boundingBox.maxY > this.boundingBox.minY && p_70785_1_.boundingBox.minY < this.boundingBox.maxY) + { + this.attackTime = 20; + this.attackEntityAsMob(p_70785_1_); + } + } + + protected void func_145780_a(int p_145780_1_, int p_145780_2_, int p_145780_3_, Block p_145780_4_) + { + this.playSound("mob.silverfish.step", 0.15F, 1.0F); + } + + protected Item getDropItem() + { + return Item.getItemById(0); } @Override public void onSpawn(){ - this.spawnParticleEffect(); - } - - @Override - public void onDespawn(){ - this.spawnParticleEffect(); - } - - private void spawnParticleEffect(){ if(this.worldObj.isRemote){ for(int i=0;i<15;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, worldObj, this.posX + this.rand.nextFloat(), this.posY + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0.0d, 0.0d, 0.0d, 0, 0.3f, 0.3f, 0.3f); - } - } - } - - @Override - public void onSuccessfulAttack(EntityLivingBase target){ - if(!target.isEntityAlive()){ - this.onKillEntity(target); - } - } - - @Override - public void onKillEntity(EntityLivingBase victim) { - // If the silverfish has a summoner, this is actually called from Wizardry's event handler rather than by - // Minecraft itself, because the damagesource being changed causes it not to get called. - if(!this.worldObj.isRemote){ - // Summons 1-4 more silverfish - int alliesToSummon = rand.nextInt(4) + 1; - - for(int i=0; i 0) + { + --this.allySummonCooldown; + + if (this.allySummonCooldown == 0) + { + i = MathHelper.floor_double(this.posX); + j = MathHelper.floor_double(this.posY); + k = MathHelper.floor_double(this.posZ); + boolean flag = false; + + for (int l = 0; !flag && l <= 5 && l >= -5; l = l <= 0 ? 1 - l : 0 - l) + { + for (i1 = 0; !flag && i1 <= 10 && i1 >= -10; i1 = i1 <= 0 ? 1 - i1 : 0 - i1) + { + for (int j1 = 0; !flag && j1 <= 10 && j1 >= -10; j1 = j1 <= 0 ? 1 - j1 : 0 - j1) + { + if (this.worldObj.getBlock(i + i1, j + l, k + j1) == Blocks.monster_egg) + { + if (!this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")) + { + int k1 = this.worldObj.getBlockMetadata(i + i1, j + l, k + j1); + ImmutablePair immutablepair = BlockSilverfish.func_150197_b(k1); + this.worldObj.setBlock(i + i1, j + l, k + j1, (Block)immutablepair.getLeft(), ((Integer)immutablepair.getRight()).intValue(), 3); + } + else + { + this.worldObj.func_147480_a(i + i1, j + l, k + j1, false); + } + + Blocks.monster_egg.onBlockDestroyedByPlayer(this.worldObj, i + i1, j + l, k + j1, 0); + + if (this.rand.nextBoolean()) + { + flag = true; + break; + } + } + } + } + } + } + } + + if (this.entityToAttack == null && !this.hasPath()) + { + i = MathHelper.floor_double(this.posX); + j = MathHelper.floor_double(this.posY + 0.5D); + k = MathHelper.floor_double(this.posZ); + int l1 = this.rand.nextInt(6); + Block block = this.worldObj.getBlock(i + Facing.offsetsXForSide[l1], j + Facing.offsetsYForSide[l1], k + Facing.offsetsZForSide[l1]); + i1 = this.worldObj.getBlockMetadata(i + Facing.offsetsXForSide[l1], j + Facing.offsetsYForSide[l1], k + Facing.offsetsZForSide[l1]); + + if (BlockSilverfish.func_150196_a(block)) + { + this.worldObj.setBlock(i + Facing.offsetsXForSide[l1], j + Facing.offsetsYForSide[l1], k + Facing.offsetsZForSide[l1], Blocks.monster_egg, BlockSilverfish.func_150195_a(block, i1), 3); + this.spawnExplosionParticle(); + this.setDead(); + } + else + { + this.updateWanderPath(); + } + } + else if (this.entityToAttack != null && !this.hasPath()) + { + this.entityToAttack = null; + } + } + } + + /** + * Takes a coordinate in and returns a weight to determine how likely this creature will try to path to the block. + * Args: x, y, z + */ + public float getBlockPathWeight(int p_70783_1_, int p_70783_2_, int p_70783_3_) + { + return this.worldObj.getBlock(p_70783_1_, p_70783_2_ - 1, p_70783_3_) == Blocks.stone ? 10.0F : super.getBlockPathWeight(p_70783_1_, p_70783_2_, p_70783_3_); + } + + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() + { return true; } - @Override - protected boolean processInteract(EntityPlayer player, EnumHand hand, ItemStack stack) { - // In this case, the delegate method determines whether super is called. - // Rather handily, we can make use of Java's 'stop as soon as you find true' method of evaluating OR statements. - return this.interactDelegate(player, hand, stack) || super.processInteract(player, hand, stack); - } - - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound){ - super.writeEntityToNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound){ - super.readEntityFromNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } - - // Recommended overrides - - @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 boolean canPickUpLoot(){ return false; } - // This vanilla method has nothing to do with the custom despawn() method. - @Override protected boolean canDespawn(){ return false; } - - @Override - public boolean canAttackClass(Class entityType){ - // Returns true unless the given entity type is a flying entity. - return !EntityFlying.class.isAssignableFrom(entityType); - } - - @Override - public ITextComponent getDisplayName(){ - if(getCaster() != null){ - return new TextComponentTranslation(NAMEPLATE_TRANSLATION_KEY, getCaster().getName(), - new TextComponentTranslation("entity." + this.getEntityString() + ".name")); - }else{ - return super.getDisplayName(); - } - } - - @Override - public boolean hasCustomName(){ - // If this returns true, the renderer will show the nameplate when looking directly at the entity - return Wizardry.settings.showSummonedCreatureNames && getCaster() != null; + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() + { + return EnumCreatureAttribute.ARTHROPOD; } } \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/entity/living/EntitySkeletonMinion.java b/src/main/java/electroblob/wizardry/entity/living/EntitySkeletonMinion.java index e62435f3..70895a64 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntitySkeletonMinion.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntitySkeletonMinion.java @@ -1,216 +1,436 @@ package electroblob.wizardry.entity.living; -import java.lang.ref.WeakReference; import java.util.Calendar; -import java.util.UUID; - -import javax.annotation.Nullable; +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityCreature; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.EnumCreatureAttribute; import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.IRangedAttackMob; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIArrowAttack; +import net.minecraft.entity.ai.EntityAIAttackOnCollide; +import net.minecraft.entity.ai.EntityAIFleeSun; import net.minecraft.entity.ai.EntityAIHurtByTarget; +import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; -import net.minecraft.entity.ai.attributes.AttributeModifier; -import net.minecraft.entity.monster.EntitySkeleton; -import net.minecraft.entity.monster.SkeletonType; +import net.minecraft.entity.ai.EntityAIRestrictSun; +import net.minecraft.entity.ai.EntityAISwimming; +import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.monster.IMob; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityArrow; import net.minecraft.init.Blocks; import net.minecraft.init.Items; -import net.minecraft.init.MobEffects; -import net.minecraft.inventory.EntityEquipmentSlot; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.world.DifficultyInstance; +import net.minecraft.stats.AchievementList; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; +import net.minecraft.world.WorldProviderHell; -public class EntitySkeletonMinion extends EntitySkeleton implements ISummonedCreature { +public class EntitySkeletonMinion extends EntitySummonedCreature implements IRangedAttackMob { - // Field implementations - private int lifetime = 600; - private WeakReference casterReference; - private UUID casterUUID; + private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 20, 60, 15.0F); + private EntityAIAttackOnCollide aiAttackOnCollide = new EntityAIAttackOnCollide(this, EntityLivingBase.class, 1.2D, false); - // Setter + getter implementations - @Override public int getLifetime(){ return lifetime; } - @Override public void setLifetime(int lifetime){ this.lifetime = lifetime; } - @Override public WeakReference getCasterReference(){ return casterReference; } - @Override public void setCasterReference(WeakReference reference){ casterReference = reference; } - @Override public UUID getCasterUUID() { return casterUUID; } - @Override public void setCasterUUID(UUID uuid) { this.casterUUID = uuid; } - - /** - * Default shell constructor, only used by client. Lifetime defaults arbitrarily to 600, but this doesn't - * matter because the client side entity immediately gets the lifetime value copied over to it by this class - * anyway. When extending this class, you must override this constructor or Minecraft won't like it, but there's - * no need to do anything inside it other than call super(). - */ public EntitySkeletonMinion(World world){ super(world); - this.experienceValue = 0; + } + + public EntitySkeletonMinion(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ + + super(world, x, y, z, caster, lifetime); + this.tasks.addTask(1, new EntityAISwimming(this)); + this.tasks.addTask(2, new EntityAIRestrictSun(this)); + this.tasks.addTask(3, new EntityAIFleeSun(this, 1.0D)); + this.tasks.addTask(4, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(5, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, 0, false, true, this.targetSelector)); + + if (world != null && !world.isRemote) + { + this.setCombatTask(); + } + } + + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.25D); + } + + @Override + public boolean hasRangedAttack() { + return this.getSkeletonType() == 0; + } + + protected void entityInit() + { + super.entityInit(); + this.dataWatcher.addObject(13, new Byte((byte)0)); } /** - * Set lifetime to -1 to allow this creature to last forever. This constructor should be overridden when - * extending this class (be sure to call super()) so that AI and other things can be added. + * Returns true if the newer Entity AI code should be run */ - public EntitySkeletonMinion(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ - super(world); - this.setPosition(x, y, z); - this.casterReference = new WeakReference(caster); - this.experienceValue = 0; - this.lifetime = lifetime; - } - - // EntitySkeleton overrides - - // This particular override is pretty standard: let the superclass handle basic AI like swimming, but replace its - // targeting system with one that targets hostile mobs and takes the ADS into account. - @Override - protected void initEntityAI() + public boolean isAIEnabled() { - super.initEntityAI(); - this.targetTasks.taskEntries.clear(); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, - 0, false, true, this.getTargetSelector())); - } - - // Shouldn't have randomised armour, but does still need a bow! - @Override - protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty) { - this.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.BOW)); - } - - // Where the skeleton minion is summoned does not affect its type. - @Override - public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, @Nullable IEntityLivingData livingdata) - { - // Can't call super, so the code from the next level up (EntityLiving) had to be copied as well. - this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).applyModifier(new AttributeModifier("Random spawn bonus", this.rand.nextGaussian() * 0.05D, 1)); - - if (this.rand.nextFloat() < 0.05F) - { - this.setLeftHanded(true); - } - else - { - this.setLeftHanded(false); - } - - // Halloween pumpkin heads! Why not? - if (this.getItemStackFromSlot(EntityEquipmentSlot.HEAD) == null) - { - Calendar calendar = this.worldObj.getCurrentDate(); - - if (calendar.get(2) + 1 == 10 && calendar.get(5) == 31 && this.rand.nextFloat() < 0.25F) - { - this.setItemStackToSlot(EntityEquipmentSlot.HEAD, new ItemStack(this.rand.nextFloat() < 0.1F ? Blocks.LIT_PUMPKIN : Blocks.PUMPKIN)); - this.inventoryArmorDropChances[EntityEquipmentSlot.HEAD.getIndex()] = 0.0F; - } - } - - return livingdata; - } - - // Implementations - - @Override - public void setRevengeTarget(EntityLivingBase entity){ - if(this.shouldRevengeTarget(entity)) super.setRevengeTarget(entity); + return true; } - @Override - public void onUpdate(){ - super.onUpdate(); - this.updateDelegate(); + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() + { + return "mob.skeleton.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() + { + return "mob.skeleton.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() + { + return "mob.skeleton.death"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) + { + this.playSound("mob.skeleton.step", 0.15F, 1.0F); + } + + public boolean attackEntityAsMob(Entity par1Entity) + { + if (super.attackEntityAsMob(par1Entity)) + { + if (this.getSkeletonType() == 1 && par1Entity instanceof EntityLivingBase) + { + ((EntityLivingBase)par1Entity).addPotionEffect(new PotionEffect(Potion.wither.id, 200)); + } + + return true; + } + else + { + return false; + } + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() + { + return EnumCreatureAttribute.UNDEAD; } @Override public void onSpawn(){ - this.spawnParticleEffect(); - } - - @Override - public void onDespawn(){ - this.spawnParticleEffect(); - } - - private void spawnParticleEffect(){ if(this.worldObj.isRemote){ for(int i=0;i<15;i++){ - this.worldObj.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.posX + this.rand.nextFloat(), this.posY + 1 + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0, 0, 0); + this.worldObj.spawnParticle("largesmoke", this.posX + this.rand.nextFloat(), this.posY + 1 + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0, 0, 0); } } } @Override - public boolean hasParticleEffect() { - return true; - } - - @Override - public void onSuccessfulAttack(EntityLivingBase target) { - if(this.getSkeletonType() == SkeletonType.WITHER){ - target.addPotionEffect(new PotionEffect(MobEffects.WITHER, 200)); - } + public void despawn(){ + if(this.worldObj.isRemote){ + for(int i=0;i<15;i++){ + this.worldObj.spawnParticle("largesmoke", this.posX + this.rand.nextFloat(), this.posY + 1 + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0, 0, 0); + } + } + super.despawn(); } - @Override - protected boolean processInteract(EntityPlayer player, EnumHand hand, ItemStack stack) { - // In this case, the delegate method determines whether super is called. - // Rather handily, we can make use of Java's 'stop as soon as you find true' method of evaluating OR statements. - return this.interactDelegate(player, hand, stack) || super.processInteract(player, hand, stack); + public void onUpdate(){ + + super.onUpdate(); + + //Adds subtle particle effect while alive + if(this.worldObj.isRemote && rand.nextInt(8) == 0) Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, worldObj, this.posX, this.posY + rand.nextDouble()*1.5, this.posZ, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); } - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound){ - super.writeEntityToNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); + /** + * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons + * use this to react to sunlight and start to burn. + */ + public void onLivingUpdate() + { + + if (this.worldObj.isDaytime() && !this.worldObj.isRemote) + { + float f = this.getBrightness(1.0F); + + if (f > 0.5F && this.rand.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ))) + { + boolean flag = true; + ItemStack itemstack = this.getEquipmentInSlot(4); + + if (itemstack != null) + { + if (itemstack.isItemStackDamageable()) + { + itemstack.setItemDamage(itemstack.getItemDamageForDisplay() + this.rand.nextInt(2)); + + if (itemstack.getItemDamageForDisplay() >= itemstack.getMaxDamage()) + { + this.renderBrokenItemStack(itemstack); + this.setCurrentItemOrArmor(4, (ItemStack)null); + } + } + + flag = false; + } + + if (flag) + { + this.setFire(8); + } + } + } + + if (this.worldObj.isRemote && this.getSkeletonType() == 1) + { + this.setSize(0.72F, 2.34F); + } + + super.onLivingUpdate(); } - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound){ - super.readEntityFromNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } + /** + * Handles updating while being ridden by an entity + */ + public void updateRidden() + { + super.updateRidden(); - // Recommended overrides - - @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 boolean canPickUpLoot(){ return false; } - // This vanilla method has nothing to do with the custom despawn() method. - @Override protected boolean canDespawn(){ return false; } - - @Override - public boolean canAttackClass(Class entityType){ - return true; - } - - @Override - public ITextComponent getDisplayName(){ - if(getCaster() != null){ - return new TextComponentTranslation(NAMEPLATE_TRANSLATION_KEY, getCaster().getName(), - new TextComponentTranslation("entity." + this.getEntityString() + ".name")); - }else{ - return super.getDisplayName(); + if (this.ridingEntity instanceof EntityCreature) + { + EntityCreature entitycreature = (EntityCreature)this.ridingEntity; + this.renderYawOffset = entitycreature.renderYawOffset; } } - @Override - public boolean hasCustomName(){ - // If this returns true, the renderer will show the nameplate when looking directly at the entity - return Wizardry.settings.showSummonedCreatureNames && getCaster() != null; + /** + * Called when the mob's health reaches 0. + */ + public void onDeath(DamageSource par1DamageSource) + { + super.onDeath(par1DamageSource); + + if (par1DamageSource.getSourceOfDamage() instanceof EntityArrow && par1DamageSource.getEntity() instanceof EntityPlayer) + { + EntityPlayer entityplayer = (EntityPlayer)par1DamageSource.getEntity(); + double d0 = entityplayer.posX - this.posX; + double d1 = entityplayer.posZ - this.posZ; + + if (d0 * d0 + d1 * d1 >= 2500.0D) + { + entityplayer.triggerAchievement(AchievementList.snipeSkeleton); + } + } + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() + { + return -1; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param + * par2 - Level of Looting used to kill this mob. + */ + protected void dropFewItems(boolean par1, int par2) + { + + } + + /** + * Makes entity wear random armor based on difficulty + */ + protected void addRandomArmor() + { + this.setCurrentItemOrArmor(0, new ItemStack(Items.bow)); + } + + public IEntityLivingData onSpawnWithEgg(IEntityLivingData par1EntityLivingData) + { + par1EntityLivingData = super.onSpawnWithEgg(par1EntityLivingData); + + if (this.worldObj.provider instanceof WorldProviderHell && this.getRNG().nextInt(5) > 0) + { + this.tasks.addTask(4, this.aiAttackOnCollide); + this.setSkeletonType(1); + this.setCurrentItemOrArmor(0, new ItemStack(Items.stone_sword)); + this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(4.0D); + } + else + { + this.tasks.addTask(4, this.aiArrowAttack); + this.addRandomArmor(); + this.enchantEquipment(); + } + + this.setCanPickUpLoot(this.rand.nextFloat() < 0.55F * this.worldObj.func_147462_b(this.posX, this.posY, this.posZ)); + + if (this.getEquipmentInSlot(4) == null) + { + Calendar calendar = this.worldObj.getCurrentDate(); + + if (calendar.get(2) + 1 == 10 && calendar.get(5) == 31 && this.rand.nextFloat() < 0.25F) + { + this.setCurrentItemOrArmor(4, new ItemStack(this.rand.nextFloat() < 0.1F ? Blocks.lit_pumpkin : Blocks.pumpkin)); + this.equipmentDropChances[4] = 0.0F; + } + } + + return par1EntityLivingData; + } + + /** + * sets this entity's combat AI. + */ + public void setCombatTask() + { + this.tasks.removeTask(this.aiAttackOnCollide); + this.tasks.removeTask(this.aiArrowAttack); + ItemStack itemstack = this.getHeldItem(); + + if (itemstack != null && itemstack.getItem() == Items.bow) + { + this.tasks.addTask(4, this.aiArrowAttack); + } + else + { + this.tasks.addTask(4, this.aiAttackOnCollide); + } + } + /** + * Attack the specified entity using a ranged attack. + */ + public void attackEntityWithRangedAttack(EntityLivingBase p_82196_1_, float p_82196_2_) + { + EntityArrow entityarrow = new EntityArrow(this.worldObj, this, p_82196_1_, 1.6F, (float)(14 - this.worldObj.difficultySetting.getDifficultyId() * 4)); + int i = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, this.getHeldItem()); + int j = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, this.getHeldItem()); + entityarrow.setDamage((double)(p_82196_2_ * 2.0F) + this.rand.nextGaussian() * 0.25D + (double)((float)this.worldObj.difficultySetting.getDifficultyId() * 0.11F)); + entityarrow.shootingEntity = this.getCaster(); + + if (i > 0) + { + entityarrow.setDamage(entityarrow.getDamage() + (double)i * 0.5D + 0.5D); + } + + if (j > 0) + { + entityarrow.setKnockbackStrength(j); + } + + if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, this.getHeldItem()) > 0 || this.getSkeletonType() == 1) + { + entityarrow.setFire(100); + } + + this.playSound("random.bow", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); + this.worldObj.spawnEntityInWorld(entityarrow); + } + + /** + * Return this skeleton's type. + */ + public int getSkeletonType() + { + return this.dataWatcher.getWatchableObjectByte(13); + } + + /** + * Set this skeleton's type. + */ + public void setSkeletonType(int par1) + { + this.dataWatcher.updateObject(13, Byte.valueOf((byte)par1)); + this.isImmuneToFire = par1 == 1; + + if (par1 == 1) + { + this.setSize(0.72F, 2.34F); + } + else + { + this.setSize(0.6F, 1.8F); + } + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound par1NBTTagCompound) + { + super.readEntityFromNBT(par1NBTTagCompound); + + if (par1NBTTagCompound.hasKey("SkeletonType")) + { + byte b0 = par1NBTTagCompound.getByte("SkeletonType"); + this.setSkeletonType(b0); + } + + this.setCombatTask(); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound par1NBTTagCompound) + { + super.writeEntityToNBT(par1NBTTagCompound); + par1NBTTagCompound.setByte("SkeletonType", (byte)this.getSkeletonType()); + } + + /** + * Sets the held item, or an armor slot. Slot 0 is held item. Slot 1-4 is armor. Params: Item, slot + */ + public void setCurrentItemOrArmor(int par1, ItemStack par2ItemStack) + { + super.setCurrentItemOrArmor(par1, par2ItemStack); + + if (!this.worldObj.isRemote && par1 == 0) + { + this.setCombatTask(); + } + } + + /** + * Returns the Y Offset of this entity. + */ + public double getYOffset() + { + return super.getYOffset() - 0.5D; } } diff --git a/src/main/java/electroblob/wizardry/entity/living/EntitySpiderMinion.java b/src/main/java/electroblob/wizardry/entity/living/EntitySpiderMinion.java index f5714361..7ad638b6 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntitySpiderMinion.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntitySpiderMinion.java @@ -1,207 +1,290 @@ package electroblob.wizardry.entity.living; -import java.lang.ref.WeakReference; -import java.util.UUID; - +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.util.WizardryParticleType; -import net.minecraft.entity.EntityFlying; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.EnumCreatureAttribute; import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIAttackOnCollide; import net.minecraft.entity.ai.EntityAIHurtByTarget; +import net.minecraft.entity.ai.EntityAILookIdle; +import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; -import net.minecraft.entity.ai.attributes.AttributeModifier; -import net.minecraft.entity.monster.EntityCaveSpider; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.entity.ai.EntityAISwimming; +import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.monster.IMob; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -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; -import net.minecraft.world.EnumDifficulty; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; -public class EntitySpiderMinion extends EntityCaveSpider implements ISummonedCreature { +public class EntitySpiderMinion extends EntitySummonedCreature { - // Field implementations - private int lifetime = 600; - private WeakReference casterReference; - private UUID casterUUID; - - // Setter + getter implementations - @Override public int getLifetime(){ return lifetime; } - @Override public void setLifetime(int lifetime){ this.lifetime = lifetime; } - @Override public WeakReference getCasterReference(){ return casterReference; } - @Override public void setCasterReference(WeakReference reference){ casterReference = reference; } - @Override public UUID getCasterUUID() { return casterUUID; } - @Override public void setCasterUUID(UUID uuid) { this.casterUUID = uuid; } - - /** - * Default shell constructor, only used by client. Lifetime defaults arbitrarily to 600, but this doesn't - * matter because the client side entity immediately gets the lifetime value copied over to it by this class - * anyway. When extending this class, you must override this constructor or Minecraft won't like it, but there's - * no need to do anything inside it other than call super(). - */ public EntitySpiderMinion(World world){ - super(world); - this.experienceValue = 0; - } - - /** - * Set lifetime to -1 to allow this creature to last forever. This constructor should be overridden when - * extending this class (be sure to call super()) so that AI and other things can be added. - */ - public EntitySpiderMinion(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ - super(world); - this.setPosition(x, y, z); - this.casterReference = new WeakReference(caster); - this.experienceValue = 0; - this.lifetime = lifetime; - } - - // EntitySpider overrides + super(world); + } - // This particular override is pretty standard: let the superclass handle basic AI like swimming, but replace its - // targeting system with one that targets hostile mobs and takes the ADS into account. - @Override - protected void initEntityAI() - { - super.initEntityAI(); - this.targetTasks.taskEntries.clear(); - // Spiders use a custom AI type specific to spiders which I can't access, but it's just an extension of - // EntityAINearestAttackableTarget which takes daylight into account. Since I want spider minions to attack - // regardless of daylight, I can just use EntityAINearestAttackableTarget. - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, - 0, false, true, this.getTargetSelector())); - } - - // No spider jockeys! - @Override - public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata) { - - // Can't call super, so the code from the next level up (EntityLiving) had to be copied as well. - this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).applyModifier(new AttributeModifier("Random spawn bonus", this.rand.nextGaussian() * 0.05D, 1)); + public EntitySpiderMinion(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ + + super(world, x, y, z, caster, lifetime); + this.setSize(0.7F, 0.5F); + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityLivingBase.class, 1.0D, true)); + this.tasks.addTask(2, new EntityAIMoveTowardsRestriction(this, 1.0D)); + this.tasks.addTask(3, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(4, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, 0, false, true, this.targetSelector)); + this.experienceValue = 0; + } - if (this.rand.nextFloat() < 0.05F) + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() + { + return true; + } + + @Override + public boolean hasRangedAttack() { + return false; + } + + protected void entityInit() + { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte)0)); + } + + @Override + public void onSpawn(){ + if(this.worldObj.isRemote){ + for(int i=0;i<15;i++){ + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, worldObj, this.posX + this.rand.nextFloat(), this.posY + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.2f, 0.0f); + } + } + } + + @Override + public void despawn(){ + if(this.worldObj.isRemote){ + for(int i=0;i<15;i++){ + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, worldObj, this.posX + this.rand.nextFloat(), this.posY + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.2f, 0.0f); + } + } + super.despawn(); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() + { + // Adds subtle particle effect while alive + if(this.worldObj.isRemote && rand.nextInt(8) == 0) Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, worldObj, this.posX, this.posY + rand.nextDouble()*1.5, this.posZ, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); + + super.onUpdate(); + + if (!this.worldObj.isRemote) { - this.setLeftHanded(true); + this.setBesideClimbableBlock(this.isCollidedHorizontally); + } + } + + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(12.0D); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.3D); + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity isn't interested in attacking + * (Animals, Spiders at day, peaceful PigZombies). + */ + protected Entity findPlayerToAttack() + { + float f = this.getBrightness(1.0F); + + if (f < 0.5F) + { + double d0 = 16.0D; + return this.worldObj.getClosestVulnerablePlayerToEntity(this, d0); } else { - this.setLeftHanded(false); + return null; } - - // Don't need anything from EntitySpider, since neither spider jockeys nor group data is relevant. - return livingdata; - } + } - // Implementations + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() + { + return "mob.spider.say"; + } - @Override - public void setRevengeTarget(EntityLivingBase entity){ - if(this.shouldRevengeTarget(entity)) super.setRevengeTarget(entity); - } + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() + { + return "mob.spider.say"; + } - @Override - public void onUpdate(){ - super.onUpdate(); - this.updateDelegate(); - } + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() + { + return "mob.spider.death"; + } - @Override - public void onSpawn(){ - this.spawnParticleEffect(); - } + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) + { + this.playSound("mob.spider.step", 0.15F, 1.0F); + } - @Override - public void onDespawn(){ - this.spawnParticleEffect(); - } - - private void spawnParticleEffect(){ - if(this.worldObj.isRemote){ - for(int i=0;i<15;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, worldObj, this.posX + this.rand.nextFloat(), this.posY + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.2f, 0.0f); - } - } - } + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) + { + float f1 = this.getBrightness(1.0F); - @Override - public boolean hasParticleEffect() { - return true; - } - - @Override - public void onSuccessfulAttack(EntityLivingBase target){ - - int seconds = 0; + if (f1 > 0.5F && this.rand.nextInt(100) == 0) + { + this.entityToAttack = null; + } + else + { + if (par2 > 2.0F && par2 < 6.0F && this.rand.nextInt(10) == 0) + { + if (this.onGround) + { + double d0 = par1Entity.posX - this.posX; + double d1 = par1Entity.posZ - this.posZ; + float f2 = MathHelper.sqrt_double(d0 * d0 + d1 * d1); + this.motionX = d0 / (double)f2 * 0.5D * 0.800000011920929D + this.motionX * 0.20000000298023224D; + this.motionZ = d1 / (double)f2 * 0.5D * 0.800000011920929D + this.motionZ * 0.20000000298023224D; + this.motionY = 0.4000000059604645D; + } + } + else + { + super.attackEntity(par1Entity, par2); + } + } + } - if(this.worldObj.getDifficulty() == EnumDifficulty.NORMAL){ - seconds = 7; - }else if(this.worldObj.getDifficulty() == EnumDifficulty.HARD){ - seconds = 15; + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() + { + return -1; + } + + /** + * returns true if this entity is by a ladder, false otherwise + */ + public boolean isOnLadder() + { + return this.isBesideClimbableBlock(); + } + + /** + * Sets the Entity inside a web block. + */ + public void setInWeb() {} + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() + { + return EnumCreatureAttribute.ARTHROPOD; + } + + public boolean isPotionApplicable(PotionEffect par1PotionEffect) + { + return par1PotionEffect.getPotionID() == Potion.poison.id ? false : super.isPotionApplicable(par1PotionEffect); + } + + /** + * Returns true if the WatchableObject (Byte) is 0x01 otherwise returns false. The WatchableObject is updated using + * setBesideClimableBlock. + */ + public boolean isBesideClimbableBlock() + { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + /** + * Updates the WatchableObject (Byte) created in entityInit(), setting it to 0x01 if par1 is true or 0x00 if it is + * false. + */ + public void setBesideClimbableBlock(boolean par1) + { + byte b0 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) + { + b0 = (byte)(b0 | 1); + } + else + { + b0 &= -2; } - if(seconds > 0){ - target.addPotionEffect(new PotionEffect(MobEffects.POISON, seconds * 20, 0)); + this.dataWatcher.updateObject(16, Byte.valueOf(b0)); + } +/* + public boolean attackEntityAsMob(Entity par1Entity) + { + if (super.attackEntityAsMob(par1Entity)) + { + if (par1Entity instanceof EntityLivingBase) + { + byte b0 = 0; + + if (this.worldObj.difficultySetting > 1) + { + if (this.worldObj.difficultySetting == 2) + { + b0 = 7; + } + else if (this.worldObj.difficultySetting == 3) + { + b0 = 15; + } + } + + if (b0 > 0) + { + ((EntityLivingBase)par1Entity).addPotionEffect(new PotionEffect(Potion.poison.id, b0 * 20, 0)); + } + } + + return true; } - } - - @Override - protected boolean processInteract(EntityPlayer player, EnumHand hand, ItemStack stack) { - // In this case, the delegate method determines whether super is called. - // Rather handily, we can make use of Java's 'stop as soon as you find true' method of evaluating OR statements. - return this.interactDelegate(player, hand, stack) || super.processInteract(player, hand, stack); - } - - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound){ - super.writeEntityToNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound){ - super.readEntityFromNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } - - // Recommended overrides - - @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 boolean canPickUpLoot(){ return false; } - // This vanilla method has nothing to do with the custom despawn() method. - @Override protected boolean canDespawn(){ return false; } - - @Override - public boolean canAttackClass(Class entityType){ - // Returns true unless the given entity type is a flying entity. - return !EntityFlying.class.isAssignableFrom(entityType); - } - - @Override - public ITextComponent getDisplayName(){ - if(getCaster() != null){ - return new TextComponentTranslation(NAMEPLATE_TRANSLATION_KEY, getCaster().getName(), - new TextComponentTranslation("entity." + this.getEntityString() + ".name")); - }else{ - return super.getDisplayName(); - } - } - - @Override - public boolean hasCustomName(){ - // If this returns true, the renderer will show the nameplate when looking directly at the entity - return Wizardry.settings.showSummonedCreatureNames && getCaster() != null; - } + else + { + return false; + } + } +*/ + public IEntityLivingData onSpawnWithEgg(IEntityLivingData par1EntityLivingData) + { + return par1EntityLivingData; + } } diff --git a/src/main/java/electroblob/wizardry/entity/living/EntitySpiritHorse.java b/src/main/java/electroblob/wizardry/entity/living/EntitySpiritHorse.java index 47be717e..4dd0abae 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntitySpiritHorse.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntitySpiritHorse.java @@ -1,31 +1,46 @@ package electroblob.wizardry.entity.living; -import electroblob.wizardry.WizardData; +import java.util.UUID; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.item.ItemWand; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import net.minecraft.block.Block; +import net.minecraft.block.Block.SoundType; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityAgeable; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IEntityLivingData; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIFollowParent; +import net.minecraft.entity.ai.EntityAILookIdle; +import net.minecraft.entity.ai.EntityAIPanic; +import net.minecraft.entity.ai.EntityAISwimming; +import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.EntityAIWatchClosest; +import net.minecraft.entity.ai.attributes.IAttribute; +import net.minecraft.entity.ai.attributes.IAttributeInstance; +import net.minecraft.entity.ai.attributes.RangedAttribute; import net.minecraft.entity.passive.EntityAnimal; import net.minecraft.entity.passive.EntityHorse; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; +import net.minecraft.inventory.AnimalChest; import net.minecraft.item.Item; +import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.potion.Potion; import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumHand; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.util.text.translation.I18n; -import net.minecraft.world.DifficultyInstance; +import net.minecraft.util.MathHelper; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; -/** Does not implement ISummonedCreature because it has different despawning rules and because EntityHorse already - * has an owner system. */ -@SuppressWarnings("deprecation") // It's what Entity does, so... public class EntitySpiritHorse extends EntityHorse { private int idleTimer = 0; @@ -35,16 +50,19 @@ public class EntitySpiritHorse extends EntityHorse { super(par1World); } + /** + * Gets the username of the entity. + */ @Override - public String getName() + public String getCommandSenderName() { - if (this.hasCustomName()) + if (this.hasCustomNameTag()) { return this.getCustomNameTag(); } else { - return I18n.translateToLocal("entity.wizardry.Spirit Horse.name"); + return StatCollector.translateToLocal("entity.wizardry.Spirit Horse.name"); } } @@ -78,36 +96,36 @@ public class EntitySpiritHorse extends EntityHorse { protected void applyEntityAttributes() { super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(24.0D); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(24.0D); } @Override public void openGUI(EntityPlayer p_110199_1_){} @Override - public boolean processInteract(EntityPlayer player, EnumHand hand, ItemStack stack){ + public boolean interact(EntityPlayer par1EntityPlayer){ - ItemStack itemstack = player.inventory.getCurrentItem(); + ItemStack itemstack = par1EntityPlayer.inventory.getCurrentItem(); // Allows the owner (but not other players) to dispel the spirit horse using a wand (shift-clicking, because clicking mounts the horse in this case). - if(itemstack != null && itemstack.getItem() instanceof ItemWand && this.getOwner() == player && player.isSneaking()){ + if(itemstack != null && itemstack.getItem() instanceof ItemWand && this.getOwner() == par1EntityPlayer && par1EntityPlayer.isSneaking()){ // Prevents accidental double clicking. if(this.ticksExisted > 20){ for(int i=0;i<15;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, this.posX - this.width/2 + this.rand.nextFloat()*width, this.posY + this.height*this.rand.nextFloat() + 0.2f, this.posZ - this.width/2 + this.rand.nextFloat()*width, 0, 0, 0, 48 + this.rand.nextInt(12), 0.8f, 0.8f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX - this.width/2 + this.rand.nextFloat()*width, this.posY + this.height*this.rand.nextFloat() + 0.2f, this.posZ - this.width/2 + this.rand.nextFloat()*width, 0, 0, 0, 48 + this.rand.nextInt(12), 0.8f, 0.8f, 1.0f); } this.setDead(); - if(WizardData.get(player) != null){ - WizardData.get(player).hasSpiritHorse = false; + if(ExtendedPlayer.get(par1EntityPlayer) != null){ + ExtendedPlayer.get(par1EntityPlayer).hasSpiritHorse = false; } - this.playSound(WizardrySounds.SPELL_HEAL, 0.7F, rand.nextFloat() * 0.4F + 1.0F); + this.playSound("wizardry:heal", 0.7F, rand.nextFloat() * 0.4F + 1.0F); // This is necessary to prevent the wand's spell being cast when performing this action. return true; } return false; } - return super.processInteract(player, hand, itemstack); + return super.interact(par1EntityPlayer); } @Override @@ -116,16 +134,18 @@ public class EntitySpiritHorse extends EntityHorse { super.onDeath(par1DamageSource); // Allows player to summon another spirit horse once this one has died. - if(this.getOwner() instanceof EntityPlayer && WizardData.get((EntityPlayer)this.getOwner()) != null){ - WizardData.get((EntityPlayer)this.getOwner()).hasSpiritHorse = false; + if(this.getOwner() instanceof EntityPlayer && ExtendedPlayer.get((EntityPlayer)this.getOwner()) != null){ + ExtendedPlayer.get((EntityPlayer)this.getOwner()).hasSpiritHorse = false; } } // I wrote this one! private EntityLivingBase getOwner(){ + + // func_152119_ch retrieves the owner UUID from the datawatcher + if(this.func_152119_ch() == null || WizardryUtilities.verifyUUIDString(this.func_152119_ch())) return null; - // I think the DataManager stores any objects, so it now stores the UUID instead of its string representation. - Entity owner = WizardryUtilities.getEntityByUUID(worldObj, this.getOwnerUniqueId()); + Entity owner = WizardryUtilities.getEntityByUUID(worldObj, UUID.fromString(this.func_152119_ch())); if(owner instanceof EntityLivingBase){ return (EntityLivingBase)owner; @@ -141,11 +161,11 @@ public class EntitySpiritHorse extends EntityHorse { // Adds a dust particle effect if(this.worldObj.isRemote){ - Wizardry.proxy.spawnParticle(WizardryParticleType.DUST, worldObj, this.posX - this.width/2 + this.rand.nextFloat()*width, this.posY + this.height*this.rand.nextFloat() + 0.2f, this.posZ - this.width/2 + this.rand.nextFloat()*width, 0, 0, 0, 0, 0.8f, 0.8f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.DUST, worldObj, this.posX - this.width/2 + this.rand.nextFloat()*width, this.posY + this.height*this.rand.nextFloat() + 0.2f, this.posZ - this.width/2 + this.rand.nextFloat()*width, 0, 0, 0, 0, 0.8f, 0.8f, 1.0f); } // Spirit horse disappears a short time after being dismounted. - if(!this.isBeingRidden()){ + if(this.riddenByEntity == null){ this.idleTimer++; }else if(this.idleTimer > 0){ this.idleTimer = 0; @@ -154,13 +174,13 @@ public class EntitySpiritHorse extends EntityHorse { if(this.idleTimer > 200){ if(this.worldObj.isRemote){ for(int i=0;i<15;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, this.posX - this.width/2 + this.rand.nextFloat()*width, this.posY + this.height*this.rand.nextFloat() + 0.2f, this.posZ - this.width/2 + this.rand.nextFloat()*width, 0, 0, 0, 48 + this.rand.nextInt(12), 0.8f, 0.8f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX - this.width/2 + this.rand.nextFloat()*width, this.posY + this.height*this.rand.nextFloat() + 0.2f, this.posZ - this.width/2 + this.rand.nextFloat()*width, 0, 0, 0, 48 + this.rand.nextInt(12), 0.8f, 0.8f, 1.0f); } } - this.playSound(WizardrySounds.SPELL_HEAL, 0.7F, rand.nextFloat() * 0.4F + 1.0F); + this.playSound("wizardry:heal", 0.7F, rand.nextFloat() * 0.4F + 1.0F); // Allows player to summon another spirit horse once this one has disappeared. - if(this.getOwner() instanceof EntityPlayer && WizardData.get((EntityPlayer)this.getOwner()) != null){ - WizardData.get((EntityPlayer)this.getOwner()).hasSpiritHorse = false; + if(this.getOwner() instanceof EntityPlayer && ExtendedPlayer.get((EntityPlayer)this.getOwner()) != null){ + ExtendedPlayer.get((EntityPlayer)this.getOwner()).hasSpiritHorse = false; } this.setDead(); } @@ -172,32 +192,16 @@ public class EntitySpiritHorse extends EntityHorse { } @Override - public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData data){ + public IEntityLivingData onSpawnWithEgg(IEntityLivingData par1EntityLivingData){ // Adds Particles on spawn. Due to client/server differences this cannot be done in the item. if(this.worldObj.isRemote){ for(int i=0;i<15;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, this.posX - this.width/2 + this.rand.nextFloat()*width, this.posY + this.height*this.rand.nextFloat() + 0.2f, this.posZ - this.width/2 + this.rand.nextFloat()*width, 0, 0, 0, 48 + this.rand.nextInt(12), 0.8f, 0.8f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX - this.width/2 + this.rand.nextFloat()*width, this.posY + this.height*this.rand.nextFloat() + 0.2f, this.posZ - this.width/2 + this.rand.nextFloat()*width, 0, 0, 0, 48 + this.rand.nextInt(12), 0.8f, 0.8f, 1.0f); } } - return super.onInitialSpawn(difficulty, data); - } - - @Override - public ITextComponent getDisplayName(){ - if(getOwner() != null){ - return new TextComponentTranslation(ISummonedCreature.NAMEPLATE_TRANSLATION_KEY, getOwner().getName(), - new TextComponentTranslation("entity." + this.getEntityString() + ".name")); - }else{ - return super.getDisplayName(); - } - } - - @Override - public boolean hasCustomName(){ - // If this returns true, the renderer will show the nameplate when looking directly at the entity - return Wizardry.settings.showSummonedCreatureNames && getOwner() != null; + return super.onSpawnWithEgg(par1EntityLivingData); } } diff --git a/src/main/java/electroblob/wizardry/entity/living/EntitySpiritWolf.java b/src/main/java/electroblob/wizardry/entity/living/EntitySpiritWolf.java index 6de76c7b..061257ce 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntitySpiritWolf.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntitySpiritWolf.java @@ -1,71 +1,76 @@ package electroblob.wizardry.entity.living; -import electroblob.wizardry.WizardData; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; import electroblob.wizardry.item.ItemWand; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.WizardryParticleType; +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityAgeable; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IEntityLivingData; -import net.minecraft.entity.ai.EntityAIAttackMelee; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIAttackOnCollide; import net.minecraft.entity.ai.EntityAIFollowOwner; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILeapAtTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAIOwnerHurtByTarget; import net.minecraft.entity.ai.EntityAIOwnerHurtTarget; -import net.minecraft.entity.ai.EntityAISit; import net.minecraft.entity.ai.EntityAISwimming; import net.minecraft.entity.ai.EntityAIWander; import net.minecraft.entity.ai.EntityAIWatchClosest; +import net.minecraft.entity.monster.EntityCreeper; +import net.minecraft.entity.monster.EntityGhast; +import net.minecraft.entity.passive.EntityAnimal; +import net.minecraft.entity.passive.EntityHorse; import net.minecraft.entity.passive.EntityWolf; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityArrow; import net.minecraft.item.Item; +import net.minecraft.item.ItemFood; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.pathfinding.PathEntity; import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumHand; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.world.DifficultyInstance; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; -/** Does not implement ISummonedCreature because it has different despawning rules and because EntityWolf already - * has an owner system. */ public class EntitySpiritWolf extends EntityWolf { public EntitySpiritWolf(World par1World){ super(par1World); - this.experienceValue = 0; - } - - @Override - protected void initEntityAI(){ - - this.aiSit = new EntityAISit(this); + // Removes all the AI in EntityWolf so I can add what I want instead. + this.tasks.taskEntries.clear(); + this.targetTasks.taskEntries.clear(); + this.getNavigator().setAvoidsWater(true); this.tasks.addTask(1, new EntityAISwimming(this)); this.tasks.addTask(2, this.aiSit); this.tasks.addTask(3, new EntityAILeapAtTarget(this, 0.4F)); - this.tasks.addTask(4, new EntityAIAttackMelee(this, 1.0D, true)); + this.tasks.addTask(4, new EntityAIAttackOnCollide(this, 1.0D, true)); this.tasks.addTask(5, new EntityAIFollowOwner(this, 1.0D, 10.0F, 2.0F)); this.tasks.addTask(7, new EntityAIWander(this, 1.0D)); this.tasks.addTask(9, new EntityAIWatchClosest(this, EntityPlayer.class, 8.0F)); this.tasks.addTask(9, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIOwnerHurtByTarget(this)); this.targetTasks.addTask(2, new EntityAIOwnerHurtTarget(this)); - this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true, new Class[0])); + this.targetTasks.addTask(3, new EntityAIHurtByTarget(this, true)); + this.experienceValue = 0; } @Override - public void onDeath(DamageSource source){ + public void onDeath(DamageSource par1DamageSource){ // Allows player to summon another spirit wolf once this one has died. - // NOTE: This has been known to work incorrectly. - if(this.getOwner() instanceof EntityPlayer && WizardData.get((EntityPlayer)this.getOwner()) != null){ - WizardData.get((EntityPlayer)this.getOwner()).hasSpiritWolf = false; + // TODO: Or at least, it should... + if(this.getOwner() instanceof EntityPlayer && ExtendedPlayer.get((EntityPlayer)this.getOwner()) != null){ + ExtendedPlayer.get((EntityPlayer)this.getOwner()).hasSpiritWolf = false; } - super.onDeath(source); + super.onDeath(par1DamageSource); } @Override @@ -74,16 +79,15 @@ public class EntitySpiritWolf extends EntityWolf { } @Override - public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata) { - + public IEntityLivingData onSpawnWithEgg(IEntityLivingData par1EntityLivingData){ + // Adds Particles on spawn. Due to client/server differences this cannot be done in the item. if(this.worldObj.isRemote){ for(int i=0;i<15;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, worldObj, this.posX - this.width/2 + this.rand.nextFloat()*width, this.posY + this.height*this.rand.nextFloat() + 0.2f, this.posZ - this.width/2 + this.rand.nextFloat()*width, 0, 0, 0, 48 + this.rand.nextInt(12), 0.8f, 0.8f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, this.posX - this.width/2 + this.rand.nextFloat()*width, this.posY + this.height*this.rand.nextFloat() + 0.2f, this.posZ - this.width/2 + this.rand.nextFloat()*width, 0, 0, 0, 48 + this.rand.nextInt(12), 0.8f, 0.8f, 1.0f); } } - - return livingdata; + return par1EntityLivingData; } @Override @@ -93,29 +97,31 @@ public class EntitySpiritWolf extends EntityWolf { // Adds a dust particle effect if(this.worldObj.isRemote){ - Wizardry.proxy.spawnParticle(WizardryParticleType.DUST, worldObj, this.posX - this.width/2 + this.rand.nextFloat()*width, this.posY + this.height*this.rand.nextFloat() + 0.2f, this.posZ - this.width/2 + this.rand.nextFloat()*width, 0, 0, 0, 0, 0.8f, 0.8f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.DUST, worldObj, this.posX - this.width/2 + this.rand.nextFloat()*width, this.posY + this.height*this.rand.nextFloat() + 0.2f, this.posZ - this.width/2 + this.rand.nextFloat()*width, 0, 0, 0, 0, 0.8f, 0.8f, 1.0f); } } - + @Override - public boolean processInteract(EntityPlayer player, EnumHand hand, ItemStack stack) { + public boolean interact(EntityPlayer player) + { + ItemStack itemstack = player.inventory.getCurrentItem(); if (this.isTamed()) { - if (stack != null){ + if (itemstack != null){ // Allows the owner (but not other players) to dispel the spirit wolf using a wand. - if(stack != null && stack.getItem() instanceof ItemWand && this.getOwner() == player && player.isSneaking()){ + if(itemstack != null && itemstack.getItem() instanceof ItemWand && this.getOwner() == player && player.isSneaking()){ // Prevents accidental double clicking. if(this.ticksExisted > 20){ for(int i=0;i<10;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, this.posX - this.width/2 + this.rand.nextFloat()*width, this.posY + this.height*this.rand.nextFloat() + 0.2f, this.posZ - this.width/2 + this.rand.nextFloat()*width, 0, 0, 0, 48 + this.rand.nextInt(12), 0.8f, 0.8f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX - this.width/2 + this.rand.nextFloat()*width, this.posY + this.height*this.rand.nextFloat() + 0.2f, this.posZ - this.width/2 + this.rand.nextFloat()*width, 0, 0, 0, 48 + this.rand.nextInt(12), 0.8f, 0.8f, 1.0f); } this.setDead(); - if(WizardData.get(player) != null){ - WizardData.get(player).hasSpiritWolf = false; + if(ExtendedPlayer.get(player) != null){ + ExtendedPlayer.get(player).hasSpiritWolf = false; } - this.playSound(WizardrySounds.SPELL_HEAL, 0.7F, rand.nextFloat() * 0.4F + 1.0F); + this.playSound("wizardry:heal", 0.7F, rand.nextFloat() * 0.4F + 1.0F); // This is necessary to prevent the wand's spell being cast when performing this action. return true; } @@ -123,7 +129,7 @@ public class EntitySpiritWolf extends EntityWolf { } } - return super.processInteract(player, hand, stack); + return super.interact(player); } @Override @@ -132,26 +138,16 @@ public class EntitySpiritWolf extends EntityWolf { return null; } + @Override + protected void func_145780_a(int p_145780_1_, int p_145780_2_, int p_145780_3_, Block p_145780_4_) + { + this.playSound("mob.wolf.step", 0.15F, 1.0F); + } + @Override protected Item getDropItem() { return null; } - - @Override - public ITextComponent getDisplayName(){ - if(getOwner() != null){ - return new TextComponentTranslation(ISummonedCreature.NAMEPLATE_TRANSLATION_KEY, getOwner().getName(), - new TextComponentTranslation("entity." + this.getEntityString() + ".name")); - }else{ - return super.getDisplayName(); - } - } - - @Override - public boolean hasCustomName(){ - // If this returns true, the renderer will show the nameplate when looking directly at the entity - return Wizardry.settings.showSummonedCreatureNames && getOwner() != null; - } } diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityStormElemental.java b/src/main/java/electroblob/wizardry/entity/living/EntityStormElemental.java index 204d95a0..e4aaacbe 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityStormElemental.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityStormElemental.java @@ -1,58 +1,57 @@ package electroblob.wizardry.entity.living; -import java.util.Collections; import java.util.List; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.entity.projectile.EntityLightningDisc; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.ai.EntityAIAttackMelee; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; import net.minecraft.entity.ai.EntityAIWander; import net.minecraft.entity.effect.EntityLightningBolt; -import net.minecraft.init.SoundEvents; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.SoundEvent; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.monster.IMob; +import net.minecraft.util.DamageSource; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -public class EntityStormElemental extends EntitySummonedCreature implements ISpellCaster { - - private double AISpeed = 1.0; - - private EntityAIAttackSpell spellAttackAI = new EntityAIAttackSpell(this, AISpeed, 15f, 30, 0); - - private static final List attack = Collections.singletonList(Spells.lightning_disc); +public class EntityStormElemental extends EntitySummonedCreature +{ + /** Random offset used in floating behaviour */ + private float heightOffset = 0.5F; + + /** ticks until heightOffset is randomized */ + private int heightOffsetUpdateTime; + private int field_70846_g; public EntityStormElemental(World world){ - super(world); - } - - public EntityStormElemental(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ - super(world, x, y, z, caster, lifetime); - // For some reason this can't be in initEntityAI - this.tasks.addTask(0, this.spellAttackAI); - } + super(world); + } - @Override - protected void initEntityAI(){ - - this.tasks.addTask(1, new EntityAIAttackMelee(this, AISpeed, false)); - this.tasks.addTask(2, new EntityAIWander(this, AISpeed)); - this.tasks.addTask(3, new EntityAILookIdle(this)); + public EntityStormElemental(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ + + super(world, x, y, z, caster, lifetime); + this.isImmuneToFire = true; + this.tasks.addTask(1, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(2, new EntityAILookIdle(this)); this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, - 0, false, true, this.getTargetSelector())); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLiving.class, 0, false, true, IMob.mobSelector)); + this.experienceValue = 0; + } - this.setAIMoveSpeed((float)AISpeed); + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() + { + return false; } @Override @@ -60,101 +59,219 @@ public class EntityStormElemental extends EntitySummonedCreature implements ISpe return true; } - @Override - public List getSpells(){ - return attack; - } - - @Override - public SpellModifiers getModifiers(){ - return new SpellModifiers(); - } - - @Override - public Spell getContinuousSpell(){ - return Spells.none; - } - - @Override - public void setContinuousSpell(Spell spell){ - // Doesn't use continuous spells. - } - - @Override - protected void applyEntityAttributes(){ + protected void applyEntityAttributes() + { super.applyEntityAttributes(); - this.getAttributeMap().registerAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(6.0D); - this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(AISpeed); - this.getEntityAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(30.0D); - this.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(16.0D); + this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(6.0D); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(3.0d); + this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(30.0d); + this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(16.0D); } - @Override - protected SoundEvent getAmbientSound(){ - return SoundEvents.ENTITY_BLAZE_AMBIENT; - } + protected void entityInit() + { + super.entityInit(); + this.dataWatcher.addObject(16, new Byte((byte)0)); + } - @Override - protected SoundEvent getHurtSound(){ - return SoundEvents.ENTITY_BLAZE_HURT; - } + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() + { + return "mob.blaze.breathe"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() + { + return "mob.blaze.hit"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() + { + return "mob.blaze.death"; + } - @Override - protected SoundEvent getDeathSound(){ - return SoundEvents.ENTITY_BLAZE_DEATH; - } - - @Override @SideOnly(Side.CLIENT) - public int getBrightnessForRender(float partialTicks){ + public int getBrightnessForRender(float par1) + { return 15728880; } - @Override - public float getBrightness(float partialTicks){ + /** + * Gets how bright this entity is. + */ + public float getBrightness(float par1) + { return 1.0F; } - + @Override - public void onLivingUpdate(){ + public void onSpawn(){ + for(int i=0;i<15;i++){ + float brightness = rand.nextFloat()*0.4f; + if(this.worldObj.isRemote){ + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX - 0.5d + rand.nextDouble(), this.posY + this.height/2 - 0.5d + rand.nextDouble(), this.posZ - 0.5d + rand.nextDouble(), 0, 0.05f, 0, 20 + rand.nextInt(10), brightness, 0.0f, brightness); + } + } + } + + /** + * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons + * use this to react to sunlight and start to burn. + */ + public void onLivingUpdate() + { + if (!this.worldObj.isRemote) + { + /* + if (this.isWet()) + { + this.attackEntityFrom(DamageSource.drown, 1.0F); + } + */ + + --this.heightOffsetUpdateTime; + + if (this.heightOffsetUpdateTime <= 0) + { + this.heightOffsetUpdateTime = 100; + this.heightOffset = 0.5F + (float)this.rand.nextGaussian() * 3.0F; + } + + if (this.getEntityToAttack() != null && this.getEntityToAttack().posY + (double)this.getEntityToAttack().getEyeHeight() > this.posY + (double)this.getEyeHeight() + (double)this.heightOffset) + { + this.motionY += (0.30000001192092896D - this.motionY) * 0.30000001192092896D; + } + } if(this.ticksExisted % 120 == 1){ - this.playSound(WizardrySounds.SPELL_LOOP_WIND, 1.0f, 1.0f); + this.playSound("wizardry:wind", 1.0f, 1.0f); } - if (this.rand.nextInt(24) == 0){ - this.playSound(SoundEvents.ENTITY_BLAZE_BURN, 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F); + if (this.rand.nextInt(24) == 0) + { + this.worldObj.playSoundEffect(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, "fire.fire", 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F); } - // Slow fall - if(!this.onGround && this.motionY < 0.0D){ + if (!this.onGround && this.motionY < 0.0D) + { this.motionY *= 0.6D; } if(worldObj.isRemote){ - for(int i=0; i<2; ++i){ - worldObj.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0, 0); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, worldObj, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.0d, 0.0d, 0.0d, 0, 0, 0, 0); + worldObj.spawnParticle("largesmoke", this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.0d, 0.0d, 0.0d, 0, 0, 0, 0); } for(int i=0; i<10; i++){ float brightness = rand.nextFloat()*0.2f; double dy = this.rand.nextDouble() * (double)this.height; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE_ROTATING, worldObj, this.posX, this.posY + dy, this.posZ, 0, 0, 0, 20 + rand.nextInt(10), 0, brightness, brightness, false, 0.2f + 0.5f*dy); + Wizardry.proxy.spawnParticle(EnumParticleType.BLIZZARD, worldObj, this.posX, this.posY + dy, this.posZ, 0, 0, 0, 20 + rand.nextInt(10), 0, brightness, brightness, false, 0.2f + 0.5f*dy); } } super.onLivingUpdate(); } - - @Override - public void fall(float distance, float damageMultiplier){ - // Immune to fall damage. + + /** + * Basic mob attack. Default to touch of death in EntityCreature. Overridden by each mob to define their attack. + */ + protected void attackEntity(Entity target, float distance) + { + // This is normally the melee attack, but here it is changed to be lightning. + if (this.attackTime <= 0 && distance < 3.0F && target.boundingBox.maxY > this.boundingBox.minY && target.boundingBox.minY < this.boundingBox.maxY) + { + this.attackTime = 50; + + EntityLightningBolt lightning = new EntityLightningBolt(worldObj, this.posX, this.posY, this.posZ); + worldObj.addWeatherEffect(lightning); + } + else if (distance < 30.0F) + { + double dx = target.posX - this.posX; + double dy = target.boundingBox.minY + (double)(target.height / 2.0F) - (this.posY + (double)(this.height / 2.0F)); + double dz = target.posZ - this.posZ; + + if(this.attackTime == 0){ + + this.playSound("wizardry:electricitya", 1.0F, worldObj.rand.nextFloat() * 0.3F + 0.8F); + EntityLightningDisc lightningdisc = new EntityLightningDisc(this.worldObj, this.getCaster() == null ? this : this.getCaster()); + lightningdisc.setPosition(this.posX + this.getLookVec().xCoord, this.posY, this.posZ + this.getLookVec().zCoord); + + lightningdisc.directTowards(target, 0.5f); + + lightningdisc.posY = this.posY + (double)(this.height / 2.0F) + 0.5D; + this.worldObj.spawnEntityInWorld(lightningdisc); + + this.attackTime = 50; + } + + this.rotationYaw = (float)(Math.atan2(dz, dx) * 180.0D / Math.PI) - 90.0F; + this.hasAttacked = true; + } } - + @Override - public void onStruckByLightning(EntityLightningBolt lightning){ - // Immune to lightning. + public void onStruckByLightning(EntityLightningBolt p_70077_1_){ + // Left blank so the storm elemental is immune to lightning. } -} \ No newline at end of file + + /** + * Called when the mob is falling. Calculates and applies fall damage. + */ + protected void fall(float par1) {} + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() + { + return -1; + } + + /** + * Drop 0-2 items of this living's type. @param par1 - Whether this entity has recently been hit by a player. @param + * par2 - Level of Looting used to kill this mob. + */ + protected void dropFewItems(boolean par1, int par2) + { + + } + + public boolean func_70845_n() + { + return (this.dataWatcher.getWatchableObjectByte(16) & 1) != 0; + } + + public void func_70844_e(boolean par1) + { + byte b0 = this.dataWatcher.getWatchableObjectByte(16); + + if (par1) + { + b0 = (byte)(b0 | 1); + } + else + { + b0 &= -2; + } + + this.dataWatcher.updateObject(16, Byte.valueOf(b0)); + } + + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() + { + return true; + } +} diff --git a/src/main/java/electroblob/wizardry/entity/living/EntitySummonedCreature.java b/src/main/java/electroblob/wizardry/entity/living/EntitySummonedCreature.java index 9ed6d48f..e2f8d625 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntitySummonedCreature.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntitySummonedCreature.java @@ -1,42 +1,65 @@ package electroblob.wizardry.entity.living; import java.lang.ref.WeakReference; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; import java.util.UUID; +import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.item.ItemWand; +import io.netty.buffer.ByteBuf; +import net.minecraft.command.IEntitySelector; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityFlying; +import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.monster.IMob; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -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.DamageSource; +import net.minecraft.util.MathHelper; +import net.minecraft.world.EnumDifficulty; +import net.minecraft.world.EnumSkyBlock; import net.minecraft.world.World; -/** Abstract base implementation of {@link ISummonedCreature} which is the superclass to all custom summoned entities - * (i.e. entities that don't extend vanilla/mod creatures). Also serves as an example of how to correctly implement - * the above interface, and includes some non-critical method overrides which should be used for best results (xp, drops, - * and such like). Not to be confused with the old version of EntitySummonedCreature; that system has been replaced. - * @since Wizardry 1.2 - * @author Electroblob */ -public abstract class EntitySummonedCreature extends EntityCreature implements ISummonedCreature { +/** + * This class (formerly EntityMobMod) was originally copied from EntityMob to allow AI to distinguish between + * summoned creatures and mobs, whilst still letting summoned creatures have access to the EntityMob code. It + * was later renamed and generalised to better reflect its purpose, and now all 'sentient' magical entities + * extend this class. The lifetime variable was also factored in so it can be synced automatically, rather than + * bothering with this for every single subclass. In fact, this class now bears little resemblance to EntityMob at all. + *

    + * As of Wizardry 1.1, this class has a despawn method and an onSpawn method which can be overridden to add particles + * and such like. It also now stores the creature's owner. + * @since Wizardry 1.0 + */ +public abstract class EntitySummonedCreature extends EntityCreature implements IEntityAdditionalSpawnData { - // Field implementations - private int lifetime = 600; - private WeakReference casterReference; + /** The lifetime of the summoned creature in ticks. Allows primarily for duration multiplier support, but also + * for example the skeleton legion spell which lasts for 60 seconds instead of the usual 30. Syncing and saving + * is done automatically. As of Wizardry 1.3, despawning is handled in EntitySummonedCreature; see + * {@link EntitySummonedCreature#despawn()} for details. */ + public int lifetime = 600; + + /** The entity that summoned this creature */ + private WeakReference caster; + + /** The UUID of the caster. Note that this is only for loading purposes; during normal updates + * the actual entity instance is stored (so that getEntityByUUID is not called constantly), + * so this will not always be synced (this is why it is private). */ private UUID casterUUID; - // Setter + getter implementations - @Override public int getLifetime(){ return lifetime; } - @Override public void setLifetime(int lifetime){ this.lifetime = lifetime; } - @Override public WeakReference getCasterReference(){ return casterReference; } - @Override public void setCasterReference(WeakReference reference){ casterReference = reference; } - @Override public UUID getCasterUUID() { return casterUUID; } - @Override public void setCasterUUID(UUID uuid) { this.casterUUID = uuid; } + /** The entity selector passed into the new AI methods, if used. */ + protected IEntitySelector targetSelector; /** * Default shell constructor, only used by client. Lifetime defaults arbitrarily to 600, but this doesn't @@ -54,91 +77,360 @@ public abstract class EntitySummonedCreature extends EntityCreature implements I * extending this class (be sure to call super()) so that AI and other things can be added. */ public EntitySummonedCreature(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ + super(world); this.setPosition(x, y, z); - this.casterReference = new WeakReference(caster); + this.caster = new WeakReference(caster); this.experienceValue = 0; this.lifetime = lifetime; + + this.targetSelector = new IEntitySelector(){ + + public boolean isEntityApplicable(Entity entity){ + + // If the target is valid... + if(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; + + //... and is a mob, a summoned creature, a wizard ... + if((entity instanceof IMob || entity instanceof EntitySummonedCreature || (entity instanceof EntityWizard && !(getCaster() instanceof EntityWizard)) + // ... or in the whitelist ... + || Arrays.asList(Wizardry.summonedCreatureTargetsWhitelist).contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))) + // ... and isn't in the blacklist ... + && !Arrays.asList(Wizardry.summonedCreatureTargetsBlacklist).contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))){ + // ... it can be attacked. + return true; + } + } + + return false; + } + }; } - // Implementations + @Override + protected int getExperiencePoints(EntityPlayer player){ + return 0; + } @Override - public void setRevengeTarget(EntityLivingBase entity){ - if(this.shouldRevengeTarget(entity)) super.setRevengeTarget(entity); - } - - @Override - public void onUpdate(){ - super.onUpdate(); - this.updateDelegate(); - } - - @Override - public void onSpawn(){} - - @Override - public void onDespawn(){} - - @Override - public boolean hasParticleEffect() { - return false; - } - - @Override - protected boolean processInteract(EntityPlayer player, EnumHand hand, ItemStack stack) { - // In this case, the delegate method determines whether super is called. - // Rather handily, we can make use of Java's short-circuiting method of evaluating OR statements. - return this.interactDelegate(player, hand, stack) || super.processInteract(player, hand, stack); - } - - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound){ - super.writeEntityToNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound){ - super.readEntityFromNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } - - // Recommended overrides - - @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 boolean canPickUpLoot(){ return false; } - // This vanilla method has nothing to do with the custom onDespawn() method. - @Override protected boolean canDespawn(){ return false; } - - @Override - public boolean canAttackClass(Class entityType){ + public boolean canAttackClass(Class entityType){ // Returns true unless the given entity type is a flying entity and this entity only has melee attacks. + // Overridden mainly to allow the zombie to attack creepers if the config settings allow it. return !EntityFlying.class.isAssignableFrom(entityType) || this.hasRangedAttack(); } - - // TODO: Backport the following two methods to 1.7.10. + @Override - public ITextComponent getDisplayName(){ - if(getCaster() != null){ - return new TextComponentTranslation(NAMEPLATE_TRANSLATION_KEY, getCaster().getName(), - new TextComponentTranslation("entity." + this.getEntityString() + ".name")); - }else{ - return super.getDisplayName(); - } + public void setRevengeTarget(EntityLivingBase entity){ + // Allows the config to prevent minions from revenge-targeting their owners. + if(entity != this.getCaster() || Wizardry.minionRevengeTargeting) super.setRevengeTarget(entity); } - @Override - public boolean hasCustomName(){ - // If this returns true, the renderer will show the nameplate when looking directly at the entity - return Wizardry.settings.showSummonedCreatureNames && getCaster() != null; - } - - // Specific to EntitySummonedCreature, remove if copying - /** Whether this summoned creature has a ranged attack. Used to test whether it should attack flying creatures. */ public abstract boolean hasRangedAttack(); -} \ No newline at end of file + + /** + * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons + * use this to react to sunlight and start to burn. - I still have no idea what the difference between this and + * the plain onUpdate() method is. From what I can gather, onUpdate() always calls this one anyway. + */ + public void onLivingUpdate(){ + + this.updateArmSwingProgress(); + float f = this.getBrightness(1.0F); + + if (f > 0.5F) + { + this.entityAge += 2; + } + + super.onLivingUpdate(); + } + + /** + * Called to update the entity's position/logic. + */ + public void onUpdate(){ + + super.onUpdate(); + + if(this.getCaster() == null && this.casterUUID != null){ + Entity entity = WizardryUtilities.getEntityByUUID(worldObj, casterUUID); + if(entity instanceof EntityLivingBase){ + this.caster = new WeakReference((EntityLivingBase)entity); + } + } + + if(this.ticksExisted == 1){ + this.onSpawn(); + } + + if(this.ticksExisted > this.lifetime && this.lifetime != -1){ + this.despawn(); + } + } + + /** + * Called when this creature has existed for 1 tick, effectively when it has just been spawned. Override + * to add particles, sounds, etc. + */ + public void onSpawn(){} + + /** + * Defaults to just setDead() in EntitySummonedCreature, but is provided to allow subclasses to override this, + * for example to spawn particles. You should always call super() when overriding this method, in case it changes. + * There is no need, therefore, to call setDead() when overriding. + */ + public void despawn(){ + this.setDead(); + } + + // This vanilla method has nothing to do with the custom despawn() method. + @Override + protected boolean canDespawn(){ + return false; + } + + /** + * Finds the closest player within 16 blocks to attack, or null if this Entity isn't interested in attacking + * (Animals, Spiders at day, peaceful PigZombies). + */ + // This was the same in all subclasses that use the old AI, so it might as well be here instead. + protected Entity findPlayerToAttack(){ + + // Thought I may as well use the new AI's attribute system to get the follow range, rather than make a new method. + List entities = WizardryUtilities.getEntitiesWithinRadius(this.getEntityAttribute(SharedMonsterAttributes.followRange).getAttributeValue(), this.posX, this.posY, this.posZ, this.worldObj); + Entity entity = null; + + for(Entity possibleTarget : entities){ + // Decides if current entity should be replaced. + if(entity == null || this.getDistanceToEntity(entity) > this.getDistanceToEntity(possibleTarget)){ + // Decides if new entity is a valid target. + if(this.isValidTarget(possibleTarget) && this.canEntityBeSeen(possibleTarget)){ + entity = possibleTarget; + } + } + } + + return entity; + } + + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource source, float par2) + { + if (this.isEntityInvulnerable()) + { + return false; + } + else if (super.attackEntityFrom(source, par2)) + { + Entity entity = source.getEntity(); + + if (this.riddenByEntity != entity && this.ridingEntity != entity) + { + if (entity != this) + { + this.entityToAttack = entity; + } + + return true; + } + else + { + return true; + } + } + else + { + return false; + } + } + + public boolean attackEntityAsMob(Entity target) + { + float f = (float)this.getEntityAttribute(SharedMonsterAttributes.attackDamage).getAttributeValue(); + int i = 0; + + if (target instanceof EntityLivingBase) + { + f += EnchantmentHelper.getEnchantmentModifierLiving(this, (EntityLivingBase)target); + i += EnchantmentHelper.getKnockbackModifier(this, (EntityLivingBase)target); + } + + boolean flag = target.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getCaster(), DamageType.MAGIC), f); + + if (flag) + { + if (i > 0) + { + target.addVelocity((double)(-MathHelper.sin(this.rotationYaw * (float)Math.PI / 180.0F) * (float)i * 0.5F), 0.1D, (double)(MathHelper.cos(this.rotationYaw * (float)Math.PI / 180.0F) * (float)i * 0.5F)); + this.motionX *= 0.6D; + this.motionZ *= 0.6D; + } + + int j = EnchantmentHelper.getFireAspectModifier(this); + + if (j > 0) + { + target.setFire(j * 4); + } + + if (target instanceof EntityLivingBase) + { + EnchantmentHelper.func_151384_a((EntityLivingBase)target, this); + } + + EnchantmentHelper.func_151385_b(this, target); + } + + return flag; + } + + /** + * Basic mob attack. Defaults to touch of death in EntityCreature. Overridden by each mob to define their attack. + */ + protected void attackEntity(Entity par1Entity, float par2) + { + if (this.attackTime <= 0 && par2 < 2.0F && par1Entity.boundingBox.maxY > this.boundingBox.minY && par1Entity.boundingBox.minY < this.boundingBox.maxY) + { + this.attackTime = 20; + this.attackEntityAsMob(par1Entity); + } + } + + /** + * Takes a coordinate in and returns a weight to determine how likely this creature will try to path to the block. + * Args: x, y, z + */ + public float getBlockPathWeight(int par1, int par2, int par3) + { + return 0.5F - this.worldObj.getLightBrightness(par1, par2, par3); + } + + /** + * Checks to make sure the light is not too bright where the mob is spawning + */ + protected boolean isValidLightLevel() + { + int i = MathHelper.floor_double(this.posX); + int j = MathHelper.floor_double(this.boundingBox.minY); + int k = MathHelper.floor_double(this.posZ); + + if (this.worldObj.getSavedLightValue(EnumSkyBlock.Sky, i, j, k) > this.rand.nextInt(32)) + { + return false; + } + else + { + int l = this.worldObj.getBlockLightValue(i, j, k); + + if (this.worldObj.isThundering()) + { + int i1 = this.worldObj.skylightSubtracted; + this.worldObj.skylightSubtracted = 10; + l = this.worldObj.getBlockLightValue(i, j, k); + this.worldObj.skylightSubtracted = i1; + } + + return l <= this.rand.nextInt(8); + } + } + + /** + * Checks if the entity's current position is a valid location to spawn this entity. + */ + public boolean getCanSpawnHere() + { + return this.worldObj.difficultySetting != EnumDifficulty.PEACEFUL && this.isValidLightLevel() && super.getCanSpawnHere(); + } + + @Override + protected boolean interact(EntityPlayer player) { + + ExtendedPlayer properties = ExtendedPlayer.get(player); + // Selects one of the player's minions. + if(player.isSneaking() && player.getHeldItem() != null && player.getHeldItem().getItem() instanceof ItemWand){ + + if(!player.worldObj.isRemote && properties != null && this.getCaster() == player){ + + if(properties.selectedMinion != null && properties.selectedMinion.get() == this){ + // Deselects the selected minion if right-clicked again + properties.selectedMinion = null; + }else{ + // Selects this minion + properties.selectedMinion = new WeakReference(this); + } + properties.sync(); + } + return true; + } + + return super.interact(player); + } + + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getAttributeMap().registerAttribute(SharedMonsterAttributes.attackDamage); + } + + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound nbttagcompound){ + super.writeEntityToNBT(nbttagcompound); + if(this.getCaster() != null){ + nbttagcompound.setString("casterUUID", this.getCaster().getUniqueID().toString()); + } + nbttagcompound.setInteger("lifetime", lifetime); + } + + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound nbttagcompound){ + super.readEntityFromNBT(nbttagcompound); + String string = nbttagcompound.getString("casterUUID"); + if(WizardryUtilities.verifyUUIDString(string)) casterUUID = UUID.fromString(string); + this.lifetime = nbttagcompound.getInteger("lifetime"); + } + + @Override + public void writeSpawnData(ByteBuf data){ + data.writeInt(lifetime); + } + + @Override + public void readSpawnData(ByteBuf data){ + lifetime = data.readInt(); + } + + /** + * Returns the EntityLivingBase that summoned this creature, or null if it no longer exists. Cases where the + * entity may no longer exist are: entity died or was deleted, mob despawned, player logged out, entity teleported + * to another dimension, or this creature simply had no caster in the first place. + */ + public EntityLivingBase getCaster(){ + return caster == null ? null : caster.get(); + } + + /** + * Sets the EntityLivingBase that summoned this creature to the given caster. This should only be used by subclasses + * wishing to synchronise the caster for use on the client side; this is why it is protected. + */ + protected void setCaster(EntityLivingBase caster){ + this.caster = new WeakReference(caster); + } + + /** + * Shorthand for {@link WizardryUtilities#isValidTarget(Entity, Entity)}, with the owner of this creature as the + * attacker. Also allows subclasses to override it if they wish to do so. + */ + public boolean isValidTarget(Entity target){ + return WizardryUtilities.isValidTarget(this.getCaster(), target); + } +} diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java b/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java index 7123ed28..4a3ca1d8 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityWizard.java @@ -1,37 +1,38 @@ package electroblob.wizardry.entity.living; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Locale; -import java.util.Random; -import java.util.Set; - -import com.google.common.base.Predicate; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.WizardryRegistry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.item.ItemSpellBook; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.registry.WizardryAchievements; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; +import electroblob.wizardry.packet.PacketCastSpell; +import electroblob.wizardry.packet.WizardryPacketHandler; import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WandHelper; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; import io.netty.buffer.ByteBuf; +import net.minecraft.command.IEntitySelector; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityAgeable; import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.IRangedAttackMob; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIArrowAttack; import net.minecraft.entity.ai.EntityAIHurtByTarget; import net.minecraft.entity.ai.EntityAILookAtTradePlayer; import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction; @@ -43,46 +44,27 @@ 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; -import net.minecraft.init.MobEffects; -import net.minecraft.init.SoundEvents; -import net.minecraft.inventory.EntityEquipmentSlot; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagInt; -import net.minecraft.nbt.NBTTagLong; -import net.minecraft.network.datasync.DataParameter; -import net.minecraft.network.datasync.DataSerializers; -import net.minecraft.network.datasync.EntityDataManager; +import net.minecraft.nbt.NBTTagIntArray; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; +import net.minecraft.util.ChatComponentTranslation; import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.ITextComponent; import net.minecraft.village.MerchantRecipe; import net.minecraft.village.MerchantRecipeList; -import net.minecraft.world.DifficultyInstance; import net.minecraft.world.World; -import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.common.util.Constants.NBT; -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 { - +public class EntityWizard extends EntityVillager implements IRangedAttackMob, 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, @@ -91,76 +73,71 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit * 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 - - private EntityAIAttackSpell spellCastingAI = new EntityAIAttackSpell(this, 0.5D, 14.0F, 30, 50); + + private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 0.5D, 20, 50, 14.0F); + + // Note: profession is used as element for wizards. public int textureIndex = 0; - - /** The entity selector passed into the new AI methods. */ - protected Predicate targetSelector; - - /** Copy of EntityVillager's buyingList, renamed to avoid confusion. */ - private MerchantRecipeList trades; - 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 HEAL_COOLDOWN = EntityDataManager.createKey(EntityWizard.class, DataSerializers.VARINT); - /** Data parameter for the wizard's element. */ - private static final DataParameter ELEMENT = EntityDataManager.createKey(EntityWizard.class, DataSerializers.VARINT); - - // Field implementations - private List spells = new ArrayList(4); - private Spell continuousSpell; - - /** A set of the positions of the blocks that are part of this wizard's tower. */ - private Set towerBlocks; - - public EntityWizard(World world){ - super(world); - this.detachHome(); - // For some reason this can't be in initEntityAI - this.tasks.addTask(3, this.spellCastingAI); - } - @Override - protected void entityInit(){ - super.entityInit(); - this.dataManager.register(HEAL_COOLDOWN, -1); - this.dataManager.register(ELEMENT, 0); - } - - @Override - protected void initEntityAI(){ + /** This villager's current customer. */ + private WeakReference buyingPlayer; + + /** The entity selector passed into the new AI methods. */ + protected IEntitySelector targetSelector; - this.tasks.addTask(0, new EntityAISwimming(this)); - this.tasks.addTask(1, new EntityAITradePlayer(this)); - this.tasks.addTask(1, new EntityAILookAtTradePlayer(this)); - this.tasks.addTask(4, new EntityAIRestrictOpenDoor(this)); - this.tasks.addTask(5, new EntityAIOpenDoor(this, true)); - this.tasks.addTask(6, new EntityAIMoveTowardsRestriction(this, 0.6D)); - this.tasks.addTask(7, new EntityAIWatchClosest2(this, EntityPlayer.class, 3.0F, 1.0F)); - this.tasks.addTask(7, new EntityAIWatchClosest2(this, EntityWizard.class, 5.0F, 0.02F)); - this.tasks.addTask(7, new EntityAIWander(this, 0.6D)); - this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityLiving.class, 8.0F)); + /** Initialises the MerchantRecipeList.java */ + private MerchantRecipeList buyingList; + private int timeUntilReset; - this.targetSelector = new Predicate(){ + /** addDefaultEquipmentAndRecipies is called if this is true */ + private boolean updateRecipes; + + /** Last player to trade with this villager, used for aggressivity. */ + private String lastBuyingPlayer; + + /** Index for the heal cooldown field in the datawatcher */ + private static final int healCooldownIndex = 20; + + private int[] spells = new int[4]; + + private int[][] towerBlocks; - public boolean apply(Entity entity){ + public EntityWizard(World par1World) + { + super(par1World); + this.setSize(0.6F, 1.8F); + this.dataWatcher.addObject(healCooldownIndex, 0); + this.getNavigator().setBreakDoors(true); + this.getNavigator().setAvoidsWater(true); + // EntityVillager adds unwanted AI, so this gets rid of it. + this.tasks.taskEntries.clear(); + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(1, new EntityAITradePlayer(this)); + this.tasks.addTask(1, new EntityAILookAtTradePlayer(this)); + this.tasks.addTask(4, new EntityAIRestrictOpenDoor(this)); + this.tasks.addTask(5, new EntityAIOpenDoor(this, true)); + this.tasks.addTask(6, new EntityAIMoveTowardsRestriction(this, 0.6D)); + this.tasks.addTask(7, new EntityAIWatchClosest2(this, EntityPlayer.class, 3.0F, 1.0F)); + this.tasks.addTask(7, new EntityAIWatchClosest2(this, EntityWizard.class, 5.0F, 0.02F)); + this.tasks.addTask(7, new EntityAIWander(this, 0.6D)); + this.tasks.addTask(8, new EntityAIWatchClosest(this, EntityLiving.class, 8.0F)); + + this.targetSelector = new IEntitySelector(){ - // If the target is valid and not invisible... - if(entity != null && !entity.isInvisible() && WizardryUtilities.isValidTarget(EntityWizard.this, entity)){ + public boolean isEntityApplicable(Entity entity){ + + // If the target is valid... + if(entity != null && WizardryUtilities.isValidTarget(EntityWizard.this, entity)){ //... and is a mob, a summoned creature ... - if((entity instanceof IMob || entity instanceof ISummonedCreature + if((entity instanceof IMob || entity instanceof EntitySummonedCreature // ... or in the whitelist ... - || Arrays.asList(Wizardry.settings.summonedCreatureTargetsWhitelist).contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))) + || Arrays.asList(Wizardry.summonedCreatureTargetsWhitelist).contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))) // ... and isn't in the blacklist ... - && !Arrays.asList(Wizardry.settings.summonedCreatureTargetsBlacklist).contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))){ + && !Arrays.asList(Wizardry.summonedCreatureTargetsBlacklist).contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))){ // ... it can be attacked. return true; } @@ -169,579 +146,714 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit return false; } }; + + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + // By default, wizards don't attack players unless the player has attacked them. + this.targetTasks.addTask(0, new EntityAINearestAttackableTarget(this, EntityLiving.class, 0, false, true, this.targetSelector)); + + this.tasks.addTask(3, this.aiArrowAttack); + + this.detachHome(); + } - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); - // By default, wizards don't attack players unless the player has attacked them. - this.targetTasks.addTask(0, new EntityAINearestAttackableTarget(this, EntityLiving.class, 0, false, true, this.targetSelector)); - } + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.5D); + } - @Override - protected void applyEntityAttributes(){ - super.applyEntityAttributes(); - this.getEntityAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.5); - } - - private int getHealCooldown(){ - return this.dataManager.get(HEAL_COOLDOWN); - } - - private void setHealCooldown(int cooldown){ - this.dataManager.set(HEAL_COOLDOWN, cooldown); - } - - public Element getElement(){ - return Element.values()[this.dataManager.get(ELEMENT)]; - } - - public void setElement(Element element){ - this.dataManager.set(ELEMENT, element.ordinal()); - } - - @Override - public List getSpells(){ - return this.spells; - } - - @Override - public SpellModifiers getModifiers(){ - return new SpellModifiers(); - } - - @Override - public void setContinuousSpell(Spell spell){ - this.continuousSpell = spell; - } - - @Override - public Spell getContinuousSpell(){ - return this.continuousSpell; - } - - @Override - public void onLivingUpdate(){ - - super.onLivingUpdate(); - - // Still better to store this to a local variable as it's almost certainly more efficient. - int healCooldown = this.getHealCooldown(); - - // This is now done slightly differently because isPotionActive doesn't work on client here, meaning that when - // affected with arcane jammer and healCooldown == 0, whilst the wizard didn't actually heal or play the sound, - // the particles still spawned, and since healCooldown wasn't reset they spawned every tick until the arcane - // jammer wore off. - if(healCooldown == 0 && this.getHealth() < this.getMaxHealth() && this.getHealth() > 0 && !this.isPotionActive(WizardryPotions.arcane_jammer)){ - - // Healer wizards use greater heal. - this.heal(this.getElement() == Element.HEALING ? 8 : 4); - this.setHealCooldown(-1); - - // deathTime == 0 checks the wizard isn't currently dying - }else if(healCooldown == -1 && this.deathTime == 0){ - - // Heal particles + /** + * Returns true if the newer Entity AI code should be run + */ + public boolean isAIEnabled() + { + return true; + } + + @Override + public void onLivingUpdate(){ + + super.onLivingUpdate(); + + int healCooldown = this.dataWatcher.getWatchableObjectInt(healCooldownIndex); + + // This is now done slightly differently because isPotionActive doesn't work on client here, meaning that when + // affected with arcane jammer and healCooldown == 0, whilst the wizard didn't actually heal or play the sound, + // the particles still spawned, and since healCooldown wasn't reset they spawned every tick until the arcane + // jammer wore off. + if(healCooldown == 0 && this.getHealth() < this.getMaxHealth() && this.getHealth() > 0 && !this.isPotionActive(Wizardry.arcaneJammer)){ + + // Healer wizards use greater heal. + this.heal(this.getProfession() == 7? 8 : 4); + this.dataWatcher.updateObject(healCooldownIndex, -1); + + // deathTime == 0 checks the wizard isn't currently dying + }else if(healCooldown == -1 && this.deathTime == 0){ + + // Heal particles if(worldObj.isRemote){ for(int i=0; i<10; i++){ double d0 = (double)((float)this.posX + rand.nextFloat()*2 - 1.0F); // Apparently the client side spawns the particles 1 block higher than it should... hence the - 0.5F. double d1 = (double)((float)this.posY - 0.5F + rand.nextFloat()); double d2 = (double)((float)this.posZ + rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, d0, d1, d2, 0, 0.1F, 0, 48 + rand.nextInt(12), 1.0f, 1.0f, 0.3f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, d0, d1, d2, 0, 0.1F, 0, 48 + rand.nextInt(12), 1.0f, 1.0f, 0.3f); } }else{ - if(this.getHealth() < 10){ - // Wizard heals himself more often if he has low health - this.setHealCooldown(150); - }else{ - this.setHealCooldown(400); - } - - this.playSound(WizardrySounds.SPELL_HEAL, 0.7F, rand.nextFloat() * 0.4F + 1.0F); + if(this.getHealth() < 10){ + // Wizard heals himself more often if he has low health + this.dataWatcher.updateObject(healCooldownIndex, 150); + }else{ + this.dataWatcher.updateObject(healCooldownIndex, 400); + } + + worldObj.playSoundAtEntity(this, "wizardry:heal", 0.7F, rand.nextFloat() * 0.4F + 1.0F); } - } - - if(healCooldown > 0){ - this.setHealCooldown(healCooldown-1); - } + } + if(healCooldown > 0){// && !worldObj.isRemote){ + this.dataWatcher.updateObject(healCooldownIndex, healCooldown-1); + } + } + + @Override + public void attackEntityWithRangedAttack(EntityLivingBase target, float f){ + + if(f < 30.0F && !this.isPotionActive(Wizardry.arcaneJammer)){ + + double d0 = target.posX - this.posX; + double d1 = target.boundingBox.minY + (double)(target.height / 2.0F) - (this.posY + (double)(this.height / 2.0F)); + double d2 = target.posZ - this.posZ; + + if (this.attackTime == 0 && spells.length > 0){ + + if(!this.worldObj.isRemote){ + + // New way of choosing a spell; keeps trying until one works or all have been tried + + List spellsArray = new ArrayList(spells.length); + + for(int i=0; i 0) + { + --this.timeUntilReset; - if(!this.isTrading() && this.timeUntilReset > 0){ + if (this.timeUntilReset <= 0) + { + if (this.updateRecipes) + { + if (this.buyingList.size() > 1) + { + Iterator iterator = this.buyingList.iterator(); - --this.timeUntilReset; + while (iterator.hasNext()) + { + MerchantRecipe merchantrecipe = (MerchantRecipe)iterator.next(); - if(this.timeUntilReset <= 0){ + if (merchantrecipe.isRecipeDisabled()) + { + // Increases the number of allowed uses of a disabled recipe by a random number. + merchantrecipe.func_82783_a(this.rand.nextInt(6) + this.rand.nextInt(6) + 2); + } + } + } + + if(this.buyingList.size() < 12){ + this.addRandomRecipes(1); + } + this.updateRecipes = false; + } - if(this.updateRecipes){ + this.addPotionEffect(new PotionEffect(Potion.regeneration.id, 200, 0)); + } + } + + // Super call removed because EntityVillager's version does things I don't want and the next one up is + // in EntityLivingBase and does nothing. + } - for(MerchantRecipe merchantrecipe : this.trades){ - - if(merchantrecipe.isRecipeDisabled()){ - // Increases the number of allowed uses of a disabled recipe by a random number. - merchantrecipe.increaseMaxTradeUses(this.rand.nextInt(6) + this.rand.nextInt(6) + 2); - } - } - - if(this.trades.size() < 12){ - this.addRandomRecipes(1); - } - - this.updateRecipes = false; - } - - this.addPotionEffect(new PotionEffect(MobEffects.REGENERATION, 200, 0)); - } - } - - // Super call removed because EntityVillager's version does things I don't want and the next one up is - // in EntityLivingBase and does nothing. - } - - @Override - public boolean processInteract(EntityPlayer player, EnumHand hand, ItemStack stack) { - - // Debugging - //player.addChatComponentMessage(new TextComponentTranslation("wizard.debug", Spell.get(spells[1]).getDisplayName(), Spell.get(spells[2]).getDisplayName(), Spell.get(spells[3]).getDisplayName())); - - // When right-clicked with a spell book in creative, sets one of the spells to that spell - if(player.capabilities.isCreativeMode && stack != null && stack.getItem() instanceof ItemSpellBook){ - if(this.spells.size() >= 4 && Spell.get(stack.getItemDamage()).canBeCastByNPCs()){ - this.spells.set(rand.nextInt(3)+1, Spell.get(stack.getItemDamage())); - return true; - } - } - - // Won't trade with a player that has attacked them. - if (this.isEntityAlive() && !this.isTrading() && !this.isChild() && !player.isSneaking() && this.getAttackTarget() != player) - { - if (!this.worldObj.isRemote) - { - this.setCustomer(player); - player.displayVillagerTradeGui(this); - //player.displayGUIMerchant(this, this.getElement().getWizardName()); - } - - return true; - } - else - { - return false; - } - } - - @Override - public ITextComponent getDisplayName() { - return this.getElement().getWizardName(); - } - - @Override - public void writeEntityToNBT(NBTTagCompound nbt){ - - super.writeEntityToNBT(nbt); - - if (this.trades != null){ - nbt.setTag("trades", this.trades.getRecipiesAsTags()); + /** + * Called when a player interacts with a mob. e.g. gets milk from a cow, gets into the saddle on a pig. + */ + public boolean interact(EntityPlayer player){ + + // Debugging + //player.addChatComponentMessage(new ChatComponentTranslation("wizard.debug", Spell.get(spells[1]).getDisplayName(), Spell.get(spells[2]).getDisplayName(), Spell.get(spells[3]).getDisplayName())); + + ItemStack itemstack = player.inventory.getCurrentItem(); + + // When right-clicked with a spell book in creative, sets one of the spells to that spell + if(player.capabilities.isCreativeMode && itemstack != null && itemstack.getItem() instanceof ItemSpellBook){ + if(Spell.get(itemstack.getItemDamage()).canBeCastByNPCs()){ + this.spells[rand.nextInt(3)+1] = itemstack.getItemDamage(); + return true; + } } - nbt.setInteger("element", this.getElement().ordinal()); - nbt.setInteger("skin", this.textureIndex); - nbt.setTag("spells", WizardryUtilities.listToNBT(spells, spell -> new NBTTagInt(spell.id()))); + // Won't trade with a player that has attacked them. + if (this.isEntityAlive() && !this.isTrading() && !this.isChild() && !player.isSneaking() && this.getAttackTarget() != player) + { + if (!this.worldObj.isRemote) + { + this.setCustomer(player); + player.displayGUIMerchant(this, this.getElement().getWizardName()); + } - if(this.towerBlocks != null && this.towerBlocks.size() > 0){ - nbt.setTag("towerBlocks", WizardryUtilities.listToNBT(this.towerBlocks, pos -> new NBTTagLong(pos.toLong()))); - } - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbt){ - - super.readEntityFromNBT(nbt); - - if(nbt.hasKey("trades")){ - NBTTagCompound nbttagcompound1 = nbt.getCompoundTag("trades"); - this.trades = new MerchantRecipeList(nbttagcompound1); + return true; } + else + { + return false; + } + } - this.setElement(Element.values()[nbt.getInteger("element")]); - this.textureIndex = nbt.getInteger("skin"); - this.spells = (List) WizardryUtilities.NBTToList(nbt.getTagList("spells", NBT.TAG_INT), - (NBTTagInt tag) -> Spell.get(tag.getInt())); + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ + public void writeEntityToNBT(NBTTagCompound tagcompound) + { + super.writeEntityToNBT(tagcompound); + tagcompound.setInteger("Profession", this.getProfession()); + tagcompound.setInteger("skin", this.textureIndex); - this.towerBlocks = new HashSet(WizardryUtilities.NBTToList(nbt.getTagList("towerBlocks", - NBT.TAG_LONG), (NBTTagLong tag) -> BlockPos.fromLong(tag.getLong()))); - } + if (this.buyingList != null) + { + tagcompound.setTag("Offers", this.buyingList.getRecipiesAsTags()); + } + + tagcompound.setIntArray("spells", spells); + + if(this.towerBlocks != null && this.towerBlocks.length > 0){ + + NBTTagList blocks = new NBTTagList(); + + for(int[] block : this.towerBlocks){ + blocks.appendTag(new NBTTagIntArray(block)); + } + + tagcompound.setTag("towerBlocks", blocks); + } + } - @Override - protected boolean canDespawn(){ - return false; - } + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ + public void readEntityFromNBT(NBTTagCompound tagcompound) + { + super.readEntityFromNBT(tagcompound); + this.setProfession(tagcompound.getInteger("Profession")); + this.textureIndex = tagcompound.getInteger("skin"); - @Override - public boolean isTrading() - { - return this.getCustomer() != null; - } + if (tagcompound.hasKey("Offers")) + { + NBTTagCompound nbttagcompound1 = tagcompound.getCompoundTag("Offers"); + this.buyingList = new MerchantRecipeList(nbttagcompound1); + } + + this.spells = tagcompound.getIntArray("spells"); + + NBTTagList blocks = tagcompound.getTagList("towerBlocks", NBT.TAG_INT_ARRAY); + + if(blocks != null){ + + if(this.towerBlocks == null) this.towerBlocks = new int[blocks.tagCount()][3]; + + for(int i=0; i 0){ + this.timeUntilReset = 40; + this.updateRecipes = true; - // Changed to a 4 in 5 chance of unlocking a new recipe. - if(this.rand.nextInt(5) > 0){ - this.timeUntilReset = 40; - this.updateRecipes = true; + if (this.getBuyingPlayer() != null) + { + this.lastBuyingPlayer = this.getBuyingPlayer().getCommandSenderName(); + } + else + { + this.lastBuyingPlayer = null; + } + } + } - if (this.getCustomer() != null) - { - this.getCustomer().getName(); - } - else - { - } - } + public void func_110297_a_(ItemStack par1ItemStack) + { + if (!this.worldObj.isRemote && this.livingSoundTime > -this.getTalkInterval() + 20) + { + this.livingSoundTime = -this.getTalkInterval(); + + if (par1ItemStack != null) + { + this.playSound("mob.villager.yes", this.getSoundVolume(), this.getSoundPitch()); + } + else + { + this.playSound("mob.villager.no", this.getSoundVolume(), this.getSoundPitch()); + } + } + } + + // This is called from the gui in order to display the recipes (no surprise there), and this is actually where + // the initialisation is done, i.e. the trades don't actually exist until some player goes to trade with the + // villager, at which point the first is added. + public MerchantRecipeList getRecipes(EntityPlayer par1EntityPlayer){ + + if(this.buyingList == null){ + + this.buyingList = new MerchantRecipeList(); + + // All wizards will buy spell books + ItemStack anySpellBook = new ItemStack(Wizardry.spellBook, 1, OreDictionary.WILDCARD_VALUE); + ItemStack crystalStack = new ItemStack(Wizardry.magicCrystal, 5); + + this.buyingList.add(new MerchantRecipe(anySpellBook, crystalStack)); + + this.addRandomRecipes(3); + } + + return this.buyingList; + } + + /** + * This is called once on initialisation and then once each time the wizard gains new trades (the particle thingy). + */ + private void addRandomRecipes(int numberOfItemsToAdd){ + + MerchantRecipeList merchantrecipelist; + merchantrecipelist = new MerchantRecipeList(); + + for(int i=0; i spells = Spell.getSpells(new Spell.TierElementFilter(tier, null)); // All enabled spells of the given tier that match this wizard's element List specialismSpells = Spell.getSpells(new Spell.TierElementFilter(tier, this.getElement())); - + // This code is sooooooo much neater with the new filter system! switch(tier){ - + case BASIC: randomiser = rand.nextInt(5); if(randomiser < 4 && !spells.isEmpty()){ - if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){ + if(this.getProfession() > 0 && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){ // This means it is more likely for spell books sold to be of the same element as the wizard if the wizard has an element. - return new ItemStack(WizardryItems.spell_book, 1, specialismSpells.get(rand.nextInt(specialismSpells.size())).id()); + return new ItemStack(Wizardry.spellBook, 1, specialismSpells.get(rand.nextInt(specialismSpells.size())).id()); }else{ - return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).id()); + return new ItemStack(Wizardry.spellBook, 1, spells.get(rand.nextInt(spells.size())).id()); } }else{ - if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){ + if(this.getProfession() > 0 && rand.nextInt(4) > 0){ // This means it is more likely for wands sold to be of the same element as the wizard if the wizard has an element. return new ItemStack(WizardryUtilities.getWand(tier, this.getElement())); }else{ - return new ItemStack(WizardryUtilities.getWand(tier, Element.values()[rand.nextInt(Element.values().length)])); + return new ItemStack(WizardryUtilities.getWand(tier, EnumElement.values()[rand.nextInt(EnumElement.values().length)])); } } - + case APPRENTICE: - randomiser = rand.nextInt(Wizardry.settings.discoveryMode ? 12 : 10); + randomiser = rand.nextInt(Wizardry.discoveryMode ? 12 : 10); if(randomiser < 5 && !spells.isEmpty()){ - if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){ + if(this.getProfession() > 0 && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){ // This means it is more likely for spell books sold to be of the same element as the wizard if the wizard has an element. - return new ItemStack(WizardryItems.spell_book, 1, specialismSpells.get(rand.nextInt(specialismSpells.size())).id()); + return new ItemStack(Wizardry.spellBook, 1, specialismSpells.get(rand.nextInt(specialismSpells.size())).id()); }else{ - return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).id()); + return new ItemStack(Wizardry.spellBook, 1, spells.get(rand.nextInt(spells.size())).id()); } }else if(randomiser < 6){ - if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){ + if(this.getProfession() > 0 && rand.nextInt(4) > 0){ // This means it is more likely for wands sold to be of the same element as the wizard if the wizard has an element. return new ItemStack(WizardryUtilities.getWand(tier, this.getElement())); }else{ - return new ItemStack(WizardryUtilities.getWand(tier, Element.values()[rand.nextInt(Element.values().length)])); + return new ItemStack(WizardryUtilities.getWand(tier, EnumElement.values()[rand.nextInt(EnumElement.values().length)])); } }else if(randomiser < 8){ - return new ItemStack(WizardryItems.arcane_tome, 1, 1); + return new ItemStack(Wizardry.arcaneTome, 1, 1); }else if(randomiser < 10){ - EntityEquipmentSlot slot = WizardryUtilities.ARMOUR_SLOTS[rand.nextInt(WizardryUtilities.ARMOUR_SLOTS.length)]; - if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){ + int slot = rand.nextInt(4); + if(this.getProfession() > 0 && rand.nextInt(4) > 0){ // This means it is more likely for armour sold to be of the same element as the wizard if the wizard has an element. return new ItemStack(WizardryUtilities.getArmour(this.getElement(), slot)); }else{ - return new ItemStack(WizardryUtilities.getArmour(Element.values()[rand.nextInt(Element.values().length)], slot)); + return new ItemStack(WizardryUtilities.getArmour(EnumElement.values()[rand.nextInt(EnumElement.values().length)], slot)); } }else{ // Don't need to check for discovery mode here since it is done above - return new ItemStack(WizardryItems.identification_scroll); + return new ItemStack(Wizardry.identificationScroll); } - + case ADVANCED: randomiser = rand.nextInt(12); if(randomiser < 5 && !spells.isEmpty()){ - if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){ + if(this.getProfession() > 0 && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){ // This means it is more likely for spell books sold to be of the same element as the wizard if the wizard has an element. - return new ItemStack(WizardryItems.spell_book, 1, specialismSpells.get(rand.nextInt(specialismSpells.size())).id()); + return new ItemStack(Wizardry.spellBook, 1, specialismSpells.get(rand.nextInt(specialismSpells.size())).id()); }else{ - return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).id()); + return new ItemStack(Wizardry.spellBook, 1, spells.get(rand.nextInt(spells.size())).id()); } }else if(randomiser < 6){ - if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){ + if(this.getProfession() > 0 && rand.nextInt(4) > 0){ // This means it is more likely for wands sold to be of the same element as the wizard if the wizard has an element. return new ItemStack(WizardryUtilities.getWand(tier, this.getElement())); }else{ - return new ItemStack(WizardryUtilities.getWand(tier, Element.values()[rand.nextInt(Element.values().length)])); + return new ItemStack(WizardryUtilities.getWand(tier, EnumElement.values()[rand.nextInt(EnumElement.values().length)])); } }else if(randomiser < 8){ - return new ItemStack(WizardryItems.arcane_tome, 1, 2); + return new ItemStack(Wizardry.arcaneTome, 1, 2); }else{ - List upgrades = new ArrayList(WandHelper.getSpecialUpgrades()); - randomiser = rand.nextInt(upgrades.size()); - return new ItemStack(upgrades.get(randomiser)); + randomiser = rand.nextInt(8); + switch(randomiser){ + case 0: return new ItemStack(Wizardry.condenserUpgrade); + case 1: return new ItemStack(Wizardry.siphonUpgrade); + case 2: return new ItemStack(Wizardry.storageUpgrade); + case 3: return new ItemStack(Wizardry.rangeUpgrade); + case 4: return new ItemStack(Wizardry.durationUpgrade); + case 5: return new ItemStack(Wizardry.cooldownUpgrade); + case 6: return new ItemStack(Wizardry.blastUpgrade); + case 7: return new ItemStack(Wizardry.attunementUpgrade); + } } - + case MASTER: // If a regular wizard rolls a master trade, it can only be a simple master wand or a tome of arcana - randomiser = this.getElement() != Element.MAGIC ? rand.nextInt(8) : 5 + rand.nextInt(3); - - if(randomiser < 5 && this.getElement() != Element.MAGIC && !specialismSpells.isEmpty()){ + randomiser = this.getProfession() > 0 ? rand.nextInt(8) : 5 + rand.nextInt(3); + + if(randomiser < 5 && this.getProfession() > 0 && !specialismSpells.isEmpty()){ // Master spells can only be sold by a specialist in that element. - return new ItemStack(WizardryItems.spell_book, 1, specialismSpells.get(rand.nextInt(specialismSpells.size())).id()); - + return new ItemStack(Wizardry.spellBook, 1, specialismSpells.get(rand.nextInt(specialismSpells.size())).id()); + }else if(randomiser < 6){ - if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){ + if(this.getProfession() > 0 && rand.nextInt(4) > 0){ // Master elemental wands can only be sold by a specialist in that element. return new ItemStack(WizardryUtilities.getWand(tier, this.getElement())); }else{ - return new ItemStack(WizardryItems.master_wand); + return new ItemStack(Wizardry.masterWand); } }else{ - return new ItemStack(WizardryItems.arcane_tome, 1, 3); + return new ItemStack(Wizardry.arcaneTome, 1, 3); } } - return new ItemStack(Blocks.STONE); - } - - @Override - public void setProfession(VillagerProfession prof) { - // Disables Forge's stuff. + return new ItemStack(Blocks.stone); } - @Override - public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata){ + @SideOnly(Side.CLIENT) + public void setRecipes(MerchantRecipeList par1MerchantRecipeList) {} - livingdata = super.onInitialSpawn(difficulty, livingdata); + public IEntityLivingData onSpawnWithEgg(IEntityLivingData par1EntityLivingData) + { + par1EntityLivingData = super.onSpawnWithEgg(par1EntityLivingData); textureIndex = this.rand.nextInt(6); + + if(rand.nextBoolean()){ + this.setProfession(rand.nextInt(EnumElement.values().length - 1) + 1); + }else{ + this.setProfession(0); + } + + EnumElement e = this.getElement(); + + this.setCurrentItemOrArmor(1, new ItemStack(WizardryUtilities.getArmour(e, 3))); + this.setCurrentItemOrArmor(2, new ItemStack(WizardryUtilities.getArmour(e, 2))); + this.setCurrentItemOrArmor(3, new ItemStack(WizardryUtilities.getArmour(e, 1))); + this.setCurrentItemOrArmor(4, new ItemStack(WizardryUtilities.getArmour(e, 0))); + + // This is the tier of the highest tier spell the wizard has. + EnumTier maxTier = EnumTier.BASIC; + + // Default chance is 0.085f, for reference. + this.setEquipmentDropChance(0, 0.0f); + this.setEquipmentDropChance(1, 0.0f); + this.setEquipmentDropChance(2, 0.0f); + this.setEquipmentDropChance(3, 0.0f); + this.setEquipmentDropChance(4, 0.0f); + + // All wizards know magic missile, even if it is disabled. + spells[0] = WizardryRegistry.magicMissile.id(); + + List npcSpells = Spell.getSpells(Spell.npcSpells); + + for(int i=1; i maxTier.ordinal()) maxTier = tier; + + // Finds all the spells of the chosen tier and element + List list = Spell.getSpells(new Spell.TierElementFilter(tier, element)); + // Keeps only spells which can be cast by NPCs + list.retainAll(npcSpells); + // Removes spells that the wizard already has + for(int j=0; j spells, Element e, int n, Random random){ - - // This is the tier of the highest tier spell added. - Tier maxTier = Tier.BASIC; - - List npcSpells = Spell.getSpells(Spell.npcSpells); - - for(int i=0; i<3; i++){ - - Tier tier; - // If the wizard has no element, it picks a random one each time. - Element element = e == Element.MAGIC ? Element.values()[random.nextInt(Element.values().length)] : e; - - int randomiser = random.nextInt(20); - - // Uses its own special weighting - if(randomiser < 10){ - tier = Tier.BASIC; - }else if(randomiser < 16){ - tier = Tier.APPRENTICE; - }else{ - tier = Tier.ADVANCED; - } - - if(tier.ordinal() > maxTier.ordinal()) maxTier = tier; - - // Finds all the spells of the chosen tier and element - List list = Spell.getSpells(new Spell.TierElementFilter(tier, element)); - // Keeps only spells which can be cast by NPCs - list.retainAll(npcSpells); - // Removes spells that the wizard already has - list.removeAll(spells); - - // Ensures the tier chosen actually has spells in it. (isEmpty() is exactly the same as size() == 0) - if(list.isEmpty()){ - // If there are no spells applicable, tier and element restrictions are removed to give maximum - // possibility of there being an applicable spell. - list = npcSpells; - // Removes spells that the wizard already has - list.removeAll(spells); - } - - // If the list is still empty now, there must be less than 3 enabled spells that can be cast by wizards - // (excluding magic missile). In this case, having empty slots seems reasonable. - if(!list.isEmpty()) spells.add(list.get(random.nextInt(list.size()))); - - } - - return maxTier; - } + public EntityVillager createChild(EntityAgeable par1EntityAgeable) + { + return this.doSomething(par1EntityAgeable); + } @Override public void writeSpawnData(ByteBuf data){ @@ -753,25 +865,33 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit textureIndex = data.readInt(); } - @Override - public boolean attackEntityFrom(DamageSource source, float damage){ - - if(source.getEntity() instanceof EntityPlayer){ - ((EntityPlayer)source.getEntity()).addStat(WizardryAchievements.anger_wizard); - } - - return super.attackEntityFrom(source, damage); + private EntityPlayer getBuyingPlayer() { + return buyingPlayer == null ? null : buyingPlayer.get(); } + private void setBuyingPlayer(EntityPlayer buyingPlayer) { + this.buyingPlayer = new WeakReference(buyingPlayer); + } + + @Override + public boolean attackEntityFrom(DamageSource source, float damage){ + + if(source.getEntity() instanceof EntityPlayer){ + ((EntityPlayer)source.getEntity()).triggerAchievement(Wizardry.angerWizard); + } + + return super.attackEntityFrom(source, damage); + } + /** * Sets the list of blocks that are part of this wizard's tower. If a player breaks any of these blocks, the wizard * will get angry and attack them. - * @param blocks A Set of BlockPos objects representing the blocks in the tower. + * @param blocks An array of coordinate arrays for the blocks in the tower. */ - public void setTowerBlocks(Set blocks){ + public void setTowerBlocks(int[][] blocks){ this.towerBlocks = blocks; } - + /** * Tests whether the block at the given coordinates is part of this wizard's tower. * @param x @@ -779,49 +899,39 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit * @param z * @return */ - public boolean isBlockPartOfTower(BlockPos pos){ - if(this.towerBlocks == null) return false; - // Uses .equals() rather than == so this will work fine. - return this.towerBlocks.contains(pos); + public boolean isBlockPartOfTower(int x, int y, int z){ + + if(this.towerBlocks == null || this.towerBlocks.length <= 0) return false; + + for(int[] block : this.towerBlocks){ + if(block != null && block[0] == x && block[1] == y && block[2] == z) return true; + } + + return false; } - @SubscribeEvent - public static void onBlockBreakEvent(BlockEvent.BreakEvent event){ - // Makes wizards angry if a player breaks a block in their tower - if(!(event.getPlayer() instanceof FakePlayer)){ - - List wizards = WizardryUtilities.getEntitiesWithinRadius(64, event.getPos().getX(), - event.getPos().getY(), event.getPos().getZ(), event.getWorld(), EntityWizard.class); - - if(!wizards.isEmpty()){ - for(EntityWizard wizard : wizards){ - if(wizard.isBlockPartOfTower(event.getPos())){ - wizard.setRevengeTarget(event.getPlayer()); - event.getPlayer().addStat(WizardryAchievements.anger_wizard); - } - } - } - } - } - - // EntityVillager overrides (that don't add features) - - @Override public boolean isMating(){ return false; } - @Override public void setMating(boolean p_70947_1_){} - @Override public void setPlaying(boolean p_70939_1_){} - @Override public boolean isPlaying(){ return false; } - @Override public void setLookingForHome(){} - // 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){} + // Start of EntityVillager overrides + @Override - public void onStruckByLightning(EntityLightningBolt lightningBolt){ - // Restores the normal behaviour, replacing EntityVillager's witch conversion. - this.attackEntityFrom(DamageSource.lightningBolt, 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); - } - + public boolean isMating() + { + return false; + } + + @Override + public void setMating(boolean p_70947_1_){} + + @Override + public void setPlaying(boolean p_70939_1_){} + + @Override + public boolean isPlaying() + { + return false; + } + + @Override + public void setLookingForHome(){} + + } diff --git a/src/main/java/electroblob/wizardry/entity/living/EntityZombieMinion.java b/src/main/java/electroblob/wizardry/entity/living/EntityZombieMinion.java index c1ac3a7a..c343215e 100644 --- a/src/main/java/electroblob/wizardry/entity/living/EntityZombieMinion.java +++ b/src/main/java/electroblob/wizardry/entity/living/EntityZombieMinion.java @@ -1,175 +1,319 @@ package electroblob.wizardry.entity.living; -import java.lang.ref.WeakReference; import java.util.UUID; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; -import net.minecraft.entity.EntityFlying; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.EnumCreatureAttribute; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.ai.EntityAIAttackOnCollide; import net.minecraft.entity.ai.EntityAIHurtByTarget; +import net.minecraft.entity.ai.EntityAILookIdle; import net.minecraft.entity.ai.EntityAIMoveThroughVillage; +import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction; import net.minecraft.entity.ai.EntityAINearestAttackableTarget; -import net.minecraft.entity.monster.EntityZombie; -import net.minecraft.entity.monster.ZombieType; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; +import net.minecraft.entity.ai.EntityAISwimming; +import net.minecraft.entity.ai.EntityAIWander; +import net.minecraft.entity.ai.attributes.AttributeModifier; +import net.minecraft.entity.ai.attributes.IAttributeInstance; +import net.minecraft.entity.monster.EntityMob; +import net.minecraft.entity.monster.IMob; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextComponentTranslation; -import net.minecraft.world.DifficultyInstance; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; -public class EntityZombieMinion extends EntityZombie implements ISummonedCreature { +public class EntityZombieMinion extends EntitySummonedCreature { - // Field implementations - private int lifetime = 600; - private WeakReference casterReference; - private UUID casterUUID; - - // Setter + getter implementations - @Override public int getLifetime(){ return lifetime; } - @Override public void setLifetime(int lifetime){ this.lifetime = lifetime; } - @Override public WeakReference getCasterReference(){ return casterReference; } - @Override public void setCasterReference(WeakReference reference){ casterReference = reference; } - @Override public UUID getCasterUUID() { return casterUUID; } - @Override public void setCasterUUID(UUID uuid) { this.casterUUID = uuid; } - - /** - * Default shell constructor, only used by client. Lifetime defaults arbitrarily to 600, but this doesn't - * matter because the client side entity immediately gets the lifetime value copied over to it by this class - * anyway. When extending this class, you must override this constructor or Minecraft won't like it, but there's - * no need to do anything inside it other than call super(). - */ public EntityZombieMinion(World world){ super(world); - this.experienceValue = 0; } - - /** - * Set lifetime to -1 to allow this creature to last forever. This constructor should be overridden when - * extending this class (be sure to call super()) so that AI and other things can be added. - */ + public EntityZombieMinion(World world, double x, double y, double z, EntityLivingBase caster, int lifetime){ - super(world); - this.setPosition(x, y, z); - this.casterReference = new WeakReference(caster); + + super(world, x, y, z, caster, lifetime); + + // The first number in the AI tasks is priority. + this.getNavigator().setBreakDoors(true); + this.tasks.addTask(0, new EntityAISwimming(this)); + // When it comes to ally system support, EntityMob.class needs to be changed to EntityLivingBase.class + // Parameters: Entity, Target type, move speed, long memory (will keep target even if it can't get to them) + this.tasks.addTask(1, new EntityAIAttackOnCollide(this, EntityLivingBase.class, 1.0D, true)); + this.tasks.addTask(2, new EntityAIMoveTowardsRestriction(this, 1.0D)); + this.tasks.addTask(3, new EntityAIMoveThroughVillage(this, 1.0D, false)); + this.tasks.addTask(4, new EntityAIWander(this, 1.0D)); + this.tasks.addTask(5, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + // A good way of getting it to work with the new AI would be to make an anonymous class implementing + // IEntitySelector in EntitySummonedCreature and feed it in here, changing EntityLiving to EntityLivingBase. + // Also, the reason it uses an entity selector in the first place is because not all IMobs are subclasses of + // EntityMob, namely slimes, ghasts and the enderdragon. + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, 0, false, true, this.targetSelector)); this.experienceValue = 0; - this.lifetime = lifetime; } - - // EntityZombie overrides (EntityZombie is a long class so there are lots of these) - - @Override - protected void applyEntityAI() - { - this.tasks.addTask(6, new EntityAIMoveThroughVillage(this, 1.0D, false)); - this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false)); - this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityLivingBase.class, - 0, false, true, this.getTargetSelector())); - } - - @Override public boolean isChild(){ return false; } - @Override public void setChild(boolean childZombie){} - @Override public ZombieType getZombieType(){ return ZombieType.NORMAL; } - @Override public boolean isVillager(){ return false; } - @Override public net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession getVillagerTypeForge(){ return null; } - @Override protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty){} // They don't have equipment! - @Override public void onKillEntity(EntityLivingBase entityLivingIn){} // Turns villagers to zombies in EntityZombie - @Override protected void startConversion(int ticks){} - @Override public boolean isConverting(){ return false; } - @Override protected void convertToVillager(){} - @Override protected int getConversionTimeBoost(){ return 0; } - @Override public void setChildSize(boolean isChild){} - - // Implementations - @Override - public void setRevengeTarget(EntityLivingBase entity){ - if(this.shouldRevengeTarget(entity)) super.setRevengeTarget(entity); + protected void applyEntityAttributes() + { + super.applyEntityAttributes(); + this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(40.0D); + this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23000000417232513D); + this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(3.0D); } @Override - public void onUpdate(){ - super.onUpdate(); - this.updateDelegate(); + public boolean hasRangedAttack() { + return false; + } + + protected void entityInit() + { + super.entityInit(); + this.getDataWatcher().addObject(12, Byte.valueOf((byte)0)); + this.getDataWatcher().addObject(13, Byte.valueOf((byte)0)); + this.getDataWatcher().addObject(14, Byte.valueOf((byte)0)); + } + + /** + * Returns the current armor value as determined by a call to InventoryPlayer.getTotalArmorValue + */ + public int getTotalArmorValue() + { + int i = super.getTotalArmorValue() + 2; + + if (i > 20) + { + i = 20; + } + + return i; + } + + /** + * Returns true if the newer Entity AI code should be run + */ + protected boolean isAIEnabled() + { + return true; + } + + /** + * If Animal, checks if the age timer is negative + */ + public boolean isChild() + { + return this.getDataWatcher().getWatchableObjectByte(12) == 1; + } + + /** + * Return whether this zombie is a villager. + */ + public boolean isVillager() + { + return this.getDataWatcher().getWatchableObjectByte(13) == 1; + } + + /** + * Set whether this zombie is a villager. + */ + public void setVillager(boolean par1) + { + this.getDataWatcher().updateObject(13, Byte.valueOf((byte)(par1 ? 1 : 0))); } @Override public void onSpawn(){ - this.spawnParticleEffect(); - } - - @Override - public void onDespawn(){ - this.spawnParticleEffect(); - } - - private void spawnParticleEffect(){ if(this.worldObj.isRemote){ for(int i=0;i<15;i++){ - this.worldObj.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.posX + this.rand.nextFloat(), this.posY + 1 + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0, 0, 0); + this.worldObj.spawnParticle("largesmoke", this.posX + this.rand.nextFloat(), this.posY + 1 + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0, 0, 0); } } } @Override - public boolean hasParticleEffect() { - return true; + public void despawn(){ + if(this.worldObj.isRemote){ + for(int i=0;i<15;i++){ + this.worldObj.spawnParticle("largesmoke", this.posX + this.rand.nextFloat(), this.posY + 1 + this.rand.nextFloat(), this.posZ + this.rand.nextFloat(), 0, 0, 0); + } + } + super.despawn(); } - @Override - public boolean processInteract(EntityPlayer player, EnumHand hand, ItemStack stack) { - // In this case, the delegate method determines whether super is called. - // Rather handily, we can make use of Java's 'stop as soon as you find true' method of evaluating OR statements. - return this.interactDelegate(player, hand, stack) || super.processInteract(player, hand, stack); + /** + * Called frequently so the entity can update its state every tick as required. For example, zombies and skeletons + * use this to react to sunlight and start to burn. + */ + public void onLivingUpdate() + { + if (this.worldObj.isDaytime() && !this.worldObj.isRemote && !this.isChild()) + { + float f = this.getBrightness(1.0F); + + if (f > 0.5F && this.rand.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.worldObj.canBlockSeeTheSky(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ))) + { + boolean flag = true; + ItemStack itemstack = this.getEquipmentInSlot(4); + + if (itemstack != null) + { + if (itemstack.isItemStackDamageable()) + { + itemstack.setItemDamage(itemstack.getItemDamageForDisplay() + this.rand.nextInt(2)); + + if (itemstack.getItemDamageForDisplay() >= itemstack.getMaxDamage()) + { + this.renderBrokenItemStack(itemstack); + this.setCurrentItemOrArmor(4, (ItemStack)null); + } + } + + flag = false; + } + + if (flag) + { + this.setFire(8); + } + } + } + + super.onLivingUpdate(); } - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound){ - super.writeEntityToNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } + /** + * Called when the entity is attacked. + */ + public boolean attackEntityFrom(DamageSource par1DamageSource, float par2) + { + if (!super.attackEntityFrom(par1DamageSource, par2)) + { + return false; + } + else + { + EntityLivingBase entitylivingbase = this.getAttackTarget(); - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound){ - super.readEntityFromNBT(nbttagcompound); - this.writeNBTDelegate(nbttagcompound); - } + if (entitylivingbase == null && this.getEntityToAttack() instanceof EntityLivingBase) + { + entitylivingbase = (EntityLivingBase)this.getEntityToAttack(); + } - // Recommended overrides + if (entitylivingbase == null && par1DamageSource.getEntity() instanceof EntityLivingBase) + { + entitylivingbase = (EntityLivingBase)par1DamageSource.getEntity(); + } - @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 boolean canPickUpLoot(){ return false; } - // This vanilla method has nothing to do with the custom despawn() method. - @Override protected boolean canDespawn(){ return false; } - - @Override - public boolean canAttackClass(Class entityType){ - // Returns true unless the given entity type is a flying entity. - return !EntityFlying.class.isAssignableFrom(entityType); - } - - @Override - public ITextComponent getDisplayName(){ - if(getCaster() != null){ - return new TextComponentTranslation(NAMEPLATE_TRANSLATION_KEY, getCaster().getName(), - new TextComponentTranslation("entity." + this.getEntityString() + ".name")); - }else{ - return super.getDisplayName(); + return true; } } @Override - public boolean hasCustomName(){ - // If this returns true, the renderer will show the nameplate when looking directly at the entity - return Wizardry.settings.showSummonedCreatureNames && getCaster() != null; + public boolean attackEntityAsMob(Entity entity) + { + boolean flag = super.attackEntityAsMob(entity); + + if (flag) + { + int i = this.worldObj.difficultySetting.getDifficultyId(); + + if (this.getHeldItem() == null && this.isBurning() && this.rand.nextFloat() < (float)i * 0.3F) + { + entity.setFire(2 * i); + } + } + + return flag; } -} \ No newline at end of file + /** + * Called to update the entity's position/logic. + */ + public void onUpdate() + { + // Adds subtle particle effect while alive + if(this.worldObj.isRemote && rand.nextInt(8) == 0) Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, worldObj, this.posX, this.posY + rand.nextDouble()*1.5, this.posZ, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); + + super.onUpdate(); + } + + /** + * Returns the sound this mob makes while it's alive. + */ + protected String getLivingSound() + { + return "mob.zombie.say"; + } + + /** + * Returns the sound this mob makes when it is hurt. + */ + protected String getHurtSound() + { + return "mob.zombie.hurt"; + } + + /** + * Returns the sound this mob makes on death. + */ + protected String getDeathSound() + { + return "mob.zombie.death"; + } + + /** + * Plays step sound at given x, y, z for the entity + */ + protected void playStepSound(int par1, int par2, int par3, int par4) + { + this.playSound("mob.zombie.step", 0.15F, 1.0F); + } + + /** + * Returns the item ID for the item the mob drops on death. + */ + protected int getDropItemId() + { + return -1; + } + + /** + * Get this Entity's EnumCreatureAttribute + */ + public EnumCreatureAttribute getCreatureAttribute() + { + return EnumCreatureAttribute.UNDEAD; + } + + protected void dropRareDrop(int par1) + { + + } + + /** + * Makes entity wear random armor based on difficulty + */ + protected void addRandomArmor() + { + + } + + @SideOnly(Side.CLIENT) + public void handleHealthUpdate(byte par1) + { + if (par1 == 16) + { + this.worldObj.playSound(this.posX + 0.5D, this.posY + 0.5D, this.posZ + 0.5D, "mob.zombie.remedy", 1.0F + this.rand.nextFloat(), this.rand.nextFloat() * 0.7F + 0.3F, false); + } + else + { + super.handleHealthUpdate(par1); + } + } + +} diff --git a/src/main/java/electroblob/wizardry/entity/living/IIntelligentSpellCaster.java b/src/main/java/electroblob/wizardry/entity/living/IIntelligentSpellCaster.java deleted file mode 100644 index 1bcb7c86..00000000 --- a/src/main/java/electroblob/wizardry/entity/living/IIntelligentSpellCaster.java +++ /dev/null @@ -1,20 +0,0 @@ -package electroblob.wizardry.entity.living; - -import java.util.List; - -import electroblob.wizardry.spell.Spell; - -/** [NYI] Interface for entities that can select between spells based on their current circumstances, to be used in - * conjunction with {@link EntityAISelectSpell}. */ -public interface IIntelligentSpellCaster extends ISpellCaster { - - /** Called from {@link EntityAISelectSpell} to set the spells that the entity can use in its current situation. - * Implementors should assign the given list to some internal field and retrieve it when {@link #getSpells()} is - * called. */ - public void setCurrentSpells(List spells); - - /** Returns a list of spells that this entity 'knows'. The entity's current spell will be selected from this list - * based on the current situation: whether it is attacking, its health, etc. Most likely, you will want to return a - * constant list, but it may change for some reason - perhaps if the entity 'learns' a new spell. */ - public List getKnownSpells(); -} diff --git a/src/main/java/electroblob/wizardry/entity/living/ISpellCaster.java b/src/main/java/electroblob/wizardry/entity/living/ISpellCaster.java deleted file mode 100644 index ce2733df..00000000 --- a/src/main/java/electroblob/wizardry/entity/living/ISpellCaster.java +++ /dev/null @@ -1,61 +0,0 @@ -package electroblob.wizardry.entity.living; - -import java.util.List; - -import javax.annotation.Nonnull; - -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.SpellModifiers; - -/** Interface for entities that can cast spells. Mainly intended for use by wizard-type entities, but can be - * implemented by any subclass of EntityLiving. Designed to be as flexible as possible - ranging from the simplest - * use of giving an entity a specific spell as an attack, to a complex AI which selects different spell types - * depending on the situation. The only restriction is that the spells must be castable by NPCs. - *

    - * This is intended for entities that use {@link EntityAIAttackSpell}. If so, all the spell casting code (including - * packets) is handled by that class, and all the implementor needs to do is decide which spell(s) to select. - *

    - * This class also allows Wizardry to do all the syncing necessary for continuous spell casting. All the implementor - * needs to do is store the actual fields involved. - */ -/* Perhaps this should be a capability? Though I can't help thinking they're mainly for attaching data to vanilla - * classes, rather than custom ones. For now, the main purpose of this is to centralise code within wizardry itself, - * and I may as well make it an API feature - but I'm not writing a capability unless someone sees a reason to attach - * it to a class they don't own, and I don't see that happening anytime soon. */ -// For even more fun, combine this with an ISummonedCreature and have skeletons that can cast spells! -public interface ISpellCaster { - - /** - * Called each time the entity attacks to get the spells that can be cast. For simple implementations, just - * return a list of size one containing the spell that the entity uses as an attack, perhaps performing some - * simple logic within this method. For more intelligent implementations based on spell types, consider using - * {@link IIntelligentSpellCaster} instead. - * @return A list of {@link Spell} instances. A random spell from this list will be cast when the entity attacks. - * The list will not be modified by the AI class and can therefore be an immutable list. The spells in the list - * must be castable by NPCs (i.e. {@link Spell#canBeCastByNPCs()} returns true). - */ - @Nonnull - public List getSpells(); - - /** - * Called each time the entity attacks to get the modifiers to apply to the spell. - * @return A {@link SpellModifiers} object representing the modifiers to apply to the spell. If no modifiers are required, - * pass in an empty {@code SpellModifiers} object. - */ - @Nonnull - public SpellModifiers getModifiers(); - - /** Returns the continuous spell that is currently being cast, or the None spell if there is none. Implementors should simply - * store this as a private field and return it here. Will be synced by the AI class, but whether it is saved to NBT - * is up to you. If the implementing class does not deal with continuous spells, just return {@link Spells#none}. If the - * implementing class only ever uses one continuous spell, do not just return that spell; the field must still - * be stored. */ - @Nonnull - public Spell getContinuousSpell(); - - /** Sets the continuous spell that is currently being cast, or the None spell if there is none. Implementors should simply - * store this as a private field and assign it here. Will be synced by the AI class, but whether it is saved to NBT - * is up to you. If the implementing class does not deal with continuous spells, leave this method blank. */ - public void setContinuousSpell(Spell spell); -} diff --git a/src/main/java/electroblob/wizardry/entity/living/ISummonedCreature.java b/src/main/java/electroblob/wizardry/entity/living/ISummonedCreature.java deleted file mode 100644 index 39c68a28..00000000 --- a/src/main/java/electroblob/wizardry/entity/living/ISummonedCreature.java +++ /dev/null @@ -1,333 +0,0 @@ -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; - -import com.google.common.base.Predicate; - -import electroblob.wizardry.WizardData; -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.WizardryEventHandler; -import electroblob.wizardry.item.ItemWand; -import electroblob.wizardry.util.IElementalDamage; -import electroblob.wizardry.util.IndirectMinionDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.MinionDamage; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; -import io.netty.buffer.ByteBuf; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityList; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.monster.IMob; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.DamageSource; -import net.minecraft.util.EntityDamageSource; -import net.minecraft.util.EntityDamageSourceIndirect; -import net.minecraft.util.EnumHand; -import net.minecraftforge.event.entity.living.LivingAttackEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; - -/** Interface for all summoned creatures. The code for summoned creatures has been overhauled in Wizardry 2.1, and this - * interface allows summoned creatures to extend vanilla (or indeed modded) entity classes, so EntitySummonedZombie - * now extends EntityZombie, for example. This change has two major benefits: - *

    - * - There is no longer any need for separate render classes, because summoned creatures are now instances of vanilla - * types. You don't even need to assign a render class because the supertype should already be assigned the correct one.
    - * - Summoned creature classes are now much more robust when it comes to changes between Minecraft versions, since none - * of the vanilla code needs to be copied. - *

    - * Summoned creatures that do not emulate vanilla entities do not directly implement this interface. Instead, they - * should extend the abstract base implementation, {@link EntitySummonedCreature}. - *

    - * All damage dealt by ISummonedCreature instances is redirected via {@link WizardryEventHandler#onLivingAttackEvent( - * net.minecraftforge.event.entity.living.LivingAttackEvent) WizardryEventHandler.onLivingAttackEvent(LivingAttackEvent)} - * and replaced by an instance of {@link electroblob.wizardry.util.IElementalDamage IElementalDamage} with the summoner - * of that creature as the source rather than the creature itself. This means that kills by summoned creatures register - * as player kills, dropping xp and rare loot. - *

    - * Though this system is a lot better than the previous system, it is not a perfect solution. The old - * EntitySummonedCreature class overrode some methods from Entity in order to add shared functionality, but this cannot - * be done with an interface. To get around this problem, this interface contains 5 delegate methods that do the same - * things, with the aim of centralising as much code as possible, even though it is not automatically applied. - * Implementing classes must override the corresponding methods from Entity, and within them, call the appropriate - * delegate method in this interface. It is impossible to enforce this condition, but the summoned creature will not - * work properly unless it is adhered to. The position of the delegate method call is unimportant, but by convention - * it is usually at the start of the calling method, which avoids it being unintentionally skipped by a return statement. - *

    - * It is recommended that when implementing this interface, you begin by copying {@link EntitySummonedCreature} to ensure - * all the relevant methods are duplicated. You can then change the superclass, override any additional methods and add - * functionality to any that are already overridden. You will always want to override the AI methods at the very least. - *

    - * Due to the limitations of interfaces, some methods that really ought to be protected are public. These are clearly - * marked as 'Internal, DO NOT CALL'. Don't call them, only implement them. - * @since Wizardry 2.1 - * @author Electroblob */ -/* - * Quite honestly, this is not what default methods are really for. However, this is modding, and in modding some - * sacrifices have to be made when it comes to Java style - because adding on to a pre-existing program is not a - * good way of doing this sort of thing anyway, but we have no choice about that! - */ -@Mod.EventBusSubscriber -public interface ISummonedCreature extends IEntityAdditionalSpawnData { - - // Remember that ALL fields are static and final in interfaces, even if they don't explicitly state that. - String NAMEPLATE_TRANSLATION_KEY = "entity.wizardry.summonedcreature.nameplate"; - - // Setters and getters. The subclass fields that these access should be private. - - /** Sets the lifetime of the summoned creature in ticks. */ - void setLifetime(int ticks); - - /** Returns the lifetime of the summoned creature in ticks. Allows primarily for duration multiplier support, but - * also for example the skeleton legion spell which lasts for 60 seconds instead of the usual 30. Syncing and saving - * is done automatically. As of Wizardry 2.1, despawning is handled in ISummonedCreature; see - * {@link ISummonedCreature#onDespawn()} for details. */ - int getLifetime(); - - /** Sets the WeakReference object which refers to the owner of this summoned creature. Internal, don't call - * unless you know what you are doing. */ - void setCasterReference(WeakReference reference); - - /** Returns a WeakReference object which refers to the owner of this summoned creature. Subclasses should store this - * as a private field. This may be null; as such it is preferable to use {@link ISummonedCreature#getCaster()} to get - * the caster object itself. */ - @Nullable - WeakReference getCasterReference(); - - /** Internal, DO NOT CALL. */ - void setCasterUUID(UUID uuid); - /** Internal, DO NOT CALL. This is for loading purposes only and is not usually synchronised. */ - UUID getCasterUUID(); - - /** Returns the EntityLivingBase that summoned this creature, or null if it no longer exists. Cases where the - * entity may no longer exist are: entity died or was deleted, mob despawned, player logged out, entity teleported - * to another dimension, or this creature simply had no caster in the first place. This is the correct method - * to use to get the owner of this summoned creature. */ - @Nullable - default EntityLivingBase getCaster(){ - return getCasterReference() == null ? null : getCasterReference().get(); - } - - // Miscellaneous - - /** - * Called by the server when constructing the spawn packet. - * Data should be added to the provided stream. - * Implementors must call super when overriding. - * - * @param buffer The packet data stream - */ - @Override - default void writeSpawnData(ByteBuf buffer) { - buffer.writeInt(getCaster() != null ? getCaster().getEntityId() : -1); - buffer.writeInt(getLifetime()); - } - - /** - * Called by the client when it receives a Entity spawn packet. - * Data should be read out of the stream in the same way as it was written. - * Implementors must call super when overriding. - * - * @param additionalData The packet data stream - */ - @Override - default void readSpawnData(ByteBuf buffer) { - int id = buffer.readInt(); - // We're on the client side here, so we can safely use Minecraft.getMinecraft().theWorld via proxies. - if(id > -1) setCasterReference(new WeakReference((EntityLivingBase)Wizardry.proxy.getTheWorld().getEntityByID(id))); - setLifetime(buffer.readInt()); - } - - /** - * Shorthand for {@link WizardryUtilities#isValidTarget(Entity, Entity)}, with the owner of this creature as the - * attacker. Also allows implementors to override it if they wish to do so. - */ - default boolean isValidTarget(Entity target){ - return WizardryUtilities.isValidTarget(this.getCaster(), target); - } - - /** Returns a entity selector to be passed into AI methods. Normally, this should not be overridden, but it is - * possible for implementors to override this in order to do something special when selecting a target. */ - default Predicate getTargetSelector(){ - - return new Predicate(){ - - public boolean apply(Entity entity){ - // TODO: Backport invisibility check (also in wizards) - // If the target is valid and not invisible... - 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; - - //... 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))) - // ... and isn't in the blacklist ... - && !Arrays.asList(Wizardry.settings.summonedCreatureTargetsBlacklist).contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))){ - // ... it can be attacked. - return true; - } - } - - return false; - } - }; - } - - /** - * Called when this creature has existed for 1 tick, effectively when it has just been spawned. Normally used - * to add particles, sounds, etc. - */ - void onSpawn(); - - /** - * Called when this summoned creature vanishes. Normally used to add particles, sounds, etc. - */ - void onDespawn(); - - /** Whether this creature should spawn a subtle black swirl particle effect while alive. */ - boolean hasParticleEffect(); - - /** Called from the event handler after the damage change is applied. Does nothing by default, but can be overridden - * to do something when a successful attack is made. This was added because the event-based damage source system - * can cause parts of attackEntityAsMob not to fire, since attackEntityFrom is intercepted and canceled. - *

    - * Usage examples: {@link EntitySliverfishMinion} uses this to summon more silverfish if the target is killed, - * {@link EntitySkeletonMinion} and {@link EntitySpiderMinion} use this to add potion effects to the target. */ - default void onSuccessfulAttack(EntityLivingBase target){}; - - // Delegates - - /** Implementors should call this from writeEntityToNBT. Can be overridden as long as super is called, but there's - * very little point in doing that since anything extra could just be added to writeEntityToNBT anyway. */ - default void writeNBTDelegate(NBTTagCompound tagcompound){ - if(this.getCaster() != null){ - tagcompound.setUniqueId("casterUUID", this.getCaster().getUniqueID()); - } - tagcompound.setInteger("lifetime", getLifetime()); - } - - /** Implementors should call this from readEntityFromNBT. Can be overridden as long as super is called, but there's - * very little point in doing that since anything extra could just be added to readEntityFromNBT anyway. */ - default void readNBTDelegate(NBTTagCompound tagcompound){ - this.setCasterUUID(tagcompound.getUniqueId("casterUUID")); - this.setLifetime(tagcompound.getInteger("lifetime")); - } - - /** Implementors should call this from setRevengeTarget, and call super.setRevengeTarget if and only if this method - * returns true. */ - default boolean shouldRevengeTarget(EntityLivingBase entity){ - // Allows the config to prevent minions from revenge-targeting their owners. - return entity != this.getCaster() || Wizardry.settings.minionRevengeTargeting; - } - - /** Implementors should call this from onUpdate. Can be overridden as long as super is called, but there's - * very little point in doing that since anything extra could just be added to onUpdate anyway. */ - default void updateDelegate(){ - - if(!(this instanceof Entity)) throw new ClassCastException("Implementations of ISummonedCreature must extend Entity!"); - - Entity thisEntity = ((Entity)this); - - if(this.getCaster() == null && this.getCasterUUID() != null){ - Entity entity = WizardryUtilities.getEntityByUUID(thisEntity.worldObj, getCasterUUID()); - if(entity instanceof EntityLivingBase){ - this.setCasterReference(new WeakReference((EntityLivingBase)entity)); - } - } - - if(thisEntity.ticksExisted == 1){ - this.onSpawn(); - } - - if(thisEntity.ticksExisted > this.getLifetime() && this.getLifetime() != -1){ - this.onDespawn(); - thisEntity.setDead(); - } - - if(this.hasParticleEffect() && thisEntity.worldObj.isRemote && thisEntity.worldObj.rand.nextInt(8) == 0) - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, thisEntity.worldObj, thisEntity.posX, thisEntity.posY + thisEntity.worldObj.rand.nextDouble()*1.5, thisEntity.posZ, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); - - } - - /** Implementors should call this from processInteract, and call super.processInteract if and only if this method - * returns false. */ - default boolean interactDelegate(EntityPlayer player, EnumHand hand, ItemStack stack) { - - WizardData properties = WizardData.get(player); - // Selects one of the player's minions. - if(player.isSneaking() && stack != null && stack.getItem() instanceof ItemWand){ - - if(!player.worldObj.isRemote && properties != null && this.getCaster() == player){ - - if(properties.selectedMinion != null && properties.selectedMinion.get() == this){ - // Deselects the selected minion if right-clicked again - properties.selectedMinion = null; - }else{ - // Selects this minion - properties.selectedMinion = new WeakReference(this); - } - properties.sync(); - } - return true; - } - - return false; - } - - // Damage system - - @SubscribeEvent - public static void onLivingAttackEvent(LivingAttackEvent event){ - - // Rather than bother overriding entire attack methods in ISummonedCreature implementations, it's easier (and - // more robust) to use LivingAttackEvent to modify the damage source. - if(event.getSource().getEntity() instanceof ISummonedCreature){ - - EntityLivingBase summoner = ((ISummonedCreature)event.getSource().getEntity()).getCaster(); - - if(summoner != null){ - - event.setCanceled(true); - DamageSource newSource = event.getSource(); - // Copies over the original DamageType if appropriate. - DamageType type = event.getSource() instanceof IElementalDamage ? ((IElementalDamage)event.getSource()).getType() : DamageType.MAGIC; - // Copies over the original isRetaliatory flag if appropriate. - boolean isRetaliatory = event.getSource() instanceof IElementalDamage && ((IElementalDamage)event.getSource()).isRetaliatory(); - - // All summoned creatures are classified as magic, so it makes sense to do it this way. - if(event.getSource() instanceof EntityDamageSourceIndirect){ - newSource = new IndirectMinionDamage(event.getSource().damageType, event.getSource().getSourceOfDamage(), event.getSource().getEntity(), summoner, type, isRetaliatory); - }else if(event.getSource() instanceof EntityDamageSource){ - // Name is copied over so it uses the appropriate vanilla death message - newSource = new MinionDamage(event.getSource().damageType, event.getSource().getEntity(), summoner, type, isRetaliatory); - } - - // Copy over any relevant 'attributes' the original DamageSource might have had. - if(event.getSource().isExplosion()) newSource.setExplosion(); - 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 - // is unnoticeable, but it looks a bit weird with summoned creatures involved - so this fixes that. - if(WizardryUtilities.attackEntityWithoutKnockback(event.getEntity(), newSource, event.getAmount())){ - WizardryUtilities.applyStandardKnockback(event.getSource().getEntity(), event.getEntityLiving()); - ((ISummonedCreature)event.getSource().getEntity()).onSuccessfulAttack(event.getEntityLiving()); - } - - } - } - } - -} diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityBomb.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityBomb.java deleted file mode 100644 index f383ca21..00000000 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityBomb.java +++ /dev/null @@ -1,59 +0,0 @@ -package electroblob.wizardry.entity.projectile; - -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 - * allow for the spread of particles to be changed depending on the blast area. - * @author Electroblob - * @since Wizardry 1.2 - */ -public abstract class EntityBomb extends EntityMagicProjectile implements IEntityAdditionalSpawnData { - - /** The entity blast multiplier. This is now synced and saved centrally from {@link EntityBomb}. */ - public float blastMultiplier = 1.0f; - - public EntityBomb(World world) { - super(world); - } - - public EntityBomb(World world, EntityLivingBase thrower) { - super(world, thrower); - } - - public EntityBomb(World world, EntityLivingBase thrower, float damageMultiplier, float blastMultiplier) { - super(world, thrower, damageMultiplier); - this.blastMultiplier = blastMultiplier; - } - - public EntityBomb(World par1World, double par2, double par4, double par6) { - super(par1World, par2, par4, par6); - } - - @Override - public void writeSpawnData(ByteBuf buffer) { - buffer.writeFloat(blastMultiplier); - } - - @Override - public void readSpawnData(ByteBuf buffer) { - blastMultiplier = buffer.readFloat(); - } - - @Override - public void readEntityFromNBT(NBTTagCompound nbttagcompound){ - super.readEntityFromNBT(nbttagcompound); - blastMultiplier = nbttagcompound.getFloat("blastMultiplier"); - } - - @Override - public void writeEntityToNBT(NBTTagCompound nbttagcompound){ - super.writeEntityToNBT(nbttagcompound); - nbttagcompound.setFloat("blastMultiplier", blastMultiplier); - } - -} diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityDarknessOrb.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityDarknessOrb.java index 1ba45a28..2c2947af 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityDarknessOrb.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityDarknessOrb.java @@ -1,15 +1,16 @@ package electroblob.wizardry.entity.projectile; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.MobEffects; -import net.minecraft.init.SoundEvents; +import net.minecraft.entity.boss.EntityWither; +import net.minecraft.entity.monster.EntitySkeleton; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; public class EntityDarknessOrb extends EntityMagicProjectile @@ -34,25 +35,28 @@ public class EntityDarknessOrb extends EntityMagicProjectile super(par1World, par2, par4, par6); } - @Override - protected float getSpeed(){ + /** This is the speed */ + protected float func_70182_d() + { return 0.5F; } - @Override - protected void onImpact(RayTraceResult RayTraceResult) + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected void onImpact(MovingObjectPosition movingobjectposition) { - Entity target = RayTraceResult.entityHit; + Entity target = movingobjectposition.entityHit; if (target != null && !MagicDamage.isEntityImmune(DamageType.WITHER, target)) { float damage = 8 * damageMultiplier; - target.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.WITHER).setProjectile(), damage); + target.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getThrower(), DamageType.WITHER).setProjectile(), damage); - if(target instanceof EntityLivingBase && !MagicDamage.isEntityImmune(DamageType.WITHER, target)) ((EntityLivingBase)target).addPotionEffect(new PotionEffect(MobEffects.WITHER, 150, 1)); + if(target instanceof EntityLivingBase && !MagicDamage.isEntityImmune(DamageType.WITHER, target)) ((EntityLivingBase)target).addPotionEffect(new PotionEffect(Potion.wither.id, 150, 1)); - this.playSound(SoundEvents.ENTITY_WITHER_HURT, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + this.playSound("mob.wither.hurt", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); } this.setDead(); @@ -64,8 +68,8 @@ public class EntityDarknessOrb extends EntityMagicProjectile if(worldObj.isRemote){ float brightness = rand.nextFloat()*0.2f; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0, 0, 20 + rand.nextInt(10), brightness, 0.0f, brightness); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, worldObj, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0, 0, 0, 20 + rand.nextInt(10), brightness, 0.0f, brightness); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, worldObj, this.posX + (this.rand.nextDouble() - 0.5D) * (double)this.width, this.posY + this.rand.nextDouble() * (double)this.height, this.posZ + (this.rand.nextDouble() - 0.5D) * (double)this.width, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); } if(this.ticksExisted > 150){ diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityDart.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityDart.java index 3625f995..5dfb24b4 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityDart.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityDart.java @@ -1,12 +1,11 @@ package electroblob.wizardry.entity.projectile; +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.MobEffects; -import net.minecraft.init.SoundEvents; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.world.World; @@ -42,20 +41,20 @@ public class EntityDart extends EntityMagicArrow @Override public void onEntityHit(EntityLivingBase entityHit){ //Adds a weakness effect to the target. - entityHit.addPotionEffect(new PotionEffect(MobEffects.WEAKNESS, 200, 1, false, false)); - this.playSound(SoundEvents.ENTITY_GENERIC_HURT, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + entityHit.addPotionEffect(new PotionEffect(Potion.weakness.id, 200, 1, true)); + this.playSound("game.neutral.hurt", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); } @Override public void onBlockHit(){ - this.playSound(SoundEvents.ENTITY_ARROW_HIT, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + this.playSound("random.bowhit", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); } @Override public void tickInAir(){ if(this.worldObj.isRemote){ - Wizardry.proxy.spawnParticle(WizardryParticleType.LEAF, worldObj, this.posX, this.posY, this.posZ, 0, -0.03, 0, 10 + rand.nextInt(5)); + Wizardry.proxy.spawnParticle(EnumParticleType.LEAF, worldObj, this.posX, this.posY, this.posZ, 0, -0.03, 0, 10 + rand.nextInt(5)); } } diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityFirebolt.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityFirebolt.java index ed8c5c0f..1f87ae6e 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityFirebolt.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityFirebolt.java @@ -1,12 +1,10 @@ package electroblob.wizardry.entity.projectile; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.SoundEvents; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; public class EntityFirebolt extends EntityMagicProjectile @@ -30,27 +28,38 @@ public class EntityFirebolt extends EntityMagicProjectile { super(par1World, par2, par4, par6); } - + + /** This is the speed */ @Override - protected void onImpact(RayTraceResult rayTrace) + protected float func_70182_d() { - Entity entityHit = rayTrace.entityHit; + return 2.5F; + } + + /** + * Called when this EntityThrowable hits a block or entity. + */ + @Override + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) + { + Entity entityHit = par1MovingObjectPosition.entityHit; if (entityHit != null) { float damage = 5 * damageMultiplier; - entityHit.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.FIRE).setProjectile(), damage); + entityHit.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getThrower(), DamageType.FIRE).setProjectile(), damage); if(!MagicDamage.isEntityImmune(DamageType.FIRE, entityHit)) entityHit.setFire(5); } - this.playSound(SoundEvents.BLOCK_LAVA_POP, 2, 0.8f + rand.nextFloat()*0.3f); + this.playSound("liquid.lavapop", 2, 0.8f + rand.nextFloat()*0.3f); // Particle effect if(worldObj.isRemote){ for(int i=0;i<8;i++){ - worldObj.spawnParticle(EnumParticleTypes.LAVA, this.posX + rand.nextFloat() - 0.5, this.posY + this.height/2 + rand.nextFloat() - 0.5, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0); + //Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySparkFX(worldObj, this.posX + rand.nextFloat() - 0.5, this.posY + this.height/2 + rand.nextFloat() - 0.5, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0)); + worldObj.spawnParticle("lava", this.posX + rand.nextFloat() - 0.5, this.posY + this.height/2 + rand.nextFloat() - 0.5, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0); } } @@ -64,7 +73,7 @@ public class EntityFirebolt extends EntityMagicProjectile if(worldObj.isRemote){ for(int i=0; i<4; i++){ - worldObj.spawnParticle(EnumParticleTypes.FLAME, this.posX + rand.nextFloat()*0.2 - 0.1, this.posY + this.height/2 + rand.nextFloat()*0.2 - 0.1, this.posZ + rand.nextFloat()*0.2 - 0.1, 0, 0, 0); + worldObj.spawnParticle("flame", this.posX + rand.nextFloat()*0.2 - 0.1, this.posY + this.height/2 + rand.nextFloat()*0.2 - 0.1, this.posZ + rand.nextFloat()*0.2 - 0.1, 0, 0, 0); } } diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityFirebomb.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityFirebomb.java index 637fe5e8..0270bd17 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityFirebomb.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityFirebomb.java @@ -2,19 +2,24 @@ package electroblob.wizardry.entity.projectile; import java.util.List; +import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; +import io.netty.buffer.ByteBuf; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.SoundEvents; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; -public class EntityFirebomb extends EntityBomb { +public class EntityFirebomb extends EntityMagicProjectile implements IEntityAdditionalSpawnData +{ + /** The entity blast multiplier. Only some projectiles cause a blast, which is why this isn't in EntityMagicProjectile. */ + public float blastMultiplier = 1.0f; public EntityFirebomb(World par1World) { @@ -28,7 +33,8 @@ public class EntityFirebomb extends EntityBomb { public EntityFirebomb(World par1World, EntityLivingBase par2EntityLivingBase, float damageMultiplier, float blastMultiplier) { - super(par1World, par2EntityLivingBase, damageMultiplier, blastMultiplier); + super(par1World, par2EntityLivingBase, damageMultiplier); + this.blastMultiplier = blastMultiplier; } public EntityFirebomb(World par1World, double par2, double par4, double par6) @@ -39,34 +45,34 @@ public class EntityFirebomb extends EntityBomb { /** * Called when this EntityThrowable hits a block or entity. */ - protected void onImpact(RayTraceResult par1RayTraceResult) + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - Entity entityHit = par1RayTraceResult.entityHit; + Entity entityHit = par1MovingObjectPosition.entityHit; if (entityHit != null) { // This is if the firebomb gets a direct hit float damage = 5 * damageMultiplier; - entityHit.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.FIRE).setProjectile(), damage); + entityHit.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getThrower(), DamageType.FIRE).setProjectile(), damage); if(!MagicDamage.isEntityImmune(DamageType.FIRE, entityHit)) entityHit.setFire(10); } // Particle effect if(worldObj.isRemote){ - this.worldObj.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0); + this.worldObj.spawnParticle("largeexplode", this.posX, this.posY, this.posZ, 0, 0, 0); for(int i=0;i<60*blastMultiplier;i++){ - //this.worldObj.spawnParticle(EnumParticleTypes.FLAME, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0, 0, 0); - Wizardry.proxy.spawnParticle(WizardryParticleType.MAGIC_FIRE, worldObj, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0, 0, 0, 15 + rand.nextInt(5), 2 + rand.nextFloat(), 0, 0); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, worldObj, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0.0d, 0.0d, 0.0d, 0, 1.0f, 0.2f + rand.nextFloat()*0.4f, 0.0f); + //this.worldObj.spawnParticle("flame", this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.MAGIC_FIRE, worldObj, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0, 0, 0, 15 + rand.nextInt(5), 2 + rand.nextFloat(), 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, worldObj, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0.0d, 0.0d, 0.0d, 0, 1.0f, 0.2f + rand.nextFloat()*0.4f, 0.0f); } } if(!this.worldObj.isRemote){ - this.playSound(SoundEvents.ENTITY_SPLASH_POTION_BREAK, 1.5F, rand.nextFloat() * 0.4F + 0.6F); - this.playSound(SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1); + this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "game.potion.smash", 1.5F, rand.nextFloat() * 0.4F + 0.6F); + if(!worldObj.isRemote) worldObj.playAuxSFX(1009, (int)this.posX, (int)this.posY, (int)this.posZ, 0); double range = 3.0d*blastMultiplier; @@ -75,7 +81,7 @@ public class EntityFirebomb extends EntityBomb { for(EntityLivingBase target : targets){ if(target != entityHit && target != this.getThrower() && !MagicDamage.isEntityImmune(DamageType.FIRE, target)){ // Splash damage does not count as projectile damage - target.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.FIRE), 4.0f * damageMultiplier); + target.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getThrower(), DamageType.FIRE), 4.0f * damageMultiplier); target.setFire(7); } } @@ -83,5 +89,26 @@ public class EntityFirebomb extends EntityBomb { this.setDead(); } } - + + @Override + public void writeSpawnData(ByteBuf buffer) { + buffer.writeFloat(blastMultiplier); + } + + @Override + public void readSpawnData(ByteBuf buffer) { + blastMultiplier = buffer.readFloat(); + } + + @Override + public void readEntityFromNBT(NBTTagCompound nbttagcompound){ + super.readEntityFromNBT(nbttagcompound); + blastMultiplier = nbttagcompound.getFloat("blastMultiplier"); + } + + @Override + public void writeEntityToNBT(NBTTagCompound nbttagcompound){ + super.writeEntityToNBT(nbttagcompound); + nbttagcompound.setFloat("blastMultiplier", blastMultiplier); + } } diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityForceArrow.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityForceArrow.java index 0cf2ec6d..aba9a5a5 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityForceArrow.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityForceArrow.java @@ -1,9 +1,8 @@ package electroblob.wizardry.entity.projectile; -import electroblob.wizardry.util.MagicDamage.DamageType; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.SoundEvents; import net.minecraft.world.World; public class EntityForceArrow extends EntityMagicArrow { @@ -37,7 +36,7 @@ public class EntityForceArrow extends EntityMagicArrow { @Override public void onEntityHit(EntityLivingBase entityHit){ - this.playSound(SoundEvents.ENTITY_FIREWORK_BLAST, 1.0F, 1.0F); + this.playSound("fireworks.blast", 1.0F, 1.0F); } @Override @@ -47,7 +46,7 @@ public class EntityForceArrow extends EntityMagicArrow { @Override public void onBlockHit(){ - this.playSound(SoundEvents.ENTITY_FIREWORK_BLAST, 1.0F, 1.0F); + this.playSound("fireworks.blast", 1.0F, 1.0F); } @Override diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityForceOrb.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityForceOrb.java index 9a4eaa7e..f842abfc 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityForceOrb.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityForceOrb.java @@ -2,22 +2,21 @@ package electroblob.wizardry.entity.projectile; import java.util.List; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; +import electroblob.wizardry.client.particle.EntitySparkleFX; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.SoundEvents; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; public class EntityForceOrb extends EntityMagicProjectile { - /** The entity blast multiplier. In this particular case, it doesn't need syncing, so this class doesn't extend - * EntityBlastProjectile. */ + /** The entity blast multiplier. Only some projectiles cause a blast, which is why this isn't in EntityMagicProjectile. */ public float blastMultiplier; public EntityForceOrb(World par1World) @@ -44,32 +43,32 @@ public class EntityForceOrb extends EntityMagicProjectile { /** * Called when this EntityThrowable hits a block or entity. */ - protected void onImpact(RayTraceResult par1RayTraceResult){ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition){ - if (par1RayTraceResult.entityHit != null) + if (par1MovingObjectPosition.entityHit != null) { // This is if the force orb gets a direct hit - this.playSound(SoundEvents.ENTITY_GENERIC_HURT, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + this.playSound("game.neutral.hurt", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); } // Particle effect if(this.worldObj.isRemote){ + this.worldObj.spawnParticle("largeexplode", this.posX, this.posY, this.posZ, 0, 0, 0); for(int j=0; j<20; j++){ float brightness = 0.5f + (rand.nextFloat()/2); double x = this.posX - 0.25d + (rand.nextDouble()/2); double y = this.posY - 0.25d + (rand.nextDouble()/2); double z = this.posZ - 0.25d + (rand.nextDouble()/2); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, x, y, z, (x - this.posX)*2, (y - this.posY)*2, (z - this.posZ)*2, 6, brightness, 1.0f, brightness + 0.2f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, x, y, z, (x - this.posX)*2, (y - this.posY)*2, (z - this.posZ)*2, 6, brightness, 1.0f, brightness + 0.2f); } - this.worldObj.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0); } if(!this.worldObj.isRemote){ // 2 gives a cool flanging effect! float pitch = this.rand.nextFloat() * 0.2F + 0.3F; - this.playSound(SoundEvents.ENTITY_FIREWORK_BLAST, 1.5F, pitch); - this.playSound(SoundEvents.ENTITY_FIREWORK_BLAST, 1.5F, pitch - 0.01f); + this.playSound("fireworks.blast", 1.5F, pitch); + this.playSound("fireworks.blast", 1.5F, pitch - 0.01f); double blastRadius = 4.0d*blastMultiplier; @@ -78,14 +77,16 @@ public class EntityForceOrb extends EntityMagicProjectile { for(EntityLivingBase target : targets){ if(target != this.getThrower()){ + double velX = target.motionX; double velY = target.motionY; + double velZ = target.motionZ; double dx = this.posX-target.posX > 0? -0.5 - (this.posX-target.posX)/8 : 0.5 - (this.posX-target.posX)/8; double dz = this.posZ-target.posZ > 0? -0.5 - (this.posZ-target.posZ)/8 : 0.5 - (this.posZ-target.posZ)/8; float damage = 4*damageMultiplier; - target.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.BLAST), damage); + target.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getThrower(), DamageType.BLAST), damage); target.motionX = dx; target.motionY = velY + 0.4; diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityIceCharge.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityIceCharge.java index ce5c9907..b9dc8c9e 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityIceCharge.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityIceCharge.java @@ -2,24 +2,25 @@ package electroblob.wizardry.entity.projectile; import java.util.List; +import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; +import io.netty.buffer.ByteBuf; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.Blocks; -import net.minecraft.init.SoundEvents; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; -public class EntityIceCharge extends EntityBomb { +public class EntityIceCharge extends EntityMagicProjectile implements IEntityAdditionalSpawnData +{ + /** The entity blast multiplier. Only some projectiles cause a blast, which is why this isn't in EntityMagicProjectile. */ + public float blastMultiplier; public EntityIceCharge(World par1World) { @@ -33,7 +34,8 @@ public class EntityIceCharge extends EntityBomb { public EntityIceCharge(World par1World, EntityLivingBase par2EntityLivingBase, float damageMultiplier, float blastMultiplier) { - super(par1World, par2EntityLivingBase, damageMultiplier, blastMultiplier); + super(par1World, par2EntityLivingBase, damageMultiplier); + this.blastMultiplier = blastMultiplier; } public EntityIceCharge(World par1World, double par2, double par4, double par6) @@ -44,35 +46,35 @@ public class EntityIceCharge extends EntityBomb { /** * Called when this EntityThrowable hits a block or entity. */ - protected void onImpact(RayTraceResult par1RayTraceResult) + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - Entity entityHit = par1RayTraceResult.entityHit; + Entity entityHit = par1MovingObjectPosition.entityHit; if (entityHit != null) { // This is if the ice charge gets a direct hit float damage = 4 * damageMultiplier; - entityHit.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.FROST).setProjectile(), damage); + entityHit.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getThrower(), DamageType.FROST).setProjectile(), damage); if(entityHit instanceof EntityLivingBase && !MagicDamage.isEntityImmune(DamageType.FROST, entityHit)) - ((EntityLivingBase)entityHit).addPotionEffect(new PotionEffect(WizardryPotions.frost, 120, 1)); + ((EntityLivingBase)entityHit).addPotionEffect(new PotionEffect(Wizardry.frost.id, 120, 1)); } // Particle effect if(worldObj.isRemote){ - this.worldObj.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0); + this.worldObj.spawnParticle("largeexplode", this.posX, this.posY, this.posZ, 0, 0, 0); for(int i=0;i<30*blastMultiplier;i++){ float brightness = 0.4f + rand.nextFloat()*0.5f; - Wizardry.proxy.spawnParticle(WizardryParticleType.ICE, worldObj, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0.0d, 0.0d, 0.0d, 35); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, worldObj, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0.0d, 0.0d, 0.0d, 0, brightness, brightness+0.1f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.ICE, worldObj, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0.0d, 0.0d, 0.0d, 35); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, worldObj, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0.0d, 0.0d, 0.0d, 0, brightness, brightness+0.1f, 1.0f); } } if(!this.worldObj.isRemote){ - this.playSound(SoundEvents.ENTITY_SPLASH_POTION_BREAK, 1.5f, rand.nextFloat() * 0.4f + 0.6f); - this.playSound(WizardrySounds.SPELL_ICE, 1.2f, rand.nextFloat() * 0.4f + 1.2f); + this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "random.glass", 1.5f, rand.nextFloat() * 0.4f + 0.6f); + this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "wizardry:ice", 1.2f, rand.nextFloat() * 0.4f + 1.2f); double radius = 3.0d*blastMultiplier; @@ -81,30 +83,21 @@ public class EntityIceCharge extends EntityBomb { // Slows targets for(EntityLivingBase target : targets){ if(target != entityHit && target != this.getThrower()){ - if(!MagicDamage.isEntityImmune(DamageType.FROST, target)) target.addPotionEffect(new PotionEffect(WizardryPotions.frost, 100, 0)); + if(!MagicDamage.isEntityImmune(DamageType.FROST, target)) target.addPotionEffect(new PotionEffect(Wizardry.frost.id, 100, 0, true)); } } // Places snow and ice on ground. for(int i=-1; i<2; i++){ for(int j=-1; j<2; j++){ - - BlockPos pos = new BlockPos(this.posX + i, this.posY, this.posZ + j); - - int y = WizardryUtilities.getNearestFloorLevelB(worldObj, pos, 7); - - pos = new BlockPos(pos.getX(), y, pos.getZ()); - - double dist = this.getDistance(pos.getX(), pos.getY(), pos.getZ()); - + int y = WizardryUtilities.getNearestFloorLevelB(worldObj, (int)this.posX + i, (int)this.posY, (int)this.posZ + j, 7); + double dist = this.getDistance((int)this.posX + i, y, (int)this.posZ + j); // Randomised with weighting so that the nearer the block the more likely it is to be snowed. if(y != -1 && rand.nextInt((int)dist*2 + 1) < 1 && dist < 2){ - if(worldObj.getBlockState(pos.down()).getBlock() == Blocks.WATER){ - worldObj.setBlockState(pos.down(), Blocks.ICE.getDefaultState()); + if(worldObj.getBlock((int)this.posX + i, y-1, (int)this.posZ + j) == Blocks.water){ + worldObj.setBlock((int)this.posX + i, y-1, (int)this.posZ + j, Blocks.ice); }else{ - // Don't need to check whether the block at pos can be replaced since getNearestFloorLevelB - // only ever returns floors with air above them. - worldObj.setBlockState(pos, Blocks.SNOW_LAYER.getDefaultState()); + worldObj.setBlock((int)this.posX + i, y, (int)this.posZ + j, Blocks.snow_layer); } } } @@ -132,4 +125,26 @@ public class EntityIceCharge extends EntityBomb { public boolean canRenderOnFire() { return false; } + + @Override + public void writeSpawnData(ByteBuf buffer) { + buffer.writeFloat(blastMultiplier); + } + + @Override + public void readSpawnData(ByteBuf buffer) { + blastMultiplier = buffer.readFloat(); + } + + @Override + public void readEntityFromNBT(NBTTagCompound nbttagcompound){ + super.readEntityFromNBT(nbttagcompound); + blastMultiplier = nbttagcompound.getFloat("blastMultiplier"); + } + + @Override + public void writeEntityToNBT(NBTTagCompound nbttagcompound){ + super.writeEntityToNBT(nbttagcompound); + nbttagcompound.setFloat("blastMultiplier", blastMultiplier); + } } diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityIceLance.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityIceLance.java index ca4dd674..5a61f4de 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityIceLance.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityIceLance.java @@ -1,13 +1,11 @@ package electroblob.wizardry.entity.projectile; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.SoundEvents; import net.minecraft.potion.PotionEffect; import net.minecraft.world.World; @@ -48,9 +46,9 @@ public class EntityIceLance extends EntityMagicArrow { public void onEntityHit(EntityLivingBase entityHit){ // Adds a freeze effect to the target. - if(!MagicDamage.isEntityImmune(DamageType.FROST, entityHit)) entityHit.addPotionEffect(new PotionEffect(WizardryPotions.frost, 300, 0)); + if(!MagicDamage.isEntityImmune(DamageType.FROST, entityHit)) entityHit.addPotionEffect(new PotionEffect(Wizardry.frost.id, 300, 0, true)); - this.playSound(SoundEvents.ENTITY_GENERIC_HURT, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + this.playSound("game.neutral.hurt", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); } @Override @@ -66,11 +64,11 @@ public class EntityIceLance extends EntityMagicArrow { double x = this.posX - 0.25d + (rand.nextDouble()/2); double y = this.posY - 0.25d + (rand.nextDouble()/2); double z = this.posZ - 0.25d + (rand.nextDouble()/2); - Wizardry.proxy.spawnParticle(WizardryParticleType.ICE, worldObj, x, y, z, x - this.posX, y - this.posY, z - this.posZ, 20 + rand.nextInt(10)); + Wizardry.proxy.spawnParticle(EnumParticleType.ICE, worldObj, x, y, z, x - this.posX, y - this.posY, z - this.posZ, 20 + rand.nextInt(10)); } } // Parameters for sound: sound event name, volume, pitch. - this.playSound(SoundEvents.ENTITY_SPLASH_POTION_BREAK, 1.0F, rand.nextFloat() * 0.4F + 1.2F); + this.playSound("game.potion.smash", 1.0F, rand.nextFloat() * 0.4F + 1.2F); } diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityIceShard.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityIceShard.java index 0805c4e0..1d8d9b74 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityIceShard.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityIceShard.java @@ -1,13 +1,11 @@ package electroblob.wizardry.entity.projectile; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.SoundEvents; import net.minecraft.potion.PotionEffect; import net.minecraft.world.World; @@ -44,9 +42,9 @@ public class EntityIceShard extends EntityMagicArrow { public void onEntityHit(EntityLivingBase entityHit){ // Adds a freeze effect to the target. - if(!MagicDamage.isEntityImmune(DamageType.FROST, entityHit)) entityHit.addPotionEffect(new PotionEffect(WizardryPotions.frost, 200, 0)); + if(!MagicDamage.isEntityImmune(DamageType.FROST, entityHit)) entityHit.addPotionEffect(new PotionEffect(Wizardry.frost.id, 200, 0, true)); - this.playSound(SoundEvents.ENTITY_GENERIC_HURT, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + this.playSound("game.neutral.hurt", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); } @Override @@ -62,11 +60,11 @@ public class EntityIceShard extends EntityMagicArrow { double x = this.posX - 0.25d + (rand.nextDouble()/2); double y = this.posY - 0.25d + (rand.nextDouble()/2); double z = this.posZ - 0.25d + (rand.nextDouble()/2); - Wizardry.proxy.spawnParticle(WizardryParticleType.ICE, worldObj, x, y, z, x - this.posX, y - this.posY, z - this.posZ, 20 + rand.nextInt(10)); + Wizardry.proxy.spawnParticle(EnumParticleType.ICE, worldObj, x, y, z, x - this.posX, y - this.posY, z - this.posZ, 20 + rand.nextInt(10)); } } // Parameters for sound: sound event name, volume, pitch. - this.playSound(SoundEvents.ENTITY_SPLASH_POTION_BREAK, 1.0F, rand.nextFloat() * 0.4F + 1.2F); + this.playSound("game.potion.smash", 1.0F, rand.nextFloat() * 0.4F + 1.2F); } diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityLightningArrow.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityLightningArrow.java index e7f250ba..a6dc7fe3 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityLightningArrow.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityLightningArrow.java @@ -1,11 +1,12 @@ package electroblob.wizardry.entity.projectile; +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityCreeper; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.world.World; public class EntityLightningArrow extends EntityMagicArrow { @@ -42,16 +43,16 @@ public class EntityLightningArrow extends EntityMagicArrow { if(worldObj.isRemote){ for(int j=0;j<8;j++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, worldObj, this.posX + rand.nextFloat() - 0.5, this.posY + this.height/2 + rand.nextFloat() - 0.5, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0, 3); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, this.posX + rand.nextFloat() - 0.5, this.posY + this.height/2 + rand.nextFloat() - 0.5, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0, 3); } } - /* Pretty sure this needn't be here, probably missed it when I implemented the damage type system. + if(entityHit instanceof EntityCreeper && !((EntityCreeper)entityHit).getPowered()){ entityHit.getDataWatcher().updateObject(17, Byte.valueOf((byte)1)); - if(this.getShootingEntity() instanceof EntityPlayer) ((EntityPlayer)this.getShootingEntity()).addStat(Wizardry.chargeCreeper); + if(this.getShootingEntity() instanceof EntityPlayer) ((EntityPlayer)this.getShootingEntity()).triggerAchievement(Wizardry.chargeCreeper); } - */ - this.playSound(WizardrySounds.SPELL_SPARK, 1.0F, 1.0F); + + this.playSound("wizardry:arc", 1.0F, 1.0F); } @Override @@ -62,7 +63,7 @@ public class EntityLightningArrow extends EntityMagicArrow { } if(worldObj.isRemote){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, worldObj, this.posX, this.posY, this.posZ, 0, 0, 0, 3); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, this.posX, this.posY, this.posZ, 0, 0, 0, 3); } } diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityLightningDisc.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityLightningDisc.java index e27e34d1..68b65d11 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityLightningDisc.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityLightningDisc.java @@ -2,15 +2,19 @@ package electroblob.wizardry.entity.projectile; import java.util.List; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.monster.EntityCreeper; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class EntityLightningDisc extends EntityMagicProjectile @@ -37,14 +41,16 @@ public class EntityLightningDisc extends EntityMagicProjectile this.height = 0.5f; } - @Override - protected float getSpeed(){ - return 1.2f; + /** This is the speed */ + protected float func_70182_d() + { + return 1.2F; } - - @Override - protected void onImpact(RayTraceResult mop) + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected void onImpact(MovingObjectPosition mop) { Entity entityHit = mop.entityHit; @@ -52,15 +58,14 @@ public class EntityLightningDisc extends EntityMagicProjectile { float damage = 12 * damageMultiplier; - entityHit.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK), damage); + entityHit.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getThrower(), DamageType.SHOCK), damage); } - this.playSound(WizardrySounds.SPELL_SPARK, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + this.playSound("wizardry:arc", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); - if(mop.typeOfHit == RayTraceResult.Type.BLOCK) this.setDead(); + if(mop.typeOfHit == MovingObjectType.BLOCK) this.setDead(); } - - @Override + public void onUpdate(){ super.onUpdate(); @@ -68,8 +73,8 @@ public class EntityLightningDisc extends EntityMagicProjectile // Particle effect if(worldObj.isRemote){ for(int i=0;i<8;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, worldObj, this.posX + rand.nextFloat()*2 - 1, this.posY, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0, 3); - //worldObj.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.posX + rand.nextFloat() - 0.5, this.posY + this.height/2 + rand.nextFloat() - 0.5, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, this.posX + rand.nextFloat()*2 - 1, this.posY, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0, 3); + //worldObj.spawnParticle("largesmoke", this.posX + rand.nextFloat() - 0.5, this.posY + this.height/2 + rand.nextFloat() - 0.5, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0); } } @@ -105,15 +110,17 @@ public class EntityLightningDisc extends EntityMagicProjectile this.motionZ /= 0.99; } - - @Override + /** + * Gets the amount of gravity to apply to the thrown entity with each tick. + */ protected float getGravityVelocity() { return 0.0F; } - - @Override + /** + * Return whether this entity should be rendered as on fire. + */ public boolean canRenderOnFire() { return false; diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicArrow.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicArrow.java index fefa58cd..b2990b9c 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicArrow.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicArrow.java @@ -4,13 +4,17 @@ import java.lang.ref.WeakReference; import java.util.List; import java.util.UUID; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryUtilities; +import org.apache.logging.log4j.core.helpers.UUIDUtil; + +import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.MagicDamage.DamageType; +import electroblob.wizardry.WizardryUtilities; import io.netty.buffer.ByteBuf; import net.minecraft.block.Block; import net.minecraft.block.material.Material; -import net.minecraft.block.state.IBlockState; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -19,38 +23,31 @@ import net.minecraft.entity.monster.EntityEnderman; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.network.play.server.SPacketChangeGameState; +import net.minecraft.network.play.server.S2BPacketChangeGameState; +import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.MathHelper; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.Vec3; import net.minecraft.world.World; -import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; /** This class was copied from EntityArrow in the 1.7.10 update as part of the overhaul and major cleanup * of the code for the projectiles. It provides a unifying superclass for all directed projectiles (i.e. not * spherical stuff like snowballs), namely magic missile, ice shard, force arrow, lightning arrow and dart. - * All spherical projectiles should extend {@link EntityMagicProjectile}. + * All other projectiles should extend {@link EntityMagicProjectile}. *

    * This class handles saving of the damage multiplier and all shared logic. Methods are provided which are * triggered at useful points during the entity update cycle as well as a few getters for various properties. * Override any of these to change the behaviour (no need to call super for any of them). * @since Wizardry 1.0 - * @author Electroblob */ -public abstract class EntityMagicArrow extends Entity implements IProjectile, IEntityAdditionalSpawnData { - +public abstract class EntityMagicArrow extends Entity implements IProjectile, IEntityAdditionalSpawnData +{ private int blockX = -1; private int blockY = -1; private int blockZ = -1; /** The block the arrow is stuck in */ - private IBlockState stuckInBlock; + private Block stuckInBlock; /** The metadata of the block the arrow is stuck in */ private int inData; private boolean inGround; @@ -74,6 +71,7 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE public EntityMagicArrow(World world) { super(world); + this.renderDistanceWeight = 10.0D; this.setSize(0.5F, 0.5F); } @@ -82,9 +80,10 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE public EntityMagicArrow(World world, double x, double y, double z) { super(world); + this.renderDistanceWeight = 10.0D; this.setSize(0.5F, 0.5F); this.setPosition(x, y, z); - // yOffset was set to 0 here, but that has been replaced by getYOffset(), which returns 0 in Entity anyway. + this.yOffset = 0.0F; } /** Creates a projectile at the position of the caster, pointing at the given target. The trajectory seems to be altered @@ -93,13 +92,14 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE public EntityMagicArrow(World world, EntityLivingBase caster, Entity target, float speed, float aimingError, float damageMultiplier) { super(world); - this.shootingEntity = new WeakReference(caster); + this.renderDistanceWeight = 10.0D; + this.shootingEntity = new WeakReference(caster); this.damageMultiplier = damageMultiplier; this.posY = caster.posY + (double)caster.getEyeHeight() - 0.10000000149011612D; double d0 = target.posX - caster.posX; - double d1 = this.doGravity() ? target.getEntityBoundingBox().minY + (double)(target.height / 3.0F) - this.posY - : target.getEntityBoundingBox().minY + (double)(target.height / 2.0F) - this.posY; + double d1 = this.doGravity() ? target.boundingBox.minY + (double)(target.height / 3.0F) - this.posY + : target.boundingBox.minY + (double)(target.height / 2.0F) - this.posY; double d2 = target.posZ - caster.posZ; double d3 = (double)MathHelper.sqrt_double(d0 * d0 + d2 * d2); @@ -110,21 +110,21 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE double d4 = d0 / d3; double d5 = d2 / d3; this.setLocationAndAngles(caster.posX + d4, this.posY, caster.posZ + d5, f2, f3); - // yOffset was set to 0 here, but that has been replaced by getYOffset(), which returns 0 in Entity anyway. - + this.yOffset = 0.0F; // f4 depends on the horizontal distance between the two entities and accounts for bullet drop, // but of course if gravity is ignored this should be 0. - float bulletDropCompensation = this.doGravity() ? (float)d3 * 0.2F : 0; - this.setThrowableHeading(d0, d1 + (double)bulletDropCompensation, d2, speed, aimingError); + float f4 = this.doGravity() ? (float)d3 * 0.2F : 0; + this.setThrowableHeading(d0, d1 + (double)f4, d2, speed, aimingError); } } /** Creates a projectile pointing in the direction the caster is looking, with the given speed. - * Use this constructor for normal, player-cast spells. */ + * USE THIS CONSTRUCTOR FOR NORMAL SPELLS. */ public EntityMagicArrow(World world, EntityLivingBase caster, float speed, float damageMultiplier) { super(world); - this.shootingEntity = new WeakReference(caster); + this.renderDistanceWeight = 10.0D; + this.shootingEntity = new WeakReference(caster); this.damageMultiplier = damageMultiplier; this.setSize(0.5F, 0.5F); @@ -133,7 +133,7 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE this.posY -= 0.10000000149011612D; this.posZ -= (double)(MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * 0.16F); this.setPosition(this.posX, this.posY, this.posZ); - // yOffset was set to 0 here, but that has been replaced by getYOffset(), which returns 0 in Entity anyway. + this.yOffset = 0.0F; this.motionX = (double)(-MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI)); this.motionZ = (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI)); this.motionY = (double)(-MathHelper.sin(this.rotationPitch / 180.0F * (float)Math.PI)); @@ -189,13 +189,21 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE this.ticksInGround = 0; } - // There was an override for setPositionAndRotationDirect here, but it was exactly the same as the superclass - // method (in Entity), so it was removed since it was redundant. + /** + * Sets the position and rotation. Only difference from the other one is no bounding on the rotation. Args: posX, + * posY, posZ, yaw, pitch + * - Allows the arrow to stick in blocks, I think. + */ + @SideOnly(Side.CLIENT) + public void setPositionAndRotation2(double p_70056_1_, double p_70056_3_, double p_70056_5_, float p_70056_7_, float p_70056_8_, int p_70056_9_) + { + this.setPosition(p_70056_1_, p_70056_3_, p_70056_5_); + this.setRotation(p_70056_7_, p_70056_8_); + } /** * Sets the velocity to the args. Args: x, y, z. THIS IS CLIENT SIDE ONLY! DO NOT USE IN COMMON OR SERVER CODE! */ - @Override @SideOnly(Side.CLIENT) public void setVelocity(double p_70016_1_, double p_70016_3_, double p_70016_5_) { @@ -230,7 +238,9 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE /** Called when the projectile hits a block. Override to add sound effects and such like. */ public void onBlockHit(){} - @Override + /** + * Called to update the entity's position/logic. + */ public void onUpdate(){ super.onUpdate(); @@ -249,14 +259,14 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(this.motionY, (double)f) * 180.0D / Math.PI); } - BlockPos blockpos = new BlockPos(this.blockX, this.blockY, this.blockZ); - IBlockState iblockstate = this.worldObj.getBlockState(blockpos); + Block block = this.worldObj.getBlock(this.blockX, this.blockY, this.blockZ); - if (iblockstate.getMaterial() != Material.AIR) + if (block.getMaterial() != Material.air) { - AxisAlignedBB axisalignedbb = iblockstate.getCollisionBoundingBox(this.worldObj, blockpos); + block.setBlockBoundsBasedOnState(this.worldObj, this.blockX, this.blockY, this.blockZ); + AxisAlignedBB axisalignedbb = block.getCollisionBoundingBoxFromPool(this.worldObj, this.blockX, this.blockY, this.blockZ); - if (axisalignedbb != Block.NULL_AABB && axisalignedbb.offset(blockpos).isVecInside(new Vec3d(this.posX, this.posY, this.posZ))) + if (axisalignedbb != null && axisalignedbb.isVecInside(Vec3.createVectorHelper(this.posX, this.posY, this.posZ))) { this.inGround = true; } @@ -274,26 +284,26 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE this.tickInGround(); } // When the arrow is in the air - else{ + else + { + ++this.ticksInAir; this.tickInAir(); - this.ticksInGround = 0; - ++this.ticksInAir; - Vec3d vec3d1 = new Vec3d(this.posX, this.posY, this.posZ); - Vec3d vec3d = new Vec3d(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); - RayTraceResult raytraceresult = this.worldObj.rayTraceBlocks(vec3d1, vec3d, false, true, false); - vec3d1 = new Vec3d(this.posX, this.posY, this.posZ); - vec3d = new Vec3d(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); + Vec3 vec31 = Vec3.createVectorHelper(this.posX, this.posY, this.posZ); + Vec3 vec3 = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); + MovingObjectPosition movingobjectposition = this.worldObj.func_147447_a(vec31, vec3, false, true, false); + vec31 = Vec3.createVectorHelper(this.posX, this.posY, this.posZ); + vec3 = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); - if (raytraceresult != null) + if (movingobjectposition != null) { - vec3d = new Vec3d(raytraceresult.hitVec.xCoord, raytraceresult.hitVec.yCoord, raytraceresult.hitVec.zCoord); + vec3 = Vec3.createVectorHelper(movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord, movingobjectposition.hitVec.zCoord); } Entity entity = null; - List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); + List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); double d0 = 0.0D; int i; float f1; @@ -305,12 +315,12 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE if (entity1.canBeCollidedWith() && (entity1 != this.getShootingEntity() || this.ticksInAir >= 5)) { f1 = 0.3F; - AxisAlignedBB axisalignedbb1 = entity1.getEntityBoundingBox().expand((double)f1, (double)f1, (double)f1); - RayTraceResult RayTraceResult1 = axisalignedbb1.calculateIntercept(vec3d1, vec3d); + AxisAlignedBB axisalignedbb1 = entity1.boundingBox.expand((double)f1, (double)f1, (double)f1); + MovingObjectPosition movingobjectposition1 = axisalignedbb1.calculateIntercept(vec31, vec3); - if (RayTraceResult1 != null) + if (movingobjectposition1 != null) { - double d1 = vec3d1.distanceTo(RayTraceResult1.hitVec); + double d1 = vec31.distanceTo(movingobjectposition1.hitVec); if (d1 < d0 || d0 == 0.0D) { @@ -323,25 +333,25 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE if (entity != null) { - raytraceresult = new RayTraceResult(entity); + movingobjectposition = new MovingObjectPosition(entity); } // Players that are considered invulnerable to the caster allow the projectile to pass straight through them. - if (raytraceresult != null && raytraceresult.entityHit != null && raytraceresult.entityHit instanceof EntityPlayer) + if (movingobjectposition != null && movingobjectposition.entityHit != null && movingobjectposition.entityHit instanceof EntityPlayer) { - EntityPlayer entityplayer = (EntityPlayer)raytraceresult.entityHit; + EntityPlayer entityplayer = (EntityPlayer)movingobjectposition.entityHit; if (entityplayer.capabilities.disableDamage || this.getShootingEntity() instanceof EntityPlayer && !((EntityPlayer)this.getShootingEntity()).canAttackPlayer(entityplayer)) { - raytraceresult = null; + movingobjectposition = null; } } // If the arrow hits something - if (raytraceresult != null) + if (movingobjectposition != null) { // If the arrow hits an entity - if (raytraceresult.entityHit != null) + if (movingobjectposition.entityHit != null) { DamageSource damagesource = null; @@ -351,14 +361,14 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE } else { - damagesource = MagicDamage.causeIndirectMagicDamage(this, (EntityLivingBase)this.getShootingEntity(), this.getDamageType()).setProjectile(); + damagesource = MagicDamage.causeIndirectEntityMagicDamage(this, (EntityLivingBase)this.getShootingEntity(), this.getDamageType()).setProjectile(); } - if (raytraceresult.entityHit.attackEntityFrom(damagesource, (float)(this.getDamage()*this.damageMultiplier))) + if (movingobjectposition.entityHit.attackEntityFrom(damagesource, (float)(this.getDamage()*this.damageMultiplier))) { - if (raytraceresult.entityHit instanceof EntityLivingBase) + if (movingobjectposition.entityHit instanceof EntityLivingBase) { - EntityLivingBase entityHit = (EntityLivingBase)raytraceresult.entityHit; + EntityLivingBase entityHit = (EntityLivingBase)movingobjectposition.entityHit; this.onEntityHit(entityHit); @@ -368,24 +378,24 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE if (f4 > 0.0F) { - raytraceresult.entityHit.addVelocity(this.motionX * (double)this.knockbackStrength * 0.6000000238418579D / (double)f4, 0.1D, this.motionZ * (double)this.knockbackStrength * 0.6000000238418579D / (double)f4); + movingobjectposition.entityHit.addVelocity(this.motionX * (double)this.knockbackStrength * 0.6000000238418579D / (double)f4, 0.1D, this.motionZ * (double)this.knockbackStrength * 0.6000000238418579D / (double)f4); } } // Thorns enchantment if (this.getShootingEntity() != null && this.getShootingEntity() instanceof EntityLivingBase) { - EnchantmentHelper.applyThornEnchantments(entityHit, this.getShootingEntity()); - EnchantmentHelper.applyArthropodEnchantments((EntityLivingBase)this.getShootingEntity(), entityHit); + EnchantmentHelper.func_151384_a(entityHit, this.getShootingEntity()); + EnchantmentHelper.func_151385_b((EntityLivingBase)this.getShootingEntity(), entityHit); } - if (this.getShootingEntity() != null && raytraceresult.entityHit != this.getShootingEntity() && raytraceresult.entityHit instanceof EntityPlayer && this.getShootingEntity() instanceof EntityPlayerMP) + if (this.getShootingEntity() != null && movingobjectposition.entityHit != this.getShootingEntity() && movingobjectposition.entityHit instanceof EntityPlayer && this.getShootingEntity() instanceof EntityPlayerMP) { - ((EntityPlayerMP)this.getShootingEntity()).connection.sendPacket(new SPacketChangeGameState(6, 0.0F)); + ((EntityPlayerMP)this.getShootingEntity()).playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(6, 0.0F)); } } - if (!(raytraceresult.entityHit instanceof EntityEnderman) && !this.doOverpenetration()) + if (!(movingobjectposition.entityHit instanceof EntityEnderman) && !this.doOverpenetration()) { this.setDead(); } @@ -408,13 +418,14 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE // If the arrow hits a block else { - this.blockX = raytraceresult.getBlockPos().getX(); - this.blockY = raytraceresult.getBlockPos().getY(); - this.blockZ = raytraceresult.getBlockPos().getZ(); - this.stuckInBlock = this.worldObj.getBlockState(raytraceresult.getBlockPos()); - this.motionX = (double)((float)(raytraceresult.hitVec.xCoord - this.posX)); - this.motionY = (double)((float)(raytraceresult.hitVec.yCoord - this.posY)); - this.motionZ = (double)((float)(raytraceresult.hitVec.zCoord - this.posZ)); + this.blockX = movingobjectposition.blockX; + this.blockY = movingobjectposition.blockY; + this.blockZ = movingobjectposition.blockZ; + this.stuckInBlock = this.worldObj.getBlock(this.blockX, this.blockY, this.blockZ); + this.inData = this.worldObj.getBlockMetadata(this.blockX, this.blockY, this.blockZ); + this.motionX = (double)((float)(movingobjectposition.hitVec.xCoord - this.posX)); + this.motionY = (double)((float)(movingobjectposition.hitVec.yCoord - this.posY)); + this.motionZ = (double)((float)(movingobjectposition.hitVec.zCoord - this.posZ)); //f2 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); //this.posX -= this.motionX / (double)f2 * 0.05000000074505806D; //this.posY -= this.motionY / (double)f2 * 0.05000000074505806D; @@ -425,9 +436,9 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE this.onBlockHit(); - if (this.stuckInBlock.getMaterial() != Material.AIR) + if (this.stuckInBlock.getMaterial() != Material.air) { - this.stuckInBlock.getBlock().onEntityCollidedWithBlock(this.worldObj, raytraceresult.getBlockPos(), this.stuckInBlock, this); + this.stuckInBlock.onEntityCollidedWithBlock(this.worldObj, this.blockX, this.blockY, this.blockZ, this); } } } @@ -468,7 +479,7 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE for (int l = 0; l < 4; ++l) { float f4 = 0.25F; - this.worldObj.spawnParticle(EnumParticleTypes.WATER_BUBBLE, this.posX - this.motionX * (double)f4, this.posY - this.motionY * (double)f4, this.posZ - this.motionZ * (double)f4, this.motionX, this.motionY, this.motionZ); + this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double)f4, this.posY - this.motionY * (double)f4, this.posZ - this.motionZ * (double)f4, this.motionX, this.motionY, this.motionZ); } f3 = 0.8F; @@ -488,44 +499,49 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE if(this.doGravity()) this.motionY -= 0.05; this.setPosition(this.posX, this.posY, this.posZ); - this.doBlockCollisions(); + this.func_145775_I(); } } - @Override + /** + * (abstract) Protected helper method to write subclass entity data to NBT. + */ public void writeEntityToNBT(NBTTagCompound tag) { tag.setShort("xTile", (short)this.blockX); tag.setShort("yTile", (short)this.blockY); tag.setShort("zTile", (short)this.blockZ); tag.setShort("life", (short)this.ticksInGround); - if(this.stuckInBlock != null){ - ResourceLocation resourcelocation = (ResourceLocation)Block.REGISTRY.getNameForObject(this.stuckInBlock.getBlock()); - tag.setString("inTile", resourcelocation == null ? "" : resourcelocation.toString()); - } + tag.setByte("inTile", (byte)Block.getIdFromBlock(this.stuckInBlock)); tag.setByte("inData", (byte)this.inData); tag.setByte("shake", (byte)this.arrowShake); tag.setByte("inGround", (byte)(this.inGround ? 1 : 0)); tag.setFloat("damageMultiplier", this.damageMultiplier); if(this.getShootingEntity() != null){ - tag.setUniqueId("casterUUID", this.getShootingEntity().getUniqueID()); + tag.setString("casterUUID", this.getShootingEntity().getUniqueID().toString()); } } - @Override + /** + * (abstract) Protected helper method to read subclass entity data from NBT. + */ public void readEntityFromNBT(NBTTagCompound tag) { this.blockX = tag.getShort("xTile"); this.blockY = tag.getShort("yTile"); this.blockZ = tag.getShort("zTile"); this.ticksInGround = tag.getShort("life"); - // Commented out for now because there's some funny stuff going on with blockstates and metadata. - //this.stuckInBlock = Block.getBlockById(tag.getByte("inTile") & 255); + this.stuckInBlock = Block.getBlockById(tag.getByte("inTile") & 255); this.inData = tag.getByte("inData") & 255; this.arrowShake = tag.getByte("shake") & 255; this.inGround = tag.getByte("inGround") == 1; this.damageMultiplier = tag.getFloat("damageMultiplier"); - casterUUID = tag.getUniqueId("casterUUID"); + String string = tag.getString("casterUUID"); + // Fixed issue #3: + // Uses regex to verify that the string is a valid UUID (I can't see why it wouldn't be, but it was reported + // on the issue tracker so I've fixed it). + if(WizardryUtilities.verifyUUIDString(string)) + casterUUID = UUID.fromString(string); } /** @@ -564,7 +580,7 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE } public void readSpawnData(ByteBuf buffer){ - if(buffer.isReadable()) this.shootingEntity = new WeakReference((EntityLivingBase)this.worldObj.getEntityByID(buffer.readInt())); + if(buffer.isReadable()) this.shootingEntity = new WeakReference((EntityLivingBase)this.worldObj.getEntityByID(buffer.readInt())); } /** @@ -577,6 +593,6 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE } public void setShootingEntity(EntityLivingBase entity) { - shootingEntity = new WeakReference(entity); + shootingEntity = new WeakReference(entity); } } \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicMissile.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicMissile.java index 67c079d9..9b1ad13a 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicMissile.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicMissile.java @@ -1,10 +1,9 @@ package electroblob.wizardry.entity.projectile; +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.util.WizardryParticleType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.SoundEvents; import net.minecraft.world.World; public class EntityMagicMissile extends EntityMagicArrow { @@ -38,7 +37,7 @@ public class EntityMagicMissile extends EntityMagicArrow { @Override public void onEntityHit(EntityLivingBase entityHit){ - this.playSound(SoundEvents.ENTITY_GENERIC_HURT, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + this.playSound("game.neutral.hurt", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); } @Override @@ -51,10 +50,10 @@ public class EntityMagicMissile extends EntityMagicArrow { if(this.worldObj.isRemote){ if(this.ticksExisted % 2 == 1){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, this.posX, this.posY, this.posZ, 0, 0, 0, 20 + rand.nextInt(10), 0.5f + (rand.nextFloat()/2), 0.5f + (rand.nextFloat()/2), 0.5f + (rand.nextFloat()/2)); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX, this.posY, this.posZ, 0, 0, 0, 20 + rand.nextInt(10), 0.5f + (rand.nextFloat()/2), 0.5f + (rand.nextFloat()/2), 0.5f + (rand.nextFloat()/2)); } else{ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, this.posX, this.posY, this.posZ, 0, 0, 0, 20 + rand.nextInt(10), 0.5f + (rand.nextFloat()/2), 0.5f + (rand.nextFloat()/2), 0.5f + (rand.nextFloat()/2)); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX, this.posY, this.posZ, 0, 0, 0, 20 + rand.nextInt(10), 0.5f + (rand.nextFloat()/2), 0.5f + (rand.nextFloat()/2), 0.5f + (rand.nextFloat()/2)); } } } diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicProjectile.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicProjectile.java index e37c45fa..1c499771 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicProjectile.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityMagicProjectile.java @@ -5,7 +5,6 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.projectile.EntityThrowable; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; -import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; /** This class is a generic superclass for all non-directed projectiles, namely: darkness orb, firebolt, firebomb, * force orb, ice charge, lightning disc, poison bomb, spark, spark bomb and thunderbolt. Directed (arrow-like) projectiles @@ -15,30 +14,26 @@ import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; * as it is. Range is done via the velocity when the constructor is called. Caster is already handled by EntityThrowable.getThrower(). * * Note that this class does not implement {@link IEntityAdditionalSpawnData}; subclasses that need to transfer extra data - * to the client should implement that interface themselves. See {@link EntityBomb} for an example. + * to the client should implement that interface themselves. See {@link EntitySparkBomb} for an example. * @since Wizardry 1.0 - * @author Electroblob - * @see EntityBomb */ -public abstract class EntityMagicProjectile extends EntityThrowable { - +public abstract class EntityMagicProjectile extends EntityThrowable +{ public float damageMultiplier = 1.0f; - public EntityMagicProjectile(World world) + public EntityMagicProjectile(World par1World) { - super(world); + super(par1World); } - public EntityMagicProjectile(World world, EntityLivingBase thrower) + public EntityMagicProjectile(World par1World, EntityLivingBase par2EntityLivingBase) { - super(world, thrower); + super(par1World, par2EntityLivingBase); } - public EntityMagicProjectile(World world, EntityLivingBase thrower, float damageMultiplier) + public EntityMagicProjectile(World par1World, EntityLivingBase par2EntityLivingBase, float damageMultiplier) { - super(world, thrower); - // This is the standard set of parameters for this method, used by snowballs and ender pearls amongst others. - this.setHeadingFromThrower(thrower, thrower.rotationPitch, thrower.rotationYaw, 0.0f, this.getSpeed(), 1.0f); + super(par1World, par2EntityLivingBase); this.damageMultiplier = damageMultiplier; } @@ -47,16 +42,11 @@ public abstract class EntityMagicProjectile extends EntityThrowable { super(par1World, par2, par4, par6); } - /** This got removed at some point since 1.7.10, but I liked it so I thought I'd add it back in again. */ - protected float getSpeed(){ - return 1.5f; - } - /** Sets this projectile's velocity as a normalised vector towards the target. */ public void directTowards(Entity target, float velocity){ double dx = target.posX - this.posX; - double dy = target.getEntityBoundingBox().minY + (double)(target.height / 2.0F) - (this.posY + (double)(this.height / 2.0F)); + double dy = target.boundingBox.minY + (double)(target.height / 2.0F) - (this.posY + (double)(this.height / 2.0F)); double dz = target.posZ - this.posZ; this.motionX = dx/this.getDistanceToEntity(target) * velocity; diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityPoisonBomb.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityPoisonBomb.java index 717aa618..ec3fefd4 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityPoisonBomb.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityPoisonBomb.java @@ -2,21 +2,26 @@ package electroblob.wizardry.entity.projectile; import java.util.List; +import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import io.netty.buffer.ByteBuf; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.MobEffects; -import net.minecraft.init.SoundEvents; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; -public class EntityPoisonBomb extends EntityBomb { +public class EntityPoisonBomb extends EntityMagicProjectile implements IEntityAdditionalSpawnData +{ + /** The entity blast multiplier. Only some projectiles cause a blast, which is why this isn't in EntityMagicProjectile. */ + public float blastMultiplier = 1.0f; public EntityPoisonBomb(World par1World) { @@ -30,7 +35,8 @@ public class EntityPoisonBomb extends EntityBomb { public EntityPoisonBomb(World par1World, EntityLivingBase par2EntityLivingBase, float damageMultiplier, float blastMultiplier) { - super(par1World, par2EntityLivingBase, damageMultiplier, blastMultiplier); + super(par1World, par2EntityLivingBase, damageMultiplier); + this.blastMultiplier = blastMultiplier; } public EntityPoisonBomb(World par1World, double par2, double par4, double par6) @@ -38,35 +44,36 @@ public class EntityPoisonBomb extends EntityBomb { super(par1World, par2, par4, par6); } - @Override - protected void onImpact(RayTraceResult par1RayTraceResult) + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - Entity entityHit = par1RayTraceResult.entityHit; + Entity entityHit = par1MovingObjectPosition.entityHit; if (entityHit != null) { // This is if the poison bomb gets a direct hit float damage = 5 * damageMultiplier; - entityHit.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.POISON).setProjectile(), damage); + entityHit.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getThrower(), DamageType.POISON).setProjectile(), damage); - if(entityHit instanceof EntityLivingBase && !MagicDamage.isEntityImmune(DamageType.POISON, entityHit)) ((EntityLivingBase)entityHit).addPotionEffect(new PotionEffect(MobEffects.POISON, 120, 1)); + if(entityHit instanceof EntityLivingBase && !MagicDamage.isEntityImmune(DamageType.POISON, entityHit)) ((EntityLivingBase)entityHit).addPotionEffect(new PotionEffect(Potion.poison.id, 120, 1)); } // Particle effect if(worldObj.isRemote){ + this.worldObj.spawnParticle("largeexplode", this.posX, this.posY, this.posZ, 0, 0, 0); for(int i=0;i<60*blastMultiplier;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, worldObj, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0.0d, 0.0d, 0.0d, 35, 0.2f + rand.nextFloat()*0.3f, 0.6f, 0.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, worldObj, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0.0d, 0.0d, 0.0d, 0, 0.2f + rand.nextFloat()*0.2f, 0.8f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, worldObj, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0.0d, 0.0d, 0.0d, 35, 0.2f + rand.nextFloat()*0.3f, 0.6f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, worldObj, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0.0d, 0.0d, 0.0d, 0, 0.2f + rand.nextFloat()*0.2f, 0.8f, 0.0f); } - // Spawning this after the other particles fixes the rendering colour bug. It's a bit of a cheat, but it works pretty well. - this.worldObj.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0); } if(!this.worldObj.isRemote){ - this.playSound(SoundEvents.ENTITY_SPLASH_POTION_BREAK, 1.5F, rand.nextFloat() * 0.4F + 0.6F); - this.playSound(SoundEvents.BLOCK_FIRE_EXTINGUISH, 1.2F, 1.0f); + this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "game.potion.smash", 1.5F, rand.nextFloat() * 0.4F + 0.6F); + this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "random.fizz", 1.2F, 1.0f); double range = 3.0d*blastMultiplier; @@ -74,12 +81,34 @@ public class EntityPoisonBomb extends EntityBomb { for(EntityLivingBase target : targets){ if(target != entityHit && target != this.getThrower() && !MagicDamage.isEntityImmune(DamageType.POISON, target)){ - target.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.POISON), 4.0f * damageMultiplier); - target.addPotionEffect(new PotionEffect(MobEffects.POISON, 100, 1)); + target.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getThrower(), DamageType.POISON), 4.0f * damageMultiplier); + target.addPotionEffect(new PotionEffect(19, 100, 1)); } } this.setDead(); } } + + @Override + public void writeSpawnData(ByteBuf buffer) { + buffer.writeFloat(blastMultiplier); + } + + @Override + public void readSpawnData(ByteBuf buffer) { + blastMultiplier = buffer.readFloat(); + } + + @Override + public void readEntityFromNBT(NBTTagCompound nbttagcompound){ + super.readEntityFromNBT(nbttagcompound); + blastMultiplier = nbttagcompound.getFloat("blastMultiplier"); + } + + @Override + public void writeEntityToNBT(NBTTagCompound nbttagcompound){ + super.writeEntityToNBT(nbttagcompound); + nbttagcompound.setFloat("blastMultiplier", blastMultiplier); + } } diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntitySmokeBomb.java b/src/main/java/electroblob/wizardry/entity/projectile/EntitySmokeBomb.java index 1ed5dea0..b10d0509 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntitySmokeBomb.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntitySmokeBomb.java @@ -2,21 +2,25 @@ package electroblob.wizardry.entity.projectile; import java.util.List; +import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; +import electroblob.wizardry.EnumParticleType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; -import net.minecraft.init.SoundEvents; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; -public class EntitySmokeBomb extends EntityBomb { +public class EntitySmokeBomb extends EntityMagicProjectile implements IEntityAdditionalSpawnData +{ + /** The entity blast multiplier. Only some projectiles cause a blast, which is why this isn't in EntityMagicProjectile. */ + public float blastMultiplier = 1.0f; public EntitySmokeBomb(World par1World) { @@ -30,7 +34,8 @@ public class EntitySmokeBomb extends EntityBomb { public EntitySmokeBomb(World par1World, EntityLivingBase par2EntityLivingBase, float damageMultiplier, float blastMultiplier) { - super(par1World, par2EntityLivingBase, damageMultiplier, blastMultiplier); + super(par1World, par2EntityLivingBase, damageMultiplier); + this.blastMultiplier = blastMultiplier; } public EntitySmokeBomb(World par1World, double par2, double par4, double par6) @@ -38,23 +43,39 @@ public class EntitySmokeBomb extends EntityBomb { super(par1World, par2, par4, par6); } - @Override - protected void onImpact(RayTraceResult par1RayTraceResult){ + /** + * Called when this EntityThrowable hits a block or entity. + */ + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) + { + /* + Entity entityHit = par1MovingObjectPosition.entityHit; + + if (entityHit != null) + { + // This is if the smoke bomb gets a direct hit + float damage = 2.0f * damageMultiplier; + + entityHit.attackEntityFrom(WizardryUtilities.causeIndirectEntityMagicDamage(this, this.getThrower()), damage); + + if(entityHit instanceof EntityLivingBase) ((EntityLivingBase)entityHit).addPotionEffect(new PotionEffect(Potion.blindness.id, 120, 0)); + } + */ // Particle effect if(worldObj.isRemote){ - this.worldObj.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0); + this.worldObj.spawnParticle("largeexplode", this.posX, this.posY, this.posZ, 0, 0, 0); for(int i=0;i<60*blastMultiplier;i++){ - this.worldObj.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0, 0, 0); + this.worldObj.spawnParticle("largesmoke", this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0, 0, 0); float brightness = rand.nextFloat() * 0.3f; - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, worldObj, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0.0d, 0.0d, 0.0d, 0, brightness, brightness, brightness); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, worldObj, this.posX + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posY + (this.rand.nextDouble()*4 - 2)*blastMultiplier, this.posZ + (this.rand.nextDouble()*4 - 2)*blastMultiplier, 0.0d, 0.0d, 0.0d, 0, brightness, brightness, brightness); } } if(!this.worldObj.isRemote){ - this.playSound(SoundEvents.ENTITY_SPLASH_POTION_BREAK, 1.5F, rand.nextFloat() * 0.4F + 0.6F); - this.playSound(SoundEvents.BLOCK_FIRE_EXTINGUISH, 1.2F, 1.0f); + this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "game.potion.smash", 1.5F, rand.nextFloat() * 0.4F + 0.6F); + this.worldObj.playSoundEffect(this.posX, this.posY, this.posZ, "random.fizz", 1.2F, 1.0f); double range = 3.0d * blastMultiplier; @@ -65,12 +86,14 @@ public class EntitySmokeBomb extends EntityBomb { // Gives the target blindness if it is a player, mind trick otherwise (since this has the desired // effect of preventing targeting) if(target instanceof EntityPlayer){ - target.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, 120, 0)); + target.addPotionEffect(new PotionEffect(Potion.blindness.id, 120, 0)); }else if(target instanceof EntityLiving){ // New AI ((EntityLiving)target).setAttackTarget(null); + // Old AI + if(target instanceof EntityCreature) ((EntityCreature)target).setTarget(null); - target.addPotionEffect(new PotionEffect(WizardryPotions.mind_trick, 120, 0)); + target.addPotionEffect(new PotionEffect(Wizardry.mindTrick.id, 120, 0)); } } } @@ -78,4 +101,26 @@ public class EntitySmokeBomb extends EntityBomb { this.setDead(); } } + + @Override + public void writeSpawnData(ByteBuf buffer) { + buffer.writeFloat(blastMultiplier); + } + + @Override + public void readSpawnData(ByteBuf buffer) { + blastMultiplier = buffer.readFloat(); + } + + @Override + public void readEntityFromNBT(NBTTagCompound nbttagcompound){ + super.readEntityFromNBT(nbttagcompound); + blastMultiplier = nbttagcompound.getFloat("blastMultiplier"); + } + + @Override + public void writeEntityToNBT(NBTTagCompound nbttagcompound){ + super.writeEntityToNBT(nbttagcompound); + nbttagcompound.setFloat("blastMultiplier", blastMultiplier); + } } diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntitySpark.java b/src/main/java/electroblob/wizardry/entity/projectile/EntitySpark.java index 4061b954..f7ab6078 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntitySpark.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntitySpark.java @@ -2,19 +2,21 @@ package electroblob.wizardry.entity.projectile; import java.util.List; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.entity.monster.EntityCreeper; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; -public class EntitySpark extends EntityMagicProjectile { - +public class EntitySpark extends EntityMagicProjectile +{ public EntitySpark(World par1World) { super(par1World); @@ -36,7 +38,7 @@ public class EntitySpark extends EntityMagicProjectile { } /** This is the speed */ - protected float getSpeed() + protected float func_70182_d() { return 0.5F; } @@ -44,23 +46,23 @@ public class EntitySpark extends EntityMagicProjectile { /** * Called when this EntityThrowable hits a block or entity. */ - protected void onImpact(RayTraceResult par1RayTraceResult) + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - Entity entityHit = par1RayTraceResult.entityHit; + Entity entityHit = par1MovingObjectPosition.entityHit; if (entityHit != null){ float damage = 6 * damageMultiplier; - entityHit.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK), damage); + entityHit.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getThrower(), DamageType.SHOCK), damage); } - this.playSound(WizardrySounds.SPELL_SPARK, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + this.playSound("wizardry:arc", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); // Particle effect if(worldObj.isRemote){ for(int i=0;i<8;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, worldObj, this.posX + rand.nextFloat() - 0.5, this.posY + this.height/2 + rand.nextFloat() - 0.5, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0, 3); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, this.posX + rand.nextFloat() - 0.5, this.posY + this.height/2 + rand.nextFloat() - 0.5, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0, 3); } } diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntitySparkBomb.java b/src/main/java/electroblob/wizardry/entity/projectile/EntitySparkBomb.java index 9ffedcdf..f852d748 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntitySparkBomb.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntitySparkBomb.java @@ -1,28 +1,35 @@ package electroblob.wizardry.entity.projectile; import java.util.List; +import java.util.UUID; +import cpw.mods.fml.common.network.ByteBufUtils; +import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.entity.EntityArc; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; import io.netty.buffer.ByteBuf; +import net.minecraft.enchantment.Enchantment; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityCreeper; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; -public class EntitySparkBomb extends EntityBomb { - +public class EntitySparkBomb extends EntityMagicProjectile implements IEntityAdditionalSpawnData +{ /** For client use, because thrower field is not visible. */ private int casterID; + /** The entity blast multiplier. Only some projectiles cause a blast, which is why this isn't in EntityMagicProjectile. */ + public float blastMultiplier; + public EntitySparkBomb(World par1World) { super(par1World); @@ -35,7 +42,8 @@ public class EntitySparkBomb extends EntityBomb { public EntitySparkBomb(World par1World, EntityLivingBase par2EntityLivingBase, float damageMultiplier, float blastMultiplier) { - super(par1World, par2EntityLivingBase, damageMultiplier, blastMultiplier); + super(par1World, par2EntityLivingBase, damageMultiplier); + this.blastMultiplier = blastMultiplier; } public EntitySparkBomb(World par1World, double par2, double par4, double par6) @@ -46,28 +54,28 @@ public class EntitySparkBomb extends EntityBomb { /** * Called when this EntityThrowable hits a block or entity. */ - protected void onImpact(RayTraceResult par1RayTraceResult) + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - this.playSound(SoundEvents.ENTITY_FIREWORK_BLAST_FAR, 0.5f, 0.5f); + this.playSound("fireworks.blast_far", 0.5f, 0.5f); - Entity entityHit = par1RayTraceResult.entityHit; + Entity entityHit = par1MovingObjectPosition.entityHit; if (entityHit != null) { // This is if the spark bomb gets a direct hit float damage = 6 * damageMultiplier; - this.playSound(SoundEvents.ENTITY_GENERIC_HURT, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + this.playSound("game.neutral.hurt", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); - entityHit.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK).setProjectile(), damage); + entityHit.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getThrower(), DamageType.SHOCK).setProjectile(), damage); } // Particle effect if(worldObj.isRemote){ for(int i=0;i<8;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, worldObj, this.posX + rand.nextFloat() - 0.5, this.posY + this.height/2 + rand.nextFloat() - 0.5, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0, 3); - worldObj.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.posX + rand.nextFloat() - 0.5, this.posY + this.height/2 + rand.nextFloat() - 0.5, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, this.posX + rand.nextFloat() - 0.5, this.posY + this.height/2 + rand.nextFloat() - 0.5, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0, 3); + worldObj.spawnParticle("largesmoke", this.posX + rand.nextFloat() - 0.5, this.posY + this.height/2 + rand.nextFloat() - 0.5, this.posZ + rand.nextFloat() - 0.5, 0, 0, 0); } } @@ -93,15 +101,15 @@ public class EntitySparkBomb extends EntityBomb { target.posX, target.posY + target.height/2, target.posZ); this.worldObj.spawnEntityInWorld(arc); - target.playSound(WizardrySounds.SPELL_SPARK, 1.0F, rand.nextFloat() * 0.4F + 1.5F); + worldObj.playSoundAtEntity(target, "wizardry:arc", 1.0F, rand.nextFloat() * 0.4F + 1.5F); - target.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK), 5.0f * damageMultiplier); + target.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getThrower(), DamageType.SHOCK), 5.0f * damageMultiplier); }else{ // Particle effect for(int j=0;j<8;j++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, worldObj, target.posX + rand.nextFloat() - 0.5, target.getEntityBoundingBox().minY + target.height*rand.nextFloat(), target.posZ + rand.nextFloat() - 0.5, 0, 0, 0, 3); - worldObj.spawnParticle(EnumParticleTypes.SMOKE_LARGE, target.posX + rand.nextFloat() - 0.5, target.getEntityBoundingBox().minY + target.height*rand.nextFloat(), target.posZ + rand.nextFloat() - 0.5, 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, target.posX + rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(target) + target.height*rand.nextFloat(), target.posZ + rand.nextFloat() - 0.5, 0, 0, 0, 3); + worldObj.spawnParticle("largesmoke", target.posX + rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(target) + target.height*rand.nextFloat(), target.posZ + rand.nextFloat() - 0.5, 0, 0, 0); } } } @@ -111,14 +119,26 @@ public class EntitySparkBomb extends EntityBomb { } @Override - public void writeSpawnData(ByteBuf data){ - super.writeSpawnData(data); + public void writeSpawnData(ByteBuf data) { data.writeInt(this.getThrower().getEntityId()); + data.writeFloat(blastMultiplier); } @Override - public void readSpawnData(ByteBuf data){ - super.readSpawnData(data); + public void readSpawnData(ByteBuf data) { this.casterID = data.readInt(); + this.blastMultiplier = data.readFloat(); + } + + @Override + public void readEntityFromNBT(NBTTagCompound nbttagcompound){ + super.readEntityFromNBT(nbttagcompound); + blastMultiplier = nbttagcompound.getFloat("blastMultiplier"); + } + + @Override + public void writeEntityToNBT(NBTTagCompound nbttagcompound){ + super.writeEntityToNBT(nbttagcompound); + nbttagcompound.setFloat("blastMultiplier", blastMultiplier); } } diff --git a/src/main/java/electroblob/wizardry/entity/projectile/EntityThunderbolt.java b/src/main/java/electroblob/wizardry/entity/projectile/EntityThunderbolt.java index 249dcae2..f211fa0d 100644 --- a/src/main/java/electroblob/wizardry/entity/projectile/EntityThunderbolt.java +++ b/src/main/java/electroblob/wizardry/entity/projectile/EntityThunderbolt.java @@ -1,18 +1,16 @@ package electroblob.wizardry.entity.projectile; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.WizardryParticleType; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.init.SoundEvents; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; -public class EntityThunderbolt extends EntityMagicProjectile { - +public class EntityThunderbolt extends EntityMagicProjectile +{ public EntityThunderbolt(World par1World) { super(par1World); @@ -34,7 +32,7 @@ public class EntityThunderbolt extends EntityMagicProjectile { } /** This is the speed */ - protected float getSpeed() + protected float func_70182_d() { return 2.5F; } @@ -42,25 +40,25 @@ public class EntityThunderbolt extends EntityMagicProjectile { /** * Called when this EntityThrowable hits a block or entity. */ - protected void onImpact(RayTraceResult par1RayTraceResult) + protected void onImpact(MovingObjectPosition par1MovingObjectPosition) { - Entity entityHit = par1RayTraceResult.entityHit; + Entity entityHit = par1MovingObjectPosition.entityHit; if(entityHit != null){ float damage = 3 * damageMultiplier; - entityHit.attackEntityFrom(MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK).setProjectile(), damage); + entityHit.attackEntityFrom(MagicDamage.causeIndirectEntityMagicDamage(this, this.getThrower(), DamageType.SHOCK).setProjectile(), damage); // Knockback entityHit.addVelocity(this.motionX*0.2, this.motionY*0.2, this.motionZ*0.2); } - this.playSound(SoundEvents.ENTITY_FIREWORK_LARGE_BLAST, 1.4F, 0.5f + this.rand.nextFloat() * 0.1F); + this.playSound("fireworks.largeBlast", 1.4F, 0.5f + this.rand.nextFloat() * 0.1F); // Particle effect if(worldObj.isRemote){ - worldObj.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0); + worldObj.spawnParticle("largeexplode", this.posX, this.posY, this.posZ, 0, 0, 0); } this.setDead(); @@ -71,9 +69,9 @@ public class EntityThunderbolt extends EntityMagicProjectile { super.onUpdate(); if(worldObj.isRemote){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, worldObj, this.posX + rand.nextFloat()*0.2 - 0.1, this.posY + this.height/2 + rand.nextFloat()*0.2 - 0.1, this.posZ + rand.nextFloat()*0.2 - 0.1, 0, 0, 0, 3); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, worldObj, this.posX + rand.nextFloat()*0.2 - 0.1, this.posY + this.height/2 + rand.nextFloat()*0.2 - 0.1, this.posZ + rand.nextFloat()*0.2 - 0.1, 0, 0, 0, 3); for(int i=0; i<4; i++){ - worldObj.spawnParticle(EnumParticleTypes.SMOKE_NORMAL, this.posX + rand.nextFloat()*0.2 - 0.1, this.posY + this.height/2 + rand.nextFloat()*0.2 - 0.1, this.posZ + rand.nextFloat()*0.2 - 0.1, 0, 0, 0); + worldObj.spawnParticle("smoke", this.posX + rand.nextFloat()*0.2 - 0.1, this.posY + this.height/2 + rand.nextFloat()*0.2 - 0.1, this.posZ + rand.nextFloat()*0.2 - 0.1, 0, 0, 0); } } diff --git a/src/main/java/electroblob/wizardry/event/DiscoverSpellEvent.java b/src/main/java/electroblob/wizardry/event/DiscoverSpellEvent.java deleted file mode 100644 index 066ae73d..00000000 --- a/src/main/java/electroblob/wizardry/event/DiscoverSpellEvent.java +++ /dev/null @@ -1,49 +0,0 @@ -package electroblob.wizardry.event; - -import electroblob.wizardry.spell.Spell; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.fml.common.eventhandler.Cancelable; - -/** - * DiscoverSpellEvent is fired when a player discovers a spell by any method.
    - *
    - * This event is {@link Cancelable}. If this event is canceled, the spell is not discovered.
    - *
    - * This event does not have a result. {@link HasResult}
    - *
    - * This event is fired on the {@link MinecraftForge#EVENT_BUS}. - * - * @author Electroblob - * @since Wizardry 2.1 - */ -public class DiscoverSpellEvent extends PlayerEvent { - - private final Spell spell; - private final Source source; - - public DiscoverSpellEvent(EntityPlayer player, Spell spell, Source source) { - super(player); - this.spell = spell; - this.source = source; - } - - /** Returns the spell that is being discovered. */ - public Spell getSpell(){ - return spell; - } - - /** Returns the method used to discover the spell. */ - public Source getSource(){ - return source; - } - - public enum Source { - /** Signifies that the spell was discovered by trying to cast it. */ CASTING, - /** Signifies that the spell was discovered using a scroll of identification. */ IDENTIFICATION_SCROLL, - /** Signifies that the spell was discovered using commands. */ COMMAND, - /** Signifies that the spell was discovered by some other means. */ OTHER - } - -} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/event/SpellBindEvent.java b/src/main/java/electroblob/wizardry/event/SpellBindEvent.java deleted file mode 100644 index dd6cf322..00000000 --- a/src/main/java/electroblob/wizardry/event/SpellBindEvent.java +++ /dev/null @@ -1,31 +0,0 @@ -package electroblob.wizardry.event; - -import electroblob.wizardry.tileentity.ContainerArcaneWorkbench; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.player.PlayerContainerEvent; -import net.minecraftforge.fml.common.eventhandler.Cancelable; -import net.minecraftforge.fml.common.eventhandler.Event.HasResult; - -/** - * SpellBindEvent is fired when a player presses the apply button in the arcane workbench. Note that this - * event is only fired on the server side.
    - *
    - * This event is {@link Cancelable}. If this event is canceled, no further processing takes place: spells are not bound, - * upgrades are not applied and crystals are not consumed.
    - *
    - * This event does not have a result. {@link HasResult}
    - *
    - * This event is fired on the {@link MinecraftForge#EVENT_BUS}. - * - * @author Electroblob - * @since Wizardry 2.1 - */ -@Cancelable -public class SpellBindEvent extends PlayerContainerEvent { - - public SpellBindEvent(EntityPlayer player, ContainerArcaneWorkbench container) { - super(player, container); - } - -} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/event/SpellCastEvent.java b/src/main/java/electroblob/wizardry/event/SpellCastEvent.java deleted file mode 100644 index c1072eda..00000000 --- a/src/main/java/electroblob/wizardry/event/SpellCastEvent.java +++ /dev/null @@ -1,139 +0,0 @@ -package electroblob.wizardry.event; - -import electroblob.wizardry.entity.living.ISpellCaster; -import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.SpellModifiers; -import net.minecraft.entity.EntityLivingBase; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.living.LivingEvent; -import net.minecraftforge.fml.common.eventhandler.Cancelable; - -/** - * SpellCastEvent is the parent event class for all spell casting events. Methods which subscribe to this event - * will receive all three child events (it is recommended that you use {@link SpellCastEvent.Pre}, - * {@link SpellCastEvent.Post} or {@link SpellCastEvent.Tick}, depending on the application).
    - *
    - * This event is fired on the {@link MinecraftForge#EVENT_BUS}. - * - * @author Electroblob - * @since Wizardry 2.1 - */ -public abstract class SpellCastEvent extends LivingEvent { - - private final Spell spell; - private final SpellModifiers modifiers; - private final Source source; - - public SpellCastEvent(EntityLivingBase caster, Spell spell, SpellModifiers modifiers, Source source) { - super(caster); - this.spell = spell; - this.modifiers = modifiers; - this.source = source; - } - - /** Returns the spell being cast. */ - public Spell getSpell(){ - return spell; - } - - /** Returns the modifiers for the spell being cast. */ - public SpellModifiers getModifiers(){ - return modifiers; - } - - /** Returns the source of the spell being cast. */ - public Source getSource(){ - return source; - } - - public enum Source { - /** Signifies that the spell was cast using a wand. */ WAND, - /** Signifies that the spell was cast using a scroll. */ SCROLL, - /** Signifies that the spell was cast using commands. */ COMMAND, - /** Signifies that the spell was cast by an {@link ISpellCaster}. */ NPC, - /** Signifies that the spell was cast by some other means. */ OTHER - } - - /** - * SpellCastEvent.Pre is fired just before a spell is cast. Use this event to change the spell modifiers and - * generally alter the behaviour of the spell, or stop it from being cast entirely. For example, wizardry uses this - * event to cancel spells cast by entities that have the arcane jammer effect. Note that for wands, this is called - * before mana, tier and cooldowns are checked. Also note that this event is only fired once for continuous - * spells, when they start casting.
    - *
    - * This event is {@link Cancelable}. If this event is canceled, the spell is not cast, mana is not consumed, and the - * right-click action that caused it (if any) returns a result of FAIL, meaning that the right-click is passed to - * the block/entity in front of the player, if any.
    - *
    - * This event does not have a result. {@link HasResult}
    - *
    - * This event is fired on the {@link MinecraftForge#EVENT_BUS}. - * - * @author Electroblob - * @since Wizardry 2.1 - */ - @Cancelable - public static class Pre extends SpellCastEvent { - - public Pre(EntityLivingBase caster, Spell spell, SpellModifiers modifiers, Source source) { - super(caster, spell, modifiers, source); - } - - } - - /** - * SpellCastEvent.Post is fired just after a spell is cast. Use this event for any processing which depends - * on whether the spell succeeds, and does not affect the spell itself. For example, wizardry uses this event - * to keep track of spellcasting stats. Note that although this event is fired from both sides, it is not fired from - * common code; rather, both sides fire it separately, so timing is not guaranteed. Also note that this event is - * only fired once for continuous spells, after the first casting tick.
    - *
    - * This event is not {@link Cancelable}.
    - *
    - * This event does not have a result. {@link HasResult}
    - *
    - * This event is fired on the {@link MinecraftForge#EVENT_BUS}. - * - * @author Electroblob - * @since Wizardry 2.1 - */ - public static class Post extends SpellCastEvent { - - public Post(EntityLivingBase caster, Spell spell, SpellModifiers modifiers, Source source) { - super(caster, spell, modifiers, source); - } - - } - - /** - * SpellCastEvent.Tick is fired each tick while a continuous spell is being cast.
    - *
    - * This event is {@link Cancelable}. If this event is canceled, the spell is not cast, mana is not consumed, and the - * spell casting is interrupted. Cancelling this event on the client side will stop particles being spawned, but - * will not interrupt spell casting.
    - *
    - * This event does not have a result. {@link HasResult}
    - *
    - * This event is fired on the {@link MinecraftForge#EVENT_BUS}. - * - * @author Electroblob - * @since Wizardry 2.1 - */ - @Cancelable - public static class Tick extends SpellCastEvent { - - private final int count; - - public Tick(EntityLivingBase caster, Spell spell, SpellModifiers modifiers, Source source, int count) { - super(caster, spell, modifiers, source); - this.count = count; - } - - /** Returns the number of ticks this (continuous) spell has already been cast for. */ - public int getCount(){ - return count; - } - - } - -} diff --git a/src/main/java/electroblob/wizardry/item/IConjuredItem.java b/src/main/java/electroblob/wizardry/item/IConjuredItem.java deleted file mode 100644 index ee8a0845..00000000 --- a/src/main/java/electroblob/wizardry/item/IConjuredItem.java +++ /dev/null @@ -1,57 +0,0 @@ -package electroblob.wizardry.item; - -import net.minecraft.entity.item.EntityItem; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraftforge.event.entity.item.ItemTossEvent; -import net.minecraftforge.event.entity.living.LivingDropsEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; - -/** Allows wizardry to identify items that are conjured (and therefore need destroying if they leave the inventory) - * without explicitly referencing each, thereby allowing for better expandibility. */ -@Mod.EventBusSubscriber -public interface IConjuredItem { - - /** The NBT tag key used to store the duration multiplier for conjured items. */ - public static final String DURATION_MULTIPLIER_KEY = "durationMultiplier"; - - /** Helper method for setting the duration multiplier (via NBT) for conjured items. */ - public static void setDurationMultiplier(ItemStack stack, float multiplier){ - if(!stack.hasTagCompound()) stack.setTagCompound(new NBTTagCompound()); - stack.getTagCompound().setFloat(DURATION_MULTIPLIER_KEY, multiplier); - } - - /** Helper method for returning the max damage of a conjured item based on its NBT data. Centralises the code. - * Implementors will almost certainly want to call this from {@link Item#getMaxDamage(ItemStack stack)}. */ - public default int getMaxDamageFromNBT(ItemStack stack){ - if(stack.hasTagCompound() && stack.getTagCompound().hasKey(DURATION_MULTIPLIER_KEY)){ - return (int)(this.getBaseDuration() * stack.getTagCompound().getFloat(DURATION_MULTIPLIER_KEY)); - } - return this.getBaseDuration(); - } - - /** Returns the base duration in ticks for this conjured item. Should be a constant (commonly 600). - * Implementors may want to call this when setting an item's max damage in its constructor. */ - public int getBaseDuration(); - - @SubscribeEvent - public static void onLivingDropsEvent(LivingDropsEvent event){ - // Destroys conjured items if their caster dies. - for(EntityItem item : event.getDrops()){ - if(item.getEntityItem().getItem() instanceof IConjuredItem){ - item.setDead(); - } - } - } - - @SubscribeEvent - public static void onItemTossEvent(ItemTossEvent event){ - // Prevents conjured items being thrown by dragging and dropping outside the inventory. - if(event.getEntityItem().getEntityItem().getItem() instanceof IConjuredItem){ - event.setCanceled(true); - event.getPlayer().inventory.addItemStackToInventory(event.getEntityItem().getEntityItem()); - } - } -} diff --git a/src/main/java/electroblob/wizardry/item/ItemArcaneTome.java b/src/main/java/electroblob/wizardry/item/ItemArcaneTome.java index dd7688d7..0c24bb37 100644 --- a/src/main/java/electroblob/wizardry/item/ItemArcaneTome.java +++ b/src/main/java/electroblob/wizardry/item/ItemArcaneTome.java @@ -2,15 +2,14 @@ package electroblob.wizardry.item; import java.util.List; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryTabs; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumRarity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraft.util.StatCollector; public class ItemArcaneTome extends Item { @@ -18,42 +17,41 @@ public class ItemArcaneTome extends Item { super(); this.setHasSubtypes(true); this.setMaxStackSize(1); - this.setCreativeTab(WizardryTabs.WIZARDRY); + this.setCreativeTab(Wizardry.tabWizardry); + this.setTextureName("wizardry:arcane_tome"); + this.setUnlocalizedName("arcaneTome"); } @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item item, CreativeTabs tab, List list){ - for(int i=1; i tooltip, boolean showAdvanced){ - Tier tier = Tier.values()[stack.getItemDamage()]; - Tier tier2 = Tier.values()[stack.getItemDamage()-1]; - tooltip.add(tier.getDisplayNameWithFormatting()); - tooltip.add("\u00A77" + net.minecraft.client.resources.I18n.format("item.wizardry:arcane_tome.desc1", tier2.getDisplayNameWithFormatting())); - tooltip.add("\u00A77" + net.minecraft.client.resources.I18n.format("item.wizardry:arcane_tome.desc2", tier.getDisplayNameWithFormatting() + "\u00A77")); + public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4){ + EnumTier tier = EnumTier.values()[par1ItemStack.getItemDamage()]; + EnumTier tier2 = EnumTier.values()[par1ItemStack.getItemDamage()-1]; + par3List.add(tier.getDisplayNameWithFormatting()); + par3List.add("\u00A77" + StatCollector.translateToLocalFormatted("item.arcaneTome.desc1", tier2.getDisplayNameWithFormatting())); + par3List.add("\u00A77" + StatCollector.translateToLocalFormatted("item.arcaneTome.desc2", tier.getDisplayNameWithFormatting() + "\u00A77")); } } diff --git a/src/main/java/electroblob/wizardry/item/ItemArmourUpgrade.java b/src/main/java/electroblob/wizardry/item/ItemArmourUpgrade.java index b7b96f10..de8866ff 100644 --- a/src/main/java/electroblob/wizardry/item/ItemArmourUpgrade.java +++ b/src/main/java/electroblob/wizardry/item/ItemArmourUpgrade.java @@ -2,45 +2,44 @@ package electroblob.wizardry.item; import java.util.List; -import electroblob.wizardry.registry.WizardryTabs; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumRarity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraft.util.StatCollector; -public class ItemArmourUpgrade extends Item { +public class ItemArmourUpgrade extends Item{ public ItemArmourUpgrade() { super(); this.setMaxStackSize(1); - this.setCreativeTab(WizardryTabs.WIZARDRY); + this.setCreativeTab(Wizardry.tabWizardry); + this.setTextureName("wizardry:armour_upgrade"); } + /** + * Return an item rarity from EnumRarity + */ @Override - public EnumRarity getRarity(ItemStack stack){ - return EnumRarity.EPIC; + public EnumRarity getRarity(ItemStack par1ItemStack) + { + return EnumRarity.epic; } @Override - @SideOnly(Side.CLIENT) - public boolean hasEffect(ItemStack stack){ + public boolean hasEffect(ItemStack stack, int par2){ return true; } @Override - @SideOnly(Side.CLIENT) - public void addInformation(ItemStack stack, EntityPlayer player, List tooltip, boolean advanced){ - tooltip.add(net.minecraft.client.resources.I18n.format("item.wizardry:armour_upgrade.desc1", "\u00A77")); - tooltip.add(net.minecraft.client.resources.I18n.format("item.wizardry:armour_upgrade.desc2", "\u00A77", "\u00A7d")); + public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4){ + par3List.add(StatCollector.translateToLocalFormatted("item.armourUpgrade.desc1", "\u00A77")); + par3List.add(StatCollector.translateToLocalFormatted("item.armourUpgrade.desc2", "\u00A77", "\u00A7d")); + //par3List.add("\u00A77Upgrades any wizard armour"); + //par3List.add("\u00A77to make it \u00A7dlegendary"); } - - @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item item, CreativeTabs tab, List subItems){ - subItems.add(new ItemStack(this, 1)); - } } diff --git a/src/main/java/electroblob/wizardry/item/ItemFirebomb.java b/src/main/java/electroblob/wizardry/item/ItemFirebomb.java index add289ef..b8611509 100644 --- a/src/main/java/electroblob/wizardry/item/ItemFirebomb.java +++ b/src/main/java/electroblob/wizardry/item/ItemFirebomb.java @@ -1,50 +1,37 @@ package electroblob.wizardry.item; -import java.util.List; - +import electroblob.wizardry.Wizardry; import electroblob.wizardry.entity.projectile.EntityFirebomb; -import electroblob.wizardry.registry.WizardryTabs; -import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.ActionResult; -import net.minecraft.util.EnumActionResult; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; public class ItemFirebomb extends Item { - public ItemFirebomb(){ + public ItemFirebomb() + { this.maxStackSize = 16; - this.setCreativeTab(WizardryTabs.WIZARDRY); + this.setCreativeTab(Wizardry.tabWizardry); } - @Override - public ActionResult onItemRightClick(ItemStack stack, World world, EntityPlayer player, EnumHand hand){ - - if(!player.capabilities.isCreativeMode){ + /** + * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer entityplayer) + { + if (!entityplayer.capabilities.isCreativeMode) + { --stack.stackSize; } - player.playSound(SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + world.playSoundAtEntity(entityplayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); - if(!world.isRemote){ - EntityFirebomb firebomb = new EntityFirebomb(world, player); - // This is the standard set of parameters for this method, used by snowballs and ender pearls. - firebomb.setHeadingFromThrower(player, player.rotationPitch, player.rotationYaw, 0.0f, 1.5f, 1.0f); - world.spawnEntityInWorld(firebomb); + if (!world.isRemote) + { + world.spawnEntityInWorld(new EntityFirebomb(world, entityplayer)); } - return ActionResult.newResult(EnumActionResult.SUCCESS, stack); - } - - @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item parItem, CreativeTabs parTab, List parListSubItems){ - parListSubItems.add(new ItemStack(this, 1)); + return stack; } } \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/item/ItemFlamingAxe.java b/src/main/java/electroblob/wizardry/item/ItemFlamingAxe.java index 28e1400b..d0e113c2 100644 --- a/src/main/java/electroblob/wizardry/item/ItemFlamingAxe.java +++ b/src/main/java/electroblob/wizardry/item/ItemFlamingAxe.java @@ -1,10 +1,10 @@ package electroblob.wizardry.item; -import java.util.List; - -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import net.minecraft.creativetab.CreativeTabs; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.MagicDamage.DamageType; +import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; @@ -12,81 +12,72 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemAxe; import net.minecraft.item.ItemStack; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -public class ItemFlamingAxe extends ItemAxe implements IConjuredItem { +public class ItemFlamingAxe extends ItemAxe { public ItemFlamingAxe(ToolMaterial material) { - super(material, 8, -3); - this.setMaxDamage(getBaseDuration()); + super(material); + this.setMaxDamage(600); this.setNoRepair(); this.setCreativeTab(null); } - - @Override - public int getBaseDuration(){ - return 600; - } @Override - public int getMaxDamage(ItemStack stack){ - return this.getMaxDamageFromNBT(stack); + public int getMaxDamage(ItemStack stack) + { + return stack.hasTagCompound()? (int)(getMaxDamage()*stack.stackTagCompound.getFloat("durationMultiplier")) : getMaxDamage(); } @Override - // This method allows the code for the item's timer to be greatly simplified by damaging it directly from - // onUpdate() and removing the workaround that involved WizardData and all sorts of crazy stuff. - public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged){ - - if(oldStack != null || newStack != null){ - // We only care about the situation where we specifically want the animation NOT to play. - if(oldStack.getItem() == newStack.getItem() && !slotChanged) return false; + public void onUpdate(ItemStack itemstack, World par2World, Entity entity, int par4, boolean par5) { + // Allows the 'cheaty' damage bar rendering code to start working. + if(itemstack.getItemDamage() == 0){ + itemstack.setItemDamage(1); + } + if(entity instanceof EntityPlayer){ + ExtendedPlayer properties = ExtendedPlayer.get((EntityPlayer)entity); + properties.flamingAxeDuration++; + if(properties.flamingAxeDuration > this.getMaxDamage(itemstack)){ + ((EntityPlayer)entity).inventory.consumeInventoryItem(itemstack.getItem()); + properties.flamingAxeDuration = 0; + } } - - return super.shouldCauseReequipAnimation(oldStack, newStack, slotChanged); } @Override - public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected){ - int damage = stack.getItemDamage(); - if(damage > stack.getMaxDamage()) entity.replaceItemInInventory(slot, null); - stack.setItemDamage(damage + 1); - } - - @Override - public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase wielder){ + public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase wielder) + { if(!MagicDamage.isEntityImmune(DamageType.FIRE, target)) target.setFire(8); return false; } @Override - @SideOnly(Side.CLIENT) - public boolean hasEffect(ItemStack stack){ + public int getDisplayDamage(ItemStack stack){ + return Wizardry.proxy.getConjuredItemDisplayDamage(stack); + } + + @Override + public boolean hasEffect(ItemStack par1ItemStack, int pass){ return true; } @Override - public boolean getIsRepairable(ItemStack stack, ItemStack par2ItemStack){ + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) + { return false; } @Override - public int getItemEnchantability(){ + public int getItemEnchantability() + { return 0; } - // Cannot be dropped + //Cannot be dropped @Override - public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player){ + public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player) + { return false; } - - @Override - @SideOnly(Side.CLIENT) - // Why does this method pass in an item as an argument? It is always the same item the method is invoked on. - public void getSubItems(Item item, CreativeTabs tab, List items){ - items.add(new ItemStack(this, 1)); - } } diff --git a/src/main/java/electroblob/wizardry/item/ItemFrostAxe.java b/src/main/java/electroblob/wizardry/item/ItemFrostAxe.java index 0e6100e1..b380713c 100644 --- a/src/main/java/electroblob/wizardry/item/ItemFrostAxe.java +++ b/src/main/java/electroblob/wizardry/item/ItemFrostAxe.java @@ -1,94 +1,87 @@ package electroblob.wizardry.item; -import java.util.List; - -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import net.minecraft.creativetab.CreativeTabs; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.MagicDamage.DamageType; +import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; import net.minecraft.item.ItemAxe; import net.minecraft.item.ItemStack; import net.minecraft.potion.PotionEffect; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -public class ItemFrostAxe extends ItemAxe implements IConjuredItem { +public class ItemFrostAxe extends ItemAxe { public ItemFrostAxe(ToolMaterial material) { - super(material, 8, -3); - this.setMaxDamage(getBaseDuration()); + super(material); + this.setMaxDamage(600); this.setNoRepair(); this.setCreativeTab(null); } @Override - public int getBaseDuration(){ - return 600; - } - - @Override - public int getMaxDamage(ItemStack stack){ - return this.getMaxDamageFromNBT(stack); + public int getMaxDamage(ItemStack stack) + { + return stack.hasTagCompound()? (int)(getMaxDamage()*stack.stackTagCompound.getFloat("durationMultiplier")) : getMaxDamage(); } @Override - // This method allows the code for the item's timer to be greatly simplified by damaging it directly from - // onUpdate() and removing the workaround that involved WizardData and all sorts of crazy stuff. - public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged){ - - if(oldStack != null || newStack != null){ - // We only care about the situation where we specifically want the animation NOT to play. - if(oldStack.getItem() == newStack.getItem() && !slotChanged) return false; + public void onUpdate(ItemStack itemstack, World par2World, Entity entity, int par4, boolean par5) { + // Allows the 'cheaty' damage bar rendering code to start working. + if(itemstack.getItemDamage() == 0){ + itemstack.setItemDamage(1); + } + if(entity instanceof EntityPlayer){ + ExtendedPlayer properties = ExtendedPlayer.get((EntityPlayer)entity); + properties.frostAxeDuration++; + if(properties.frostAxeDuration > this.getMaxDamage(itemstack)){ + ((EntityPlayer)entity).inventory.consumeInventoryItem(itemstack.getItem()); + properties.frostAxeDuration = 0; + } } - - return super.shouldCauseReequipAnimation(oldStack, newStack, slotChanged); - } - - @Override - public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected){ - int damage = stack.getItemDamage(); - if(damage > stack.getMaxDamage()) entity.replaceItemInInventory(slot, null); - stack.setItemDamage(damage + 1); } + /** + * Current implementations of this method in child classes do not use the entry argument beside ev. They just raise + * the damage on the stack. + */ @Override public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase wielder) { - if(!MagicDamage.isEntityImmune(DamageType.FROST, target)) target.addPotionEffect(new PotionEffect(WizardryPotions.frost, 160, 1)); + if(!MagicDamage.isEntityImmune(DamageType.FROST, target)) target.addPotionEffect(new PotionEffect(Wizardry.frost.id, 160, 1)); return false; } @Override - @SideOnly(Side.CLIENT) - public boolean hasEffect(ItemStack stack){ + public int getDisplayDamage(ItemStack stack){ + return Wizardry.proxy.getConjuredItemDisplayDamage(stack); + } + + @Override + public boolean hasEffect(ItemStack par1ItemStack, int pass){ return true; } @Override - public boolean getIsRepairable(ItemStack stack, ItemStack par2ItemStack){ + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) + { return false; } @Override - public int getItemEnchantability(){ + public int getItemEnchantability() + { return 0; } - // Cannot be dropped + //Cannot be dropped @Override - public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player){ + public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player) + { return false; } - - @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item parItem, CreativeTabs parTab, List parListSubItems){ - parListSubItems.add(new ItemStack(this, 1)); - } } diff --git a/src/main/java/electroblob/wizardry/item/ItemIdentificationScroll.java b/src/main/java/electroblob/wizardry/item/ItemIdentificationScroll.java index 265bf225..f4ef13cd 100644 --- a/src/main/java/electroblob/wizardry/item/ItemIdentificationScroll.java +++ b/src/main/java/electroblob/wizardry/item/ItemIdentificationScroll.java @@ -2,84 +2,81 @@ package electroblob.wizardry.item; import java.util.List; -import electroblob.wizardry.WizardData; -import electroblob.wizardry.event.DiscoverSpellEvent; -import electroblob.wizardry.registry.WizardryAchievements; -import electroblob.wizardry.registry.WizardryTabs; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; +import net.minecraft.inventory.ContainerPlayer; +import net.minecraft.inventory.Slot; import net.minecraft.item.Item; +import net.minecraft.item.ItemBow; import net.minecraft.item.ItemStack; -import net.minecraft.util.ActionResult; -import net.minecraft.util.EnumActionResult; -import net.minecraft.util.EnumHand; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.item.ItemSword; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; public class ItemIdentificationScroll extends Item { - + public ItemIdentificationScroll() { super(); - this.setCreativeTab(WizardryTabs.WIZARDRY); + this.setTextureName("wizardry:identification_scroll"); + this.setUnlocalizedName("identification_scroll"); + this.setCreativeTab(Wizardry.tabWizardry); } - + @Override - @SideOnly(Side.CLIENT) public boolean hasEffect(ItemStack stack){ return true; } - + @Override - @SideOnly(Side.CLIENT) - public void addInformation(ItemStack stack, EntityPlayer player, List tooltip, boolean par4){ - tooltip.add(net.minecraft.client.resources.I18n.format("item.wizardry:identification_scroll.desc1", "\u00A77")); - tooltip.add(net.minecraft.client.resources.I18n.format("item.wizardry:identification_scroll.desc2", "\u00A77")); + public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4){ + par3List.add(StatCollector.translateToLocalFormatted("item.identification_scroll.desc1", "\u00A77")); + par3List.add(StatCollector.translateToLocalFormatted("item.identification_scroll.desc2", "\u00A77")); } - + @Override - public ActionResult onItemRightClick(ItemStack stack, World world, EntityPlayer player, EnumHand hand){ + public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player){ + + if(ExtendedPlayer.get(player) != null){ + + ExtendedPlayer properties = ExtendedPlayer.get(player); - if(WizardData.get(player) != null){ + // Isolates just the hotbar + List hotbar = ((ContainerPlayer)player.openContainer).inventorySlots.subList(36, 45); - WizardData properties = WizardData.get(player); + for(Object slot : hotbar){ - for(ItemStack stack1 : WizardryUtilities.getPrioritisedHotbarAndOffhand(player)){ + if(slot instanceof Slot){ - if(stack1 != null){ - Spell spell = Spell.get(stack1.getItemDamage()); - if((stack1.getItem() instanceof ItemSpellBook || stack1.getItem() instanceof ItemScroll) - && !properties.hasSpellBeenDiscovered(spell)){ + ItemStack stack1 = ((Slot)slot).getStack(); - if(!MinecraftForge.EVENT_BUS.post(new DiscoverSpellEvent(player, spell, DiscoverSpellEvent.Source.IDENTIFICATION_SCROLL))){ + if(stack1 != null){ + Spell spell = Spell.get(stack1.getItemDamage()); + if((stack1.getItem() instanceof ItemSpellBook || stack1.getItem() instanceof ItemScroll) + && !properties.hasSpellBeenDiscovered(spell)){ + // Identification scrolls give the chat readout in creative mode, otherwise it looks like // nothing happens! properties.discoverSpell(spell); - player.addStat(WizardryAchievements.identify_spell); - player.playSound(SoundEvents.ENTITY_PLAYER_LEVELUP, 1.25f, 1); + player.triggerAchievement(Wizardry.identifySpell); + world.playSoundAtEntity(player, "random.levelup", 1.25f, 1); if(!player.capabilities.isCreativeMode) stack.stackSize--; - if(!world.isRemote) player.addChatMessage(new TextComponentTranslation("spell.discover", spell.getNameForTranslationFormatted())); - - return new ActionResult(EnumActionResult.SUCCESS, stack); + if(!world.isRemote) player.addChatMessage(new ChatComponentTranslation("spell.discover", spell.getDisplayNameWithFormatting())); + + return stack; } } } } // If it found nothing to identify, it says so! - if(!world.isRemote) player.addChatMessage(new TextComponentTranslation("item.wizardry:identification_scroll.nothing_to_identify")); + if(!world.isRemote) player.addChatMessage(new ChatComponentTranslation("item.identification_scroll.nothing_to_identify")); } - - return new ActionResult(EnumActionResult.FAIL, stack); - } - - @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item parItem, CreativeTabs parTab, List parListSubItems){ - parListSubItems.add(new ItemStack(this, 1)); + + return stack; } } diff --git a/src/main/java/electroblob/wizardry/item/ItemPoisonBomb.java b/src/main/java/electroblob/wizardry/item/ItemPoisonBomb.java index 94261841..96b4c9f0 100644 --- a/src/main/java/electroblob/wizardry/item/ItemPoisonBomb.java +++ b/src/main/java/electroblob/wizardry/item/ItemPoisonBomb.java @@ -1,51 +1,37 @@ package electroblob.wizardry.item; -import java.util.List; - +import electroblob.wizardry.Wizardry; import electroblob.wizardry.entity.projectile.EntityPoisonBomb; -import electroblob.wizardry.registry.WizardryTabs; -import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.ActionResult; -import net.minecraft.util.EnumActionResult; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; public class ItemPoisonBomb extends Item { - public ItemPoisonBomb(){ + public ItemPoisonBomb() + { this.maxStackSize = 16; - this.setCreativeTab(WizardryTabs.WIZARDRY); + this.setCreativeTab(Wizardry.tabWizardry); } - @Override - public ActionResult onItemRightClick(ItemStack stack, World world, EntityPlayer player, EnumHand hand){ - - if(!player.capabilities.isCreativeMode){ + /** + * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer entityplayer) + { + if (!entityplayer.capabilities.isCreativeMode) + { --stack.stackSize; } - player.playSound(SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + world.playSoundAtEntity(entityplayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); - if(!world.isRemote){ - EntityPoisonBomb poisonbomb = new EntityPoisonBomb(world, player); - // This is the standard set of parameters for this method, used by snowballs and ender pearls. - poisonbomb.setHeadingFromThrower(player, player.rotationPitch, player.rotationYaw, 0.0f, 1.5f, 1.0f); - world.spawnEntityInWorld(poisonbomb); + if (!world.isRemote) + { + world.spawnEntityInWorld(new EntityPoisonBomb(world, entityplayer)); } - return ActionResult.newResult(EnumActionResult.SUCCESS, stack); + return stack; } - - @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item item, CreativeTabs tab, List subItems){ - subItems.add(new ItemStack(this, 1)); - } - } \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/item/ItemScroll.java b/src/main/java/electroblob/wizardry/item/ItemScroll.java index b77a95f6..79e57aed 100644 --- a/src/main/java/electroblob/wizardry/item/ItemScroll.java +++ b/src/main/java/electroblob/wizardry/item/ItemScroll.java @@ -2,26 +2,25 @@ package electroblob.wizardry.item; import java.util.List; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.event.SpellCastEvent; -import electroblob.wizardry.event.SpellCastEvent.Source; +import electroblob.wizardry.WizardryRegistry; import electroblob.wizardry.packet.PacketCastSpell; import electroblob.wizardry.packet.WizardryPacketHandler; -import electroblob.wizardry.registry.WizardryTabs; import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.SpellModifiers; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.ActionResult; -import net.minecraft.util.EnumActionResult; -import net.minecraft.util.EnumHand; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagIntArray; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; public class ItemScroll extends Item { @@ -29,23 +28,24 @@ public class ItemScroll extends Item { super(); this.setHasSubtypes(true); this.setMaxStackSize(1); - this.setCreativeTab(WizardryTabs.SPELLS); + this.setCreativeTab(Wizardry.tabSpells); + this.setTextureName("wizardry:scroll"); + this.setUnlocalizedName("scroll"); } @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item item, CreativeTabs par2CreativeTabs, List list){ + public void getSubItems(Item item, CreativeTabs par2CreativeTabs, List list){ + // Isn't this sooooo much neater with the filter thing? for(Spell spell : Spell.getSpells(Spell.nonContinuousSpells)){ list.add(new ItemStack(item, 1, spell.id())); } } @Override - @SideOnly(Side.CLIENT) - public boolean hasEffect(ItemStack stack){ + public boolean hasEffect(ItemStack stack, int par2){ return true; } - + @Override // Item's version of this method is, quite frankly, an abomination. Why is a deprecated method being used as such // an integral part of the code? And what's the point in getUnlocalisedNameInefficiently? @@ -60,61 +60,70 @@ public class ItemScroll extends Item { * Simply put, I can't predict that, and it's not my job to cater for other people's incorrect usage of code, * especially when that might compromise some perfectly reasonable use (think Bibliocraft's 'best guess' book * detection). */ - // TODO: Backport this proxy-based fix. return Wizardry.proxy.getScrollDisplayName(stack); } @Override - public ActionResult onItemRightClick(ItemStack stack, World world, EntityPlayer player, EnumHand hand){ + public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player){ + if(player.isPotionActive(Wizardry.arcaneJammer)) return stack; + Spell spell = Spell.get(stack.getItemDamage()); - // By default, scrolls have no modifiers - but with the event system, they could be added. - SpellModifiers modifiers = new SpellModifiers(); - - // If anything stops the spell working at this point, nothing else happens. - if(MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Pre(player, spell, modifiers, Source.SCROLL))){ - return new ActionResult(EnumActionResult.FAIL, stack); + + // If a spell is disabled in the config, it will not work. + if(!spell.isEnabled()){ + if(!world.isRemote) player.addChatMessage(new ChatComponentTranslation("spell.disabled", spell.getDisplayNameWithFormatting())); + return stack; } - + if(!spell.isContinuous){ - if(!world.isRemote){ - - if(spell.cast(world, player, hand, 0, new SpellModifiers())){ - - MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(player, spell, modifiers, Source.SCROLL)); + /* + if(spell.chargeup > 0 && !entityplayer.isUsingItem()){ + // Spells with a chargeup time are now handled separately. + entityplayer.setItemInUse(stack, this.getMaxItemUseDuration(stack)); + return stack; + } + */ + if(!world.isRemote){ + + if(spell.cast(world, player, 0, 1, 1, 1, 1)){ + if(spell.doesSpellRequirePacket()){ // Sends a packet to all players in dimension to tell them to spawn particles. - IMessage msg = new PacketCastSpell.Message(player.getEntityId(), hand, spell.id(), modifiers); - WizardryPacketHandler.net.sendToDimension(msg, world.provider.getDimension()); + IMessage msg = new PacketCastSpell.Message(player.getEntityId(), 0, spell.id(), 1, 1, 1); + WizardryPacketHandler.net.sendToDimension(msg, world.provider.dimensionId); } - - // Scrolls are consumed upon successful use in survival mode + + if(!player.capabilities.isCreativeMode && !ExtendedPlayer.get(player).hasSpellBeenDiscovered(spell) && Wizardry.discoveryMode){ + player.worldObj.playSoundAtEntity(player, "random.levelup", 1.25f, 1); + if(!player.worldObj.isRemote) player.addChatMessage(new ChatComponentTranslation("spell.discover", spell.getDisplayNameWithFormatting())); + } + ExtendedPlayer.get(player).discoverSpell(spell); + if(!player.capabilities.isCreativeMode) stack.stackSize--; - - return new ActionResult(EnumActionResult.SUCCESS, stack); } - - // This else if check was bugging me for AGES! I can't believe I didn't compare to ItemWand before. - }else if(!spell.doesSpellRequirePacket()){ - // Client-inconsistent spell casting. This code only runs client-side. - if(spell.cast(world, player, hand, 0, modifiers)){ - // This is all that needs to happen, because everything above works fine on just the server side. - MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(player, spell, modifiers, Source.SCROLL)); - return new ActionResult(EnumActionResult.SUCCESS, stack); + + }else{ + if(spell.cast(world, player, 0, 1, 1, 1, 1)){ + // Added in version 1.1.3 to fix the client-side spell discovery not updating for spells with the + // packet optimisation. + if(ExtendedPlayer.get(player) != null){ + ExtendedPlayer.get(player).discoverSpell(spell); + } } } } - - return new ActionResult(EnumActionResult.FAIL, stack); - + + return stack; + } @Override @SideOnly(Side.CLIENT) - public net.minecraft.client.gui.FontRenderer getFontRenderer(ItemStack stack){ + public FontRenderer getFontRenderer(ItemStack stack){ return Wizardry.proxy.getFontRenderer(stack); } } diff --git a/src/main/java/electroblob/wizardry/item/ItemSmokeBomb.java b/src/main/java/electroblob/wizardry/item/ItemSmokeBomb.java index a2180d97..71128b8a 100644 --- a/src/main/java/electroblob/wizardry/item/ItemSmokeBomb.java +++ b/src/main/java/electroblob/wizardry/item/ItemSmokeBomb.java @@ -1,50 +1,37 @@ package electroblob.wizardry.item; -import java.util.List; - +import electroblob.wizardry.Wizardry; import electroblob.wizardry.entity.projectile.EntitySmokeBomb; -import electroblob.wizardry.registry.WizardryTabs; -import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.ActionResult; -import net.minecraft.util.EnumActionResult; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; public class ItemSmokeBomb extends Item { - public ItemSmokeBomb(){ + public ItemSmokeBomb() + { this.maxStackSize = 16; - this.setCreativeTab(WizardryTabs.WIZARDRY); + this.setCreativeTab(Wizardry.tabWizardry); } - @Override - public ActionResult onItemRightClick(ItemStack stack, World world, EntityPlayer player, EnumHand hand){ - - if(!player.capabilities.isCreativeMode){ + /** + * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer + */ + public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer entityplayer) + { + if (!entityplayer.capabilities.isCreativeMode) + { --stack.stackSize; } - player.playSound(SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + world.playSoundAtEntity(entityplayer, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); - if(!world.isRemote){ - EntitySmokeBomb smokebomb = new EntitySmokeBomb(world, player); - // This is the standard set of parameters for this method, used by snowballs and ender pearls. - smokebomb.setHeadingFromThrower(player, player.rotationPitch, player.rotationYaw, 0.0f, 1.5f, 1.0f); - world.spawnEntityInWorld(smokebomb); + if (!world.isRemote) + { + world.spawnEntityInWorld(new EntitySmokeBomb(world, entityplayer)); } - return ActionResult.newResult(EnumActionResult.SUCCESS, stack); - } - - @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item item, CreativeTabs tab, List subItems){ - subItems.add(new ItemStack(this, 1)); + return stack; } } \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/item/ItemSpawnWizard.java b/src/main/java/electroblob/wizardry/item/ItemSpawnWizard.java new file mode 100644 index 00000000..25052f04 --- /dev/null +++ b/src/main/java/electroblob/wizardry/item/ItemSpawnWizard.java @@ -0,0 +1,194 @@ +package electroblob.wizardry.item; + +import java.util.List; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.entity.living.EntityEvilWizard; +import electroblob.wizardry.entity.living.EntityWizard; +import net.minecraft.block.Block; +import net.minecraft.block.BlockLiquid; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.IEntityLivingData; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemMonsterPlacer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Facing; +import net.minecraft.util.MathHelper; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.StatCollector; +import net.minecraft.world.World; + +public class ItemSpawnWizard extends ItemMonsterPlacer { + + public ItemSpawnWizard(){ + this.setHasSubtypes(true); + this.setCreativeTab(Wizardry.tabWizardry); + this.setTextureName("minecraft:spawn_egg"); + } + + // Copied from Item to revert to normal behaviour. + @Override + public String getItemStackDisplayName(ItemStack stack) + { + return ("" + StatCollector.translateToLocal(this.getUnlocalizedName(stack) + ".name")).trim(); + } + + @Override + public String getUnlocalizedName(ItemStack stack){ + return stack.getItemDamage() == 1 ? "item.spawn_evil_wizard" : "item.spawn_wizard"; + } + + /** + * Callback for item usage. If the item does something special on right clicking, he will have one of those. Return + * True if something happen and false if it don't. This is for ITEMS, not BLOCKS + */ + @Override + public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int p_77648_4_, int p_77648_5_, int p_77648_6_, int p_77648_7_, float p_77648_8_, float p_77648_9_, float p_77648_10_) + { + if (world.isRemote) + { + return true; + } + else + { + Block block = world.getBlock(p_77648_4_, p_77648_5_, p_77648_6_); + p_77648_4_ += Facing.offsetsXForSide[p_77648_7_]; + p_77648_5_ += Facing.offsetsYForSide[p_77648_7_]; + p_77648_6_ += Facing.offsetsZForSide[p_77648_7_]; + double d0 = 0.0D; + + if (p_77648_7_ == 1 && block.getRenderType() == 11) + { + d0 = 0.5D; + } + + Entity entity = ItemSpawnWizard.spawnCreature(world, stack.getItemDamage(), (double)p_77648_4_ + 0.5D, (double)p_77648_5_ + d0, (double)p_77648_6_ + 0.5D); + + if (entity != null) + { + if (entity instanceof EntityLivingBase && stack.hasDisplayName()) + { + ((EntityLiving)entity).setCustomNameTag(stack.getDisplayName()); + } + + if (!player.capabilities.isCreativeMode) + { + --stack.stackSize; + } + } + + return true; + } + } + + /** + * Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer + */ + @Override + public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) + { + if (world.isRemote) + { + return stack; + } + else + { + MovingObjectPosition movingobjectposition = this.getMovingObjectPositionFromPlayer(world, player, true); + + if (movingobjectposition == null) + { + return stack; + } + else + { + if (movingobjectposition.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) + { + int i = movingobjectposition.blockX; + int j = movingobjectposition.blockY; + int k = movingobjectposition.blockZ; + + if (!world.canMineBlock(player, i, j, k)) + { + return stack; + } + + if (!player.canPlayerEdit(i, j, k, movingobjectposition.sideHit, stack)) + { + return stack; + } + + if (world.getBlock(i, j, k) instanceof BlockLiquid) + { + Entity entity = ItemSpawnWizard.spawnCreature(world, stack.getItemDamage(), (double)i, (double)j, (double)k); + + if (entity != null) + { + if (entity instanceof EntityLivingBase && stack.hasDisplayName()) + { + ((EntityLiving)entity).setCustomNameTag(stack.getDisplayName()); + } + + if (!player.capabilities.isCreativeMode) + { + --stack.stackSize; + } + } + } + } + + return stack; + } + } + } + + /** + * Spawns the creature specified by the egg's type in the location specified by the last three parameters. + * Parameters: world, metadata, x, y, z. + */ + public static Entity spawnCreature(World world, int metadata, double x, double y, double z){ + + Entity entity = null; + + for (int j = 0; j < 1; ++j) + { + entity = metadata == 1? new EntityEvilWizard(world) : new EntityWizard(world); + + if (entity != null && entity instanceof EntityLivingBase) + { + EntityLiving entityliving = (EntityLiving)entity; + entity.setLocationAndAngles(x, y, z, MathHelper.wrapAngleTo180_float(world.rand.nextFloat() * 360.0F), 0.0F); + entityliving.rotationYawHead = entityliving.rotationYaw; + entityliving.renderYawOffset = entityliving.rotationYaw; + entityliving.onSpawnWithEgg((IEntityLivingData)null); + world.spawnEntityInWorld(entity); + entityliving.playLivingSound(); + } + } + + return entity; + + } + + @Override + @SideOnly(Side.CLIENT) + public int getColorFromItemStack(ItemStack stack, int layer){ + if(stack.getItemDamage() == 1) return layer == 0 ? 0x290404 : 0xee9312; + return layer == 0 ? 0x19295e : 0xee9312; + } + + // Copied from Item to revert to normal behaviour. + @Override + @SideOnly(Side.CLIENT) + public void getSubItems(Item p_150895_1_, CreativeTabs p_150895_2_, List p_150895_3_) + { + p_150895_3_.add(new ItemStack(p_150895_1_, 1, 0)); + p_150895_3_.add(new ItemStack(p_150895_1_, 1, 1)); + } + +} diff --git a/src/main/java/electroblob/wizardry/item/ItemSpectralArmour.java b/src/main/java/electroblob/wizardry/item/ItemSpectralArmour.java index 951b69d9..2bea60ff 100644 --- a/src/main/java/electroblob/wizardry/item/ItemSpectralArmour.java +++ b/src/main/java/electroblob/wizardry/item/ItemSpectralArmour.java @@ -1,110 +1,117 @@ package electroblob.wizardry.item; import java.util.List; +import java.util.Locale; -import net.minecraft.creativetab.CreativeTabs; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.Wizardry; +import net.minecraft.client.model.ModelBiped; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.EntityEquipmentSlot; +import net.minecraft.item.EnumAction; import net.minecraft.item.EnumRarity; -import net.minecraft.item.Item; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; +import net.minecraft.util.DamageSource; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.common.ISpecialArmor.ArmorProperties; -public class ItemSpectralArmour extends ItemArmor implements IConjuredItem { +public class ItemSpectralArmour extends ItemArmor { - public ItemSpectralArmour(ArmorMaterial material, int renderIndex, EntityEquipmentSlot armourType) { + /** Armour types: 0 = helmet, 1 = chestplate, 2 = leggings, 3 = boots */ + public ItemSpectralArmour(ArmorMaterial material, int renderIndex, int armourType) { super(material, renderIndex, armourType); this.setCreativeTab(null); - this.setMaxDamage(getBaseDuration()); + this.setMaxDamage(1200); + + // Sets item icon texture and unlocalised name according to element and armour type. + switch(armourType){ + case 0: + this.setTextureName("wizardry:spectral_helmet"); + this.setUnlocalizedName("spectral_helmet"); + break; + case 1: + this.setTextureName("wizardry:spectral_chestplate"); + this.setUnlocalizedName("spectral_chestplate"); + break; + case 2: + this.setTextureName("wizardry:spectral_leggings"); + this.setUnlocalizedName("spectral_leggings"); + break; + case 3: + this.setTextureName("wizardry:spectral_boots"); + this.setUnlocalizedName("spectral_boots"); + break; + } } - + @Override - public int getBaseDuration(){ - return 1200; - } - - @Override - public int getMaxDamage(ItemStack stack){ - return this.getMaxDamageFromNBT(stack); + public int getMaxDamage(ItemStack stack) + { + return stack.hasTagCompound()? (int)(getMaxDamage()*stack.stackTagCompound.getFloat("durationMultiplier")) : getMaxDamage(); } // Overridden to stop the enchantment trick making the name turn blue. @Override - public EnumRarity getRarity(ItemStack stack){ - return EnumRarity.COMMON; + public EnumRarity getRarity(ItemStack p_77613_1_) + { + return EnumRarity.common; } @Override - // This method allows the code for the item's timer to be greatly simplified by damaging it directly from - // onUpdate() and removing the workaround that involved WizardData and all sorts of crazy stuff. - public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged){ - - if(oldStack != null || newStack != null){ - // We only care about the situation where we specifically want the animation NOT to play. - if(oldStack.getItem() == newStack.getItem() && !slotChanged) return false; + public void onArmorTick(World world, EntityPlayer player, ItemStack itemstack) { + // Allows the 'cheaty' damage bar rendering code to start working. + if(itemstack.getItemDamage() == 0){ + itemstack.setItemDamage(1); + } + ExtendedPlayer properties = ExtendedPlayer.get(player); + if(properties.conjuredArmourDuration > this.getMaxDamage(itemstack)){ + ((EntityPlayer)player).inventory.armorInventory[3-this.armorType] = null; } - - return super.shouldCauseReequipAnimation(oldStack, newStack, slotChanged); } @Override - public void onArmorTick(World world, EntityPlayer player, ItemStack stack){ - int damage = stack.getItemDamage(); - if(damage > stack.getMaxDamage()) player.inventory.clearMatchingItems(this, -1, 1, null); - stack.setItemDamage(damage + 1); - } + public int getDisplayDamage(ItemStack stack){ + return Wizardry.proxy.getConjuredItemDisplayDamage(stack); + } @Override - @SideOnly(Side.CLIENT) - public boolean hasEffect(ItemStack stack){ + public boolean hasEffect(ItemStack par1ItemStack, int pass){ return true; } @Override - public boolean getIsRepairable(ItemStack stack, ItemStack par2ItemStack){ + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) + { return false; } @Override - public int getItemEnchantability(){ + public int getItemEnchantability() + { return 0; } // Cannot be dropped @Override - public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player){ + public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player) + { return false; } @Override - public String getArmorTexture(ItemStack stack, Entity entity, EntityEquipmentSlot slot, String type) { - - if(slot == EntityEquipmentSlot.LEGS) return "wizardry:textures/armour/spectral_armour_legs.png"; + public String getArmorTexture(ItemStack stack, Entity entity, int slot, String type) + { + if(slot == 2) return "wizardry:textures/armour/spectral_armour_legs.png"; return "wizardry:textures/armour/spectral_armour.png"; - } - - @Override - @SideOnly(Side.CLIENT) - public net.minecraft.client.model.ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, EntityEquipmentSlot armorSlot, - net.minecraft.client.model.ModelBiped _default) { - net.minecraft.client.renderer.GlStateManager.enableBlend(); - net.minecraft.client.renderer.GlStateManager.tryBlendFuncSeparate(net.minecraft.client.renderer.GlStateManager.SourceFactor.SRC_ALPHA, net.minecraft.client.renderer.GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, - net.minecraft.client.renderer.GlStateManager.SourceFactor.ONE, net.minecraft.client.renderer.GlStateManager.DestFactor.ZERO); - return super.getArmorModel(entityLiving, itemStack, armorSlot, _default); - } - - @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item parItem, CreativeTabs parTab, List parListSubItems){ - parListSubItems.add(new ItemStack(this, 1)); } } diff --git a/src/main/java/electroblob/wizardry/item/ItemSpectralBow.java b/src/main/java/electroblob/wizardry/item/ItemSpectralBow.java index b25efc8d..3f430376 100644 --- a/src/main/java/electroblob/wizardry/item/ItemSpectralBow.java +++ b/src/main/java/electroblob/wizardry/item/ItemSpectralBow.java @@ -1,229 +1,204 @@ package electroblob.wizardry.item; -import java.util.List; - -import javax.annotation.Nullable; +import javax.swing.Icon; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; import net.minecraft.client.Minecraft; -import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.projectile.EntityArrow; -import net.minecraft.init.Enchantments; import net.minecraft.init.Items; -import net.minecraft.init.SoundEvents; -import net.minecraft.item.IItemPropertyGetter; -import net.minecraft.item.Item; -import net.minecraft.item.ItemArrow; import net.minecraft.item.ItemBow; import net.minecraft.item.ItemStack; -import net.minecraft.stats.StatList; -import net.minecraft.util.ActionResult; -import net.minecraft.util.EnumActionResult; -import net.minecraft.util.EnumHand; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.SoundCategory; +import net.minecraft.util.IIcon; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.player.ArrowLooseEvent; +import net.minecraftforge.event.entity.player.ArrowNockEvent; -public class ItemSpectralBow extends ItemBow implements IConjuredItem { +public class ItemSpectralBow extends ItemBow { - public ItemSpectralBow(){ + @SideOnly(Side.CLIENT) + private IIcon[] iconArray; + + public ItemSpectralBow() { super(); - this.setMaxDamage(getBaseDuration()); + this.setMaxDamage(600); this.setNoRepair(); this.setCreativeTab(null); - this.addPropertyOverride(new ResourceLocation("pull"), new IItemPropertyGetter() - { - @SideOnly(Side.CLIENT) - public float apply(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn) - { - if (entityIn == null) - { - return 0.0F; - } - else - { - ItemStack itemstack = entityIn.getActiveItemStack(); - // Mojang, observe - hardcoding item references into their own classes is NOT good Java. - return itemstack != null && itemstack.getItem() == ItemSpectralBow.this ? (float)(stack.getMaxItemUseDuration() - entityIn.getItemInUseCount()) / 20.0F : 0.0F; - } - } - }); - this.addPropertyOverride(new ResourceLocation("pulling"), new IItemPropertyGetter() - { - @SideOnly(Side.CLIENT) - public float apply(ItemStack stack, @Nullable World worldIn, @Nullable EntityLivingBase entityIn) - { - return entityIn != null && entityIn.isHandActive() && entityIn.getActiveItemStack() == stack ? 1.0F : 0.0F; - } - }); } - + @Override - @SideOnly(Side.CLIENT) - // Why does this still exist? Item models deal with this now, right? public boolean isFull3D(){ return true; } @Override - public int getBaseDuration(){ - return 600; - } - - @Override - public int getMaxDamage(ItemStack stack){ - return this.getMaxDamageFromNBT(stack); + public int getMaxDamage(ItemStack stack) + { + return stack.hasTagCompound()? (int)(getMaxDamage()*stack.stackTagCompound.getFloat("durationMultiplier")) : getMaxDamage(); } @Override - // This method allows the code for the item's timer to be greatly simplified by damaging it directly from - // onUpdate() and removing the workaround that involved WizardData and all sorts of crazy stuff. - public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged){ - - if(oldStack != null && newStack != null){ - // We only care about the situation where we specifically want the animation NOT to play. - if(oldStack.getItem() == newStack.getItem() && !slotChanged - // This code should only run on the client side, so using Minecraft is ok. - && !Minecraft.getMinecraft().thePlayer.isHandActive()) return false; + public ItemStack onItemRightClick(ItemStack p_77659_1_, World p_77659_2_, EntityPlayer p_77659_3_) + { + ArrowNockEvent event = new ArrowNockEvent(p_77659_3_, p_77659_1_); + MinecraftForge.EVENT_BUS.post(event); + if (event.isCanceled()) + { + return event.result; + } + + // Spectral bow always fires, regardless of whether you have an arrow or not. + p_77659_3_.setItemInUse(p_77659_1_, this.getMaxItemUseDuration(p_77659_1_)); + + return p_77659_1_; + } + + @Override + public void onUpdate(ItemStack itemstack, World par2World, Entity entity, int par4, boolean par5) { + // Allows the 'cheaty' damage bar rendering code to start working. + if(itemstack.getItemDamage() == 0){ + itemstack.setItemDamage(1); } - - return super.shouldCauseReequipAnimation(oldStack, newStack, slotChanged); - } - - @Override - public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected){ - int damage = stack.getItemDamage(); - if(damage > stack.getMaxDamage()) entity.replaceItemInInventory(slot, null); - // Can't damage it whilst in use because for some reason it causes the item use to constantly reset. - if(!(entity instanceof EntityLivingBase) || !((EntityLivingBase)entity).isHandActive()){ - stack.setItemDamage(damage + 1); - } - } - - // The following two methods re-route the displayed durability through the proxies in order to override the pausing - // of the item timer when the bow is being pulled. - - @Override - public double getDurabilityForDisplay(ItemStack stack){ - return Wizardry.proxy.getConjuredBowDurability(stack); - } - - public double getDefaultDurabilityForDisplay(ItemStack stack){ - return super.getDurabilityForDisplay(stack); - } - - @Override - public ActionResult onItemRightClick(ItemStack stack, World world, EntityPlayer player, EnumHand hand){ - - ActionResult ret = net.minecraftforge.event.ForgeEventFactory.onArrowNock(stack, world, player, hand, true); - - if(ret != null) return ret; - - player.setActiveHand(hand); - - return ActionResult.newResult(EnumActionResult.SUCCESS, stack); - - } - - @Override - @SideOnly(Side.CLIENT) - public boolean hasEffect(ItemStack stack){ - return true; - } - - @Override - public boolean getIsRepairable(ItemStack stack, ItemStack stack2){ - return false; - } - - @Override - public int getItemEnchantability(){ - return 0; - } - - // Cannot be dropped - @Override - public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player){ - return false; - } - - @Override - public void onUsingTick(ItemStack stack, EntityLivingBase player, int count){ - // player.getItemInUseMaxCount() is named incorrectly; you only have to look at the method to see what it really - // does. - if(stack.getItemDamage() + player.getItemInUseMaxCount() > stack.getMaxDamage()) - player.replaceItemInInventory(player.getActiveHand() == EnumHand.MAIN_HAND ? 98 : 99, null); - } - - @Override - public void onPlayerStoppedUsing(ItemStack stack, World world, EntityLivingBase entity, int timeLeft){ - // Decreases the timer by the amount it should have been decreased while the bow was in use. - if(!world.isRemote) stack.setItemDamage(stack.getItemDamage() + (this.getMaxItemUseDuration(stack) - timeLeft)); - - if (entity instanceof EntityPlayer){ - - EntityPlayer entityplayer = (EntityPlayer)entity; - - int i = this.getMaxItemUseDuration(stack) - timeLeft; - i = net.minecraftforge.event.ForgeEventFactory.onArrowLoose(stack, world, (EntityPlayer)entity, i, true); - if (i < 0) return; - - float f = getArrowVelocity(i); - - if ((double)f >= 0.1D){ - - if (!world.isRemote){ - - ItemArrow itemarrow = (ItemArrow)Items.ARROW; - EntityArrow entityarrow = itemarrow.createArrow(world, new ItemStack(itemarrow), entityplayer); - entityarrow.setAim(entityplayer, entityplayer.rotationPitch, entityplayer.rotationYaw, 0.0F, f * 3.0F, 1.0F); - - if (f == 1.0F) - { - entityarrow.setIsCritical(true); - } - - int j = EnchantmentHelper.getEnchantmentLevel(Enchantments.POWER, stack); - - if (j > 0) - { - entityarrow.setDamage(entityarrow.getDamage() + (double)j * 0.5D + 0.5D); - } - - int k = EnchantmentHelper.getEnchantmentLevel(Enchantments.PUNCH, stack); - - if (k > 0) - { - entityarrow.setKnockbackStrength(k); - } - - if (EnchantmentHelper.getEnchantmentLevel(Enchantments.FLAME, stack) > 0) - { - entityarrow.setFire(100); - } - - entityarrow.pickupStatus = EntityArrow.PickupStatus.DISALLOWED; - - world.spawnEntityInWorld(entityarrow); - } - - world.playSound((EntityPlayer)null, entityplayer.posX, entityplayer.posY, entityplayer.posZ, SoundEvents.ENTITY_ARROW_SHOOT, SoundCategory.NEUTRAL, 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + f * 0.5F); - - entityplayer.addStat(StatList.getObjectUseStats(this)); + if(entity instanceof EntityPlayer){ + ExtendedPlayer properties = ExtendedPlayer.get((EntityPlayer)entity); + properties.conjuredBowDuration++; + if(properties.conjuredBowDuration > this.getMaxDamage(itemstack)){ + ((EntityPlayer)entity).inventory.consumeInventoryItem(itemstack.getItem()); + properties.conjuredBowDuration = 0; } } } - + @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item item, CreativeTabs tab, List subItems){ - subItems.add(new ItemStack(this, 1)); + public int getDisplayDamage(ItemStack stack){ + return Wizardry.proxy.getConjuredItemDisplayDamage(stack); + } + + @Override + public boolean hasEffect(ItemStack par1ItemStack, int pass){ + return true; } + @Override + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) + { + return false; + } + + @Override + public int getItemEnchantability() + { + return 0; + } + + // Cannot be dropped + @Override + public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player) + { + return false; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister par1IconRegister) + { + this.itemIcon = par1IconRegister.registerIcon("wizardry:spectral_bow_standby"); + this.iconArray = new IIcon[bowPullIconNameArray.length]; + + for (int i = 0; i < this.iconArray.length; ++i) + { + this.iconArray[i] = par1IconRegister.registerIcon("wizardry:spectral_bow_" + bowPullIconNameArray[i]); + } + } + + @Override + public IIcon getIcon(ItemStack stack, int renderPass, EntityPlayer player, ItemStack usingItem, int useRemaining) + { + if(player.getItemInUse() == null) return this.itemIcon; + int time = stack.getMaxItemUseDuration() - useRemaining; + if (time >= 18) + { + return iconArray[2]; + } + else if (time > 9) + { + return iconArray[1]; + } + else if (time > 0) + { + return iconArray[0]; + } + return itemIcon; + } + + @Override + public void onPlayerStoppedUsing(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer, int par4) + { + int j = this.getMaxItemUseDuration(par1ItemStack) - par4; + + ArrowLooseEvent event = new ArrowLooseEvent(par3EntityPlayer, par1ItemStack, j); + MinecraftForge.EVENT_BUS.post(event); + if (event.isCanceled()) + { + return; + } + j = event.charge; + + float f = (float)j / 20.0F; + f = (f * f + f * 2.0F) / 3.0F; + + if ((double)f < 0.1D) + { + return; + } + + if (f > 1.0F) + { + f = 1.0F; + } + + EntityArrow entityarrow = new EntityArrow(par2World, par3EntityPlayer, f * 2.0F); + + if (f == 1.0F) + { + entityarrow.setIsCritical(true); + } + + int k = EnchantmentHelper.getEnchantmentLevel(Enchantment.power.effectId, par1ItemStack); + + if (k > 0) + { + entityarrow.setDamage(entityarrow.getDamage() + (double)k * 0.5D + 0.5D); + } + + int l = EnchantmentHelper.getEnchantmentLevel(Enchantment.punch.effectId, par1ItemStack); + + if (l > 0) + { + entityarrow.setKnockbackStrength(l); + } + + if (EnchantmentHelper.getEnchantmentLevel(Enchantment.flame.effectId, par1ItemStack) > 0) + { + entityarrow.setFire(100); + } + + par1ItemStack.damageItem(1, par3EntityPlayer); + par2World.playSoundAtEntity(par3EntityPlayer, "random.bow", 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + f * 0.5F); + + entityarrow.canBePickedUp = 2; + + if (!par2World.isRemote) + { + par2World.spawnEntityInWorld(entityarrow); + } + } } diff --git a/src/main/java/electroblob/wizardry/item/ItemSpectralPickaxe.java b/src/main/java/electroblob/wizardry/item/ItemSpectralPickaxe.java index a91c9000..767beee0 100644 --- a/src/main/java/electroblob/wizardry/item/ItemSpectralPickaxe.java +++ b/src/main/java/electroblob/wizardry/item/ItemSpectralPickaxe.java @@ -1,82 +1,72 @@ package electroblob.wizardry.item; -import java.util.List; - -import net.minecraft.creativetab.CreativeTabs; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.Wizardry; +import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; import net.minecraft.item.ItemPickaxe; import net.minecraft.item.ItemStack; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -public class ItemSpectralPickaxe extends ItemPickaxe implements IConjuredItem { +public class ItemSpectralPickaxe extends ItemPickaxe{ - public ItemSpectralPickaxe(ToolMaterial material){ + public ItemSpectralPickaxe(ToolMaterial material) { super(material); - this.setMaxDamage(getBaseDuration()); + this.setMaxDamage(600); this.setNoRepair(); this.setCreativeTab(null); } @Override - public int getBaseDuration(){ - return 600; - } - - @Override - public int getMaxDamage(ItemStack stack){ - return this.getMaxDamageFromNBT(stack); + public int getMaxDamage(ItemStack stack) + { + return stack.hasTagCompound()? (int)(getMaxDamage()*stack.stackTagCompound.getFloat("durationMultiplier")) : getMaxDamage(); } @Override - // This method allows the code for the item's timer to be greatly simplified by damaging it directly from - // onUpdate() and removing the workaround that involved WizardData and all sorts of crazy stuff. - public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged){ - - if(oldStack != null || newStack != null){ - // We only care about the situation where we specifically want the animation NOT to play. - if(oldStack.getItem() == newStack.getItem() && !slotChanged) return false; + public void onUpdate(ItemStack itemstack, World par2World, Entity entity, int par4, boolean par5) { + // Allows the 'cheaty' damage bar rendering code to start working. + if(itemstack.getItemDamage() == 0){ + itemstack.setItemDamage(1); + } + if(entity instanceof EntityPlayer){ + ExtendedPlayer properties = ExtendedPlayer.get((EntityPlayer)entity); + properties.conjuredPickaxeDuration++; + if(properties.conjuredPickaxeDuration > this.getMaxDamage(itemstack)){ + ((EntityPlayer)entity).inventory.consumeInventoryItem(itemstack.getItem()); + properties.conjuredPickaxeDuration = 0; + } } - - return super.shouldCauseReequipAnimation(oldStack, newStack, slotChanged); } @Override - public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected){ - int damage = stack.getItemDamage(); - if(damage > stack.getMaxDamage()) entity.replaceItemInInventory(slot, null); - stack.setItemDamage(damage + 1); - } + public int getDisplayDamage(ItemStack stack){ + return Wizardry.proxy.getConjuredItemDisplayDamage(stack); + } @Override - @SideOnly(Side.CLIENT) - public boolean hasEffect(ItemStack stack){ + public boolean hasEffect(ItemStack par1ItemStack, int pass){ return true; } @Override - public boolean getIsRepairable(ItemStack stack, ItemStack par2ItemStack){ + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) + { return false; } @Override - public int getItemEnchantability(){ + public int getItemEnchantability() + { return 0; } - // Cannot be dropped + //Cannot be dropped @Override - public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player){ + public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player) + { return false; } - - @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item item, CreativeTabs tab, List subItems){ - subItems.add(new ItemStack(this, 1)); - } } diff --git a/src/main/java/electroblob/wizardry/item/ItemSpectralSword.java b/src/main/java/electroblob/wizardry/item/ItemSpectralSword.java index b1db6b6e..7c683a0b 100644 --- a/src/main/java/electroblob/wizardry/item/ItemSpectralSword.java +++ b/src/main/java/electroblob/wizardry/item/ItemSpectralSword.java @@ -1,82 +1,71 @@ package electroblob.wizardry.item; -import java.util.List; - -import net.minecraft.creativetab.CreativeTabs; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.Wizardry; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -public class ItemSpectralSword extends ItemSword implements IConjuredItem { +public class ItemSpectralSword extends ItemSword { public ItemSpectralSword(ToolMaterial material) { super(material); - this.setMaxDamage(getBaseDuration()); + this.setMaxDamage(600); this.setNoRepair(); this.setCreativeTab(null); } @Override - public int getBaseDuration(){ - return 600; - } - - @Override - public int getMaxDamage(ItemStack stack){ - return this.getMaxDamageFromNBT(stack); + public int getMaxDamage(ItemStack stack) + { + return stack.hasTagCompound()? (int)(getMaxDamage()*stack.stackTagCompound.getFloat("durationMultiplier")) : getMaxDamage(); } @Override - // This method allows the code for the item's timer to be greatly simplified by damaging it directly from - // onUpdate() and removing the workaround that involved WizardData and all sorts of crazy stuff. - public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged){ - - if(oldStack != null || newStack != null){ - // We only care about the situation where we specifically want the animation NOT to play. - if(oldStack.getItem() == newStack.getItem() && !slotChanged) return false; + public void onUpdate(ItemStack itemstack, World par2World, Entity entity, int par4, boolean par5) { + // Allows the 'cheaty' damage bar rendering code to start working. + if(itemstack.getItemDamage() == 0){ + itemstack.setItemDamage(1); + } + if(entity instanceof EntityPlayer){ + ExtendedPlayer properties = ExtendedPlayer.get((EntityPlayer)entity); + properties.conjuredSwordDuration++; + if(properties.conjuredSwordDuration > this.getMaxDamage(itemstack)){ + ((EntityPlayer)entity).inventory.consumeInventoryItem(itemstack.getItem()); + properties.conjuredSwordDuration = 0; + } } - - return super.shouldCauseReequipAnimation(oldStack, newStack, slotChanged); } @Override - public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean selected){ - int damage = stack.getItemDamage(); - if(damage > stack.getMaxDamage()) entity.replaceItemInInventory(slot, null); - stack.setItemDamage(damage + 1); - } + public int getDisplayDamage(ItemStack stack){ + return Wizardry.proxy.getConjuredItemDisplayDamage(stack); + } @Override - @SideOnly(Side.CLIENT) - public boolean hasEffect(ItemStack stack){ + public boolean hasEffect(ItemStack par1ItemStack, int pass){ return true; } @Override - public boolean getIsRepairable(ItemStack stack, ItemStack par2ItemStack){ + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) + { return false; } @Override - public int getItemEnchantability(){ + public int getItemEnchantability() + { return 0; } // Cannot be dropped @Override - public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player){ + public boolean onDroppedByPlayer(ItemStack item, EntityPlayer player) + { return false; } - - @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item item, CreativeTabs tab, List subItems){ - subItems.add(new ItemStack(this, 1)); - } } diff --git a/src/main/java/electroblob/wizardry/item/ItemSpellBook.java b/src/main/java/electroblob/wizardry/item/ItemSpellBook.java index 742c660a..b51ad7c8 100644 --- a/src/main/java/electroblob/wizardry/item/ItemSpellBook.java +++ b/src/main/java/electroblob/wizardry/item/ItemSpellBook.java @@ -2,35 +2,38 @@ package electroblob.wizardry.item; import java.util.List; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.SpellGlyphData; -import electroblob.wizardry.WizardData; import electroblob.wizardry.Wizardry; import electroblob.wizardry.WizardryGuiHandler; -import electroblob.wizardry.registry.WizardryTabs; +import electroblob.wizardry.WizardryRegistry; +import electroblob.wizardry.client.GuiSpellBook; import electroblob.wizardry.spell.Spell; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.ActionResult; -import net.minecraft.util.EnumActionResult; -import net.minecraft.util.EnumHand; +import net.minecraft.util.EnumChatFormatting; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.oredict.OreDictionary; -public class ItemSpellBook extends Item { +public class ItemSpellBook extends Item{ public ItemSpellBook() { super(); this.setHasSubtypes(true); this.setMaxStackSize(1); - this.setCreativeTab(WizardryTabs.SPELLS); + this.setCreativeTab(Wizardry.tabSpells); + this.setTextureName("wizardry:spell_book"); + this.setUnlocalizedName("spellBook"); } @Override - public void getSubItems(Item item, CreativeTabs tab, List list){ + public void getSubItems(Item item, CreativeTabs tab, List list){ // In this particular case, getTotalSpellCount() is a more efficient way of doing this since the spell instance // is not required, only the id. for(int i = 0; i < Spell.getTotalSpellCount(); i++){ @@ -40,42 +43,44 @@ public class ItemSpellBook extends Item { } } - @Override - public ActionResult onItemRightClick(ItemStack stack, World world, EntityPlayer player, EnumHand hand){ - player.openGui(Wizardry.instance, WizardryGuiHandler.SPELL_BOOK, world, 0, 0, 0); - return ActionResult.newResult(EnumActionResult.SUCCESS, stack); + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer){ + par3EntityPlayer.openGui(Wizardry.instance, WizardryGuiHandler.SPELL_BOOK, par2World, 0, 0, 0); + return par1ItemStack; } - + /* @Override - @SideOnly(Side.CLIENT) - public void addInformation(ItemStack itemstack, EntityPlayer player, List tooltip, boolean advanced){ + public String getUnlocalizedName(ItemStack stack) { + return EnumSpell.getSpellFromId(stack.getItemDamage()).name; + } + */ + public void addInformation(ItemStack itemstack, EntityPlayer player, List text, boolean par4){ // Tooltip is left blank for wizards buying generic spell books. if(itemstack.getItemDamage() != OreDictionary.WILDCARD_VALUE){ Spell spell = Spell.get(itemstack.getItemDamage()); boolean discovered = true; - if(Wizardry.settings.discoveryMode && !player.capabilities.isCreativeMode && WizardData.get(player) != null - && !WizardData.get(player).hasSpellBeenDiscovered(spell)){ + if(Wizardry.discoveryMode && !player.capabilities.isCreativeMode && ExtendedPlayer.get(player) != null + && !ExtendedPlayer.get(player).hasSpellBeenDiscovered(spell)){ discovered = false; } // Element colour is not given for undiscovered spells - tooltip.add(discovered ? "\u00A77" + spell.getDisplayNameWithFormatting() : "#\u00A79" + SpellGlyphData.getGlyphName(spell, player.worldObj)); - tooltip.add(spell.tier.getDisplayNameWithFormatting()); + text.add(discovered ? "\u00A77" + spell.getDisplayNameWithFormatting() : "#\u00A79" + SpellGlyphData.getGlyphName(spell, player.worldObj)); + text.add(spell.tier.getDisplayNameWithFormatting()); } /* Removed to streamline the tooltip a bit. Information is now within the book. if(spell.isContinuous){ - tooltip.add("\u00A79Mana Cost: " + spell.cost + " per second"); + par3List.add("\u00A79Mana Cost: " + spell.cost + " per second"); }else{ - tooltip.add("\u00A79Mana Cost: " + spell.cost); + par3List.add("\u00A79Mana Cost: " + spell.cost); } */ } @Override @SideOnly(Side.CLIENT) - public net.minecraft.client.gui.FontRenderer getFontRenderer(ItemStack stack){ + public FontRenderer getFontRenderer(ItemStack stack){ return Wizardry.proxy.getFontRenderer(stack); } diff --git a/src/main/java/electroblob/wizardry/item/ItemWand.java b/src/main/java/electroblob/wizardry/item/ItemWand.java index 6f1f99b5..2433051b 100644 --- a/src/main/java/electroblob/wizardry/item/ItemWand.java +++ b/src/main/java/electroblob/wizardry/item/ItemWand.java @@ -1,45 +1,33 @@ package electroblob.wizardry.item; +import java.lang.ref.WeakReference; import java.util.List; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.SpellGlyphData; -import electroblob.wizardry.WizardData; +import electroblob.wizardry.WandHelper; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Constants; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.entity.living.ISummonedCreature; -import electroblob.wizardry.event.SpellCastEvent; -import electroblob.wizardry.event.SpellCastEvent.Source; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.entity.living.EntitySummonedCreature; import electroblob.wizardry.packet.PacketCastSpell; import electroblob.wizardry.packet.WizardryPacketHandler; -import electroblob.wizardry.registry.WizardryAchievements; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardryTabs; import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WandHelper; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.EnumAction; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.ActionResult; -import net.minecraft.util.EnumActionResult; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; /** This class is (literally) where the magic happens! All wand types are single instances of this class. There's a lot * of quite hard-to-read code in here, but unfortunately there's not much I can do about that. For this reason, I have @@ -55,48 +43,42 @@ import net.minecraftforge.fml.relauncher.SideOnly; * @since Wizardry 1.0 */ public class ItemWand extends Item { - public Tier tier; - public Element element; + public EnumTier tier; + public EnumElement element; - public ItemWand(Tier tier, Element element) { + public ItemWand(EnumTier enumtier, EnumElement enumelement) { super(); setMaxStackSize(1); - if(element == null || tier == Tier.BASIC){ - setCreativeTab(WizardryTabs.WIZARDRY); + if(enumelement == null || enumtier == EnumTier.BASIC){ + setCreativeTab(Wizardry.tabWizardry); } - this.tier = tier; - this.element = element; - this.setMaxDamage(this.tier.maxCharge); + this.tier = enumtier; + this.element = enumelement; + this.setMaxDamage(tier.maxCharge); } @Override - @SideOnly(Side.CLIENT) public boolean isFull3D(){ return true; } - @Override - @SideOnly(Side.CLIENT) - public net.minecraft.client.gui.FontRenderer getFontRenderer(ItemStack stack){ - return Wizardry.proxy.getFontRenderer(stack); - } - - @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item parItem, CreativeTabs parTab, List parListSubItems){ - parListSubItems.add(new ItemStack(this, 1)); - } - // Max damage is modifiable with upgrades. @Override public int getMaxDamage(ItemStack itemstack){ // + 0.5f corrects small float errors rounding down - return (int)(super.getMaxDamage(itemstack)*(1.0f + Constants.STORAGE_INCREASE_PER_LEVEL * WandHelper.getUpgradeLevel(itemstack, WizardryItems.storage_upgrade)) + 0.5f); + return (int)(getMaxDamage()*(1.0f + Wizardry.STORAGE_INCREASE_PER_LEVEL * WandHelper.getUpgradeLevel(itemstack, Wizardry.storageUpgrade)) + 0.5f); } @Override - public void onCreated(ItemStack stack, World par2World, EntityPlayer par3EntityPlayer){ - par3EntityPlayer.addStat(WizardryAchievements.arcane_initiate); + public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer){ + /* Removed because of mana flasks, which would cause a new book to be given each time a mana flask + * is crafted with the wand. Handbook is now given on acquiring a crystal. + ExtendedPlayer properties = ExtendedPlayer.get(par3EntityPlayer); + if(properties != null && !properties.handbookGiven){ + par3EntityPlayer.inventory.addItemStackToInventory(new ItemStack(Wizardry.wizardHandbook)); + properties.handbookGiven = true; + }*/ + par3EntityPlayer.triggerAchievement(Wizardry.arcaneInitiate); } @Override @@ -105,131 +87,136 @@ public class ItemWand extends Item { WandHelper.decrementCooldowns(itemstack); // Decrements wand damage (increases mana) every 1.5 seconds if it has a condenser upgrade - if(!world.isRemote && itemstack.isItemDamaged() && world.getWorldTime() % Constants.CONDENSER_TICK_INTERVAL == 0){ + if(!world.isRemote && itemstack.isItemDamaged() && world.getWorldTime() % Wizardry.CONDENSER_TICK_INTERVAL == 0){ // If the upgrade level is 0, this does nothing anyway. - itemstack.setItemDamage(itemstack.getItemDamage() - WandHelper.getUpgradeLevel(itemstack, WizardryItems.condenser_upgrade)); + itemstack.setItemDamage(itemstack.getItemDamage() - WandHelper.getUpgradeLevel(itemstack, Wizardry.condenserUpgrade)); } - if(entity instanceof EntityPlayer && this.element != null && this.element != Element.MAGIC){ + if(entity instanceof EntityPlayer && this.element != null && this.element != EnumElement.MAGIC){ // As it stands, this will trigger every tick. Not ideal, but I can't find a way to detect if a player // has a certain achievement. // EDIT: There is a way to check, using StatFileWriter#hasAchievementUnlocked, but this ends up calling the same - // thing as addStat anyway, meaning there's no point and it's probably not much of a problem anyway. - ((EntityPlayer)entity).addStat(WizardryAchievements.elemental); + // thing as triggerAchievement anyway, meaning there's no point and it's probably not much of a problem anyway. + ((EntityPlayer)entity).triggerAchievement(Wizardry.elemental); } } - @Override - public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged){ - - // This method does some VERY strange things! Despite its name, it also seems to affect the updating of NBT... - - if(oldStack != null || newStack != null){ - // We only care about the situation where we specifically want the animation NOT to play. - if(oldStack.getItem() == newStack.getItem() && !slotChanged - && oldStack.getItem() instanceof ItemWand && newStack.getItem() instanceof ItemWand - && WandHelper.getCurrentSpell(oldStack) == WandHelper.getCurrentSpell(newStack)) return false; - } - - return super.shouldCauseReequipAnimation(oldStack, newStack, slotChanged); - } - @Override public EnumAction getItemUseAction(ItemStack itemstack){ return WandHelper.getCurrentSpell(itemstack).action; } @Override - public int getMaxItemUseDuration(ItemStack stack){ + public int getMaxItemUseDuration(ItemStack par1ItemStack){ return 72000; } - @SideOnly(Side.CLIENT) @Override - public void addInformation(ItemStack itemstack, EntityPlayer player, List text, boolean advanced){ + public void addInformation(ItemStack itemstack, EntityPlayer player, List text, boolean par4){ // +0.5f is necessary due to the error in the way floats are calculated. - if(element != null) text.add("\u00A78" + net.minecraft.client.resources.I18n.format("item.wizardry:wand.buff", (int)((tier.level+1)*Constants.DAMAGE_INCREASE_PER_TIER*100 + 0.5f) + "%", element.getDisplayName())); + if(element != null) text.add("\u00A78" + StatCollector.translateToLocalFormatted("item.wand.buff", (int)((tier.level+1)*Wizardry.DAMAGE_INCREASE_PER_TIER*100 + 0.5f) + "%", element.getDisplayName())); Spell spell = WandHelper.getCurrentSpell(itemstack); boolean discovered = true; - if(Wizardry.settings.discoveryMode && !player.capabilities.isCreativeMode && WizardData.get(player) != null - && !WizardData.get(player).hasSpellBeenDiscovered(spell)){ + if(Wizardry.discoveryMode && !player.capabilities.isCreativeMode && ExtendedPlayer.get(player) != null + && !ExtendedPlayer.get(player).hasSpellBeenDiscovered(spell)){ discovered = false; } - text.add("\u00A77" + net.minecraft.client.resources.I18n.format("item.wizardry:wand.spell", discovered ? "\u00A77" + spell.getDisplayNameWithFormatting() : "#\u00A79" + SpellGlyphData.getGlyphName(spell, player.worldObj))); + text.add("\u00A77" + StatCollector.translateToLocalFormatted("item.wand.spell", discovered ? "\u00A77" + spell.getDisplayNameWithFormatting() : "#\u00A79" + SpellGlyphData.getGlyphName(spell, player.worldObj))); - text.add("\u00A79" + net.minecraft.client.resources.I18n.format("item.wizardry:wand.mana", (this.getMaxDamage(itemstack) - this.getDamage(itemstack)), this.getMaxDamage(itemstack))); + text.add("\u00A79" + StatCollector.translateToLocalFormatted("item.wand.mana", (this.getMaxDamage(itemstack) - this.getDamage(itemstack)), this.getMaxDamage(itemstack))); } @Override - public String getItemStackDisplayName(ItemStack stack){ - return (this.element == null ? "" : this.element.getFormattingCode()) + super.getItemStackDisplayName(stack); + public String getItemStackDisplayName(ItemStack p_77653_1_){ + + return ((this.element == null ? "" : this.element.colour) + StatCollector.translateToLocal(this.getUnlocalizedNameInefficiently(p_77653_1_) + ".name")).trim(); } - + // Continuous spells use the onUsingItemTick method instead of this one. /* An important thing to note about this method: it is only called on the server and the client of the player - * holding the item (I call this client-inconsistency). This means if you spawn particles here they will not show up - * on other players' screens. Instead, this must be done via packets. */ + * holding the item. This means if you spawn particles here they will not show up on other players' screens. + * Instead, this must be done via packets. */ @Override - public ActionResult onItemRightClick(ItemStack stack, World world, EntityPlayer player, EnumHand hand){ + public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player){ + + if(this.selectMinionTarget(player, world)) return stack; + + if(player.isPotionActive(Wizardry.arcaneJammer)) return stack; - // Alternate right-click function; overrides spell casting. - if(this.selectMinionTarget(player, world)) return new ActionResult(EnumActionResult.SUCCESS, stack); - Spell spell = WandHelper.getCurrentSpell(stack); - SpellModifiers modifiers = this.calculateModifiers(stack, spell); - - // If anything stops the spell working at this point, nothing else happens. - if(MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Pre(player, spell, modifiers, Source.WAND))){ - return new ActionResult(EnumActionResult.FAIL, stack); + + // If a spell is disabled in the config, it will not work. + if(!spell.isEnabled()){ + if(!world.isRemote) player.addChatMessage(new ChatComponentTranslation("spell.disabled", spell.getDisplayNameWithFormatting())); + return stack; } - // This is here to start the inUse thing, otherwise the onUsingTick method will not fire. - if(spell.isContinuous && !player.isHandActive()){ - player.setActiveHand(hand); - // Probably ought to be here. (Does it succeed though?) - return new ActionResult(EnumActionResult.SUCCESS, stack); + // This is here to start the inUse thing, otherwise the onItemUsingTick method will not fire. + // If the castSpell method then returns false nothing will happen (continuous spells have no EnumAction + // either so setting the item in use has no direct visible effect). + // Edit: Strictly speaking this is not true but the spells that do have an action (shield, shadow ward and levitation) + // will never return false. + if(spell.isContinuous && !player.isUsingItem()){ + player.setItemInUse(stack, this.getMaxItemUseDuration(stack)); } // Conditions for the spell to be attempted. The tier check is a failsafe; it should never be false unless the // NBT is modified directly. if(!spell.isContinuous && spell.tier.level <= this.tier.level - // Checks that the wand has enough mana to cast the spell && spell.cost <= (stack.getMaxDamage() - stack.getItemDamage()) - // Checks that the spell is not in cooldown or that the player is in creative mode && (WandHelper.getCurrentCooldown(stack) == 0 || player.capabilities.isCreativeMode)){ + // = Spell modifiers = + float rangeMultiplier = 1.0f + WandHelper.getUpgradeLevel(stack, Wizardry.rangeUpgrade)*Wizardry.RANGE_INCREASE_PER_LEVEL; + float durationMultiplier = 1.0f + WandHelper.getUpgradeLevel(stack, Wizardry.durationUpgrade)*Wizardry.DURATION_INCREASE_PER_LEVEL; + float blastMultiplier = 1.0f + WandHelper.getUpgradeLevel(stack, Wizardry.blastUpgrade)*Wizardry.BLAST_RADIUS_INCREASE_PER_LEVEL; + + // I would have liked to have made potion effects increase in strength according to the damage multiplier, + // but the amplifier level is too discrete to make this work. For example, wither 3 for 10 seconds will kill a + // normal mob on full 20 health, but wither 2 for the same duration only deals about 6 hearts of damage in total. + float damageMultiplier = 1.0f; + + if(this.element == spell.element){ + damageMultiplier = 1.0f + (this.tier.level + 1) * Wizardry.DAMAGE_INCREASE_PER_TIER; + } + // If the spell does not require a packet, the code is run in the old client-inconsistent way, since this // means that swingItem() doesn't need packets in order to work, improving performance. if(!world.isRemote){ - if(spell.cast(world, player, hand, 0, modifiers)){ - - MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(player, spell, modifiers, Source.WAND)); + if(spell.cast(world, player, 0, damageMultiplier, rangeMultiplier, durationMultiplier, blastMultiplier)){ // = Packets = if(spell.doesSpellRequirePacket()){ // Sends a packet to all players in dimension to tell them to spawn particles. // Only sent if the spell succeeded, because if the spell failed, you wouldn't // need to spawn any particles! - IMessage msg = new PacketCastSpell.Message(player.getEntityId(), hand, spell.id(), modifiers); - WizardryPacketHandler.net.sendToDimension(msg, world.provider.getDimension()); + IMessage msg = new PacketCastSpell.Message(player.getEntityId(), 0, spell.id(), damageMultiplier, rangeMultiplier, blastMultiplier); + WizardryPacketHandler.net.sendToDimension(msg, world.provider.dimensionId); } - player.setActiveHand(hand); + player.setItemInUse(stack, this.getMaxItemUseDuration(stack)); + + // = Discovery = + if(!player.capabilities.isCreativeMode && !ExtendedPlayer.get(player).hasSpellBeenDiscovered(spell) && Wizardry.discoveryMode){ + player.worldObj.playSoundAtEntity(player, "random.levelup", 1.25f, 1); + if(!player.worldObj.isRemote) player.addChatMessage(new ChatComponentTranslation("spell.discover", spell.getDisplayNameWithFormatting())); + } + ExtendedPlayer.get(player).discoverSpell(spell); // = Cooldown = // Spells only have a cooldown in survival if(!player.capabilities.isCreativeMode){ - float cooldownMultiplier = 1.0f - WandHelper.getUpgradeLevel(stack, WizardryItems.cooldown_upgrade)*Constants.COOLDOWN_REDUCTION_PER_LEVEL; + float cooldownMultiplier = 1.0f - WandHelper.getUpgradeLevel(stack, Wizardry.cooldownUpgrade)*Wizardry.COOLDOWN_REDUCTION_PER_LEVEL; - if(player.isPotionActive(WizardryPotions.font_of_mana)){ + if(player.isPotionActive(Wizardry.fontOfMana)){ // Dividing by this rather than setting it takes upgrades and font of mana into account simultaneously - cooldownMultiplier /= 2 + player.getActivePotionEffect(WizardryPotions.font_of_mana).getAmplifier(); + cooldownMultiplier /= 2 + player.getActivePotionEffect(Wizardry.fontOfMana).getAmplifier(); } WandHelper.setCurrentCooldown(stack, (int)(spell.cooldown * cooldownMultiplier)); @@ -237,162 +224,184 @@ public class ItemWand extends Item { // = Mana cost = // The spell costs 20% less for every armour piece of the matching element. - int armourPieces = getMatchingArmourCount(player, spell); + int armourPieces = 0; - stack.damageItem((int)(spell.cost * (1.0f - armourPieces*Constants.COST_REDUCTION_PER_ARMOUR)), player); + for(int i=0; i<4; i++){ + if(player.getCurrentArmor(i) != null && player.getCurrentArmor(i).getItem() instanceof ItemWizardArmour + && ((ItemWizardArmour)player.getCurrentArmor(i).getItem()).element == spell.element) armourPieces++; + } + + stack.damageItem((int)(spell.cost * (1.0f - armourPieces*Wizardry.COST_REDUCTION_PER_ARMOUR)), player); - return new ActionResult(EnumActionResult.SUCCESS, stack); } - + + // Client-inconsistent spells only. }else if(!spell.doesSpellRequirePacket()){ - // Client-inconsistent spell casting. This code only runs client-side. - if(spell.cast(world, player, hand, 0, modifiers)){ - // This is all that needs to happen, because everything above works fine on just the server side. - MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(player, spell, modifiers, Source.WAND)); - return new ActionResult(EnumActionResult.SUCCESS, stack); + // This is all that needs to happen, because everything up there works fine on just the server side. + if(spell.cast(world, player, 0, damageMultiplier, rangeMultiplier, durationMultiplier, blastMultiplier)){ + // Added in version 1.1.3 to fix the client-side spell discovery not updating for spells with the + // packet optimisation. + if(ExtendedPlayer.get(player) != null){ + ExtendedPlayer.get(player).discoverSpell(spell); + } } } } - - return new ActionResult(EnumActionResult.FAIL, stack); + return stack; } - // For continuous spells. The count argument actually decrements by 1 each tick. + + // For continuous spells and (deprecated) spells with a charge up time. + // The count argument actually decrements by 1 each tick. @Override - public void onUsingTick(ItemStack stack, EntityLivingBase user, int count){ + public void onUsingTick(ItemStack stack, EntityPlayer player, int count){ - if(user instanceof EntityPlayer){ + Spell spell = WandHelper.getCurrentSpell(stack); - EntityPlayer player = (EntityPlayer)user; - - Spell spell = WandHelper.getCurrentSpell(stack); - SpellModifiers modifiers = this.calculateModifiers(stack, spell); - int castingTick = stack.getMaxItemUseDuration() - count; - - if(MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Tick(player, spell, modifiers, Source.WAND, castingTick))) return; + ExtendedPlayer properties = ExtendedPlayer.get(player); - // Continuous spells (these must check if they can be cast each tick since the mana changes) - if(spell.isContinuous && spell.tier.level <= this.tier.level - && spell.cost/5 <= (stack.getMaxDamage() - stack.getItemDamage())){ + // Continuous spells (these must check if they can be cast each tick since the mana changes) + if(spell.isContinuous && spell.tier.level <= this.tier.level + && spell.cost/5 <= (stack.getMaxDamage() - stack.getItemDamage() - properties.damageToApply)){ - if(spell.cast(player.worldObj, player, player.getActiveHand(), castingTick, modifiers)){ + // = Spell modifiers = + float rangeMultiplier = 1.0f + WandHelper.getUpgradeLevel(stack, Wizardry.rangeUpgrade)*Wizardry.RANGE_INCREASE_PER_LEVEL; + float durationMultiplier = 1.0f + WandHelper.getUpgradeLevel(stack, Wizardry.durationUpgrade)*Wizardry.DURATION_INCREASE_PER_LEVEL; + float blastMultiplier = 1.0f + WandHelper.getUpgradeLevel(stack, Wizardry.blastUpgrade)*Wizardry.BLAST_RADIUS_INCREASE_PER_LEVEL; - if(castingTick == 0) MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(player, spell, modifiers, Source.WAND)); + // I would have liked to have made potion effects increase in strength according to the damage multiplier, + // but the amplifier level is too discrete to make this work. For example, wither 3 for 10 seconds will kill a + // normal mob on full 20 health, but wither 2 for the same duration only deals about 6 hearts of damage in total. + float damageMultiplier = 1.0f; - // = Mana cost = - // Divides the mana cost over a second appropriately; since damage is an integer it cannot - // just be divided by 20. - // Now does five times per second regardless of the spell cost, but each time it does 1/5 of the - // cost per second. - int tickNumber = (count % 20) + 1; - // Tests if the tick counter is a multiple of 4 plus 1, i.e. is true when tickNumber = 1, 5, 9, 13 or 17. - // Made a slight adjustment since the counter starts on 1 and not 4. - if(tickNumber % 4 == 1){ + if(this.element == spell.element){ + damageMultiplier = 1.0f + (this.tier.level + 1) * Wizardry.DAMAGE_INCREASE_PER_TIER; + } - int armourPieces = getMatchingArmourCount(player, spell); + if(spell.cast(player.worldObj, player, stack.getMaxItemUseDuration() - count, damageMultiplier, rangeMultiplier, durationMultiplier, blastMultiplier)){ - switch(armourPieces){ + // = Discovery = + if(!player.capabilities.isCreativeMode && !properties.hasSpellBeenDiscovered(spell) && Wizardry.discoveryMode){ + player.worldObj.playSoundAtEntity(player, "random.levelup", 1.25f, 1); + if(!player.worldObj.isRemote) player.addChatMessage(new ChatComponentTranslation("spell.discover", spell.getDisplayNameWithFormatting())); + } + properties.discoverSpell(spell); - case 0: stack.damageItem(spell.cost/5, player); - break; + // = Mana cost = + // Divides the mana cost over a second appropriately; since damage is an integer it cannot + // just be divided by 20. + // Now does five times per second regardless of the spell cost, but each time it does 1/5 of the + // cost per second. + // Removed the tick counter because it is cumbersome and stupid, when I can just as easily use the + // count argument given right here. + //properties.incrementTickNumber(); + int tickNumber = (count % 20) + 1; + // Tests if the tick counter is a multiple of 4 plus 1, i.e. is true when tickNumber = 1, 5, 9, 13 or 17. + // Made a slight adjustment since the counter starts on 1 and not 4. + if(tickNumber % 4 == 1){ - case 1: if(tickNumber != 17) stack.damageItem(spell.cost/5, player); - break; + int armourPieces = 0; - case 2: if(tickNumber != 9 && tickNumber != 17) stack.damageItem(spell.cost/5, player); - break; + for(int i=0; i<4; i++){ + if(player.getCurrentArmor(i) != null && player.getCurrentArmor(i).getItem() instanceof ItemWizardArmour + && ((ItemWizardArmour)player.getCurrentArmor(i).getItem()).element == spell.element) armourPieces++; + } - case 3: if(tickNumber != 5 && tickNumber != 13 && tickNumber != 17) stack.damageItem(spell.cost/5, player); - break; + switch(armourPieces){ - case 4: if(tickNumber == 1) stack.damageItem(spell.cost/5, player); - break; + case 0: properties.damageToApply += spell.cost/5; + break; + + case 1: if(tickNumber != 17) properties.damageToApply += spell.cost/5; + break; + + case 2: if(tickNumber != 9 && tickNumber != 17) properties.damageToApply += spell.cost/5; + break; + + case 3: if(tickNumber != 5 && tickNumber != 13 && tickNumber != 17) properties.damageToApply += spell.cost/5; + break; + + case 4: if(tickNumber == 1) properties.damageToApply += spell.cost/5; + break; - } } } } } } + /** + * Called when the player releases the use item button. Args: itemstack, world, entityplayer, itemInUseCount. + * Here it is used to apply damage after using a continuous spell. The damage shows up on the damage bar in real- + * time thanks to the getItemDamageForDisplay function, but is not actually applied until the button is released. + * This is because applying damage causes the wand to 're-equip', interrupting the spell. + * (Note that if the wand has no damage then minecraft doesn't try to render the bar, so the getItemDamageForDisplay + * function is never called, meaning if you use a continuous spell on an undamaged wand the damage doesn't appear + * until you release the mouse. A minor bug, but there's nothing I can do about it.) + */ @Override - public boolean itemInteractionForEntity(ItemStack stack, EntityPlayer player, EntityLivingBase entity, EnumHand hand){ + public void onPlayerStoppedUsing(ItemStack itemstack, World world, EntityPlayer entityplayer, int par4) { + ExtendedPlayer properties = ExtendedPlayer.get(entityplayer); + // This if statement should always be true, but is here just in case to stop the wand breaking. + if(properties.damageToApply <= itemstack.getMaxDamage() - itemstack.getItemDamage()){ + itemstack.damageItem(properties.damageToApply, entityplayer); + }else{ + itemstack.setItemDamage(itemstack.getMaxDamage()); + } + properties.damageToApply = 0; + } - if(player.isSneaking() && entity instanceof EntityPlayer && WizardData.get(player) != null){ + @Override + public boolean itemInteractionForEntity(ItemStack stack, EntityPlayer player, + EntityLivingBase entity){ + + if(player.isSneaking() && entity instanceof EntityPlayer && ExtendedPlayer.get(player) != null){ // This is one of those "the method doing the work looks as if it's just returning a value" situations. // ... I know, right?! I feel very programmer-y. But it's not too confusing here, and it looks neat. - String string = WizardData.get(player).toggleAlly((EntityPlayer)entity) ? "item.wizardry:wand.addally" : "item.wizardry:wand.removeally"; - if(!player.worldObj.isRemote) player.addChatMessage(new TextComponentTranslation(string, entity.getName())); + String string = ExtendedPlayer.get(player).toggleAlly((EntityPlayer)entity) ? "item.wand.addally" : "item.wand.removeally"; + if(!player.worldObj.isRemote) player.addChatMessage(new ChatComponentTranslation(string, entity.getCommandSenderName())); return true; } return false; } - - /** Returns a SpellModifiers object with the appropriate modifiers applied for the given ItemStack and Spell. */ - protected SpellModifiers calculateModifiers(ItemStack stack, Spell spell){ - - SpellModifiers modifiers = new SpellModifiers(); - - // Now we only need to add multipliers if they are not 1. - int level = WandHelper.getUpgradeLevel(stack, WizardryItems.range_upgrade); - if(level > 0) modifiers.set(WizardryItems.range_upgrade, 1.0f + level * Constants.RANGE_INCREASE_PER_LEVEL, true); - - level = WandHelper.getUpgradeLevel(stack, WizardryItems.duration_upgrade); - if(level > 0) modifiers.set(WizardryItems.duration_upgrade, 1.0f + level * Constants.DURATION_INCREASE_PER_LEVEL, false); - - level = WandHelper.getUpgradeLevel(stack, WizardryItems.blast_upgrade); - if(level > 0) modifiers.set(WizardryItems.blast_upgrade, 1.0f + level * Constants.BLAST_RADIUS_INCREASE_PER_LEVEL, true); - - // I would have liked to have made potion effects increase in strength according to the damage multiplier, - // but the amplifier level is too discrete to make this work. For example, wither 3 for 10 seconds will kill a - // normal mob on full 20 health, but wither 2 for the same duration only deals about 6 hearts of damage in total. - if(this.element == spell.element){ - modifiers.set(SpellModifiers.DAMAGE, 1.0f + (this.tier.level + 1) * Constants.DAMAGE_INCREASE_PER_TIER, true); - } - - return modifiers; - } - - /** Counts the number of armour pieces the given player is wearing that match the given spell's element. */ - private int getMatchingArmourCount(EntityPlayer player, Spell spell){ - - int armourPieces = 0; - - for(EntityEquipmentSlot slot : WizardryUtilities.ARMOUR_SLOTS){ - - ItemStack armour = player.getItemStackFromSlot(slot); - - if(armour != null && armour.getItem() instanceof ItemWizardArmour - && ((ItemWizardArmour)armour.getItem()).element == spell.element) armourPieces++; - } - - return armourPieces; - } - + private boolean selectMinionTarget(EntityPlayer player, World world){ - - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, player, 16); - + + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, player, 16); + if(rayTrace != null && rayTrace.entityHit instanceof EntityLivingBase){ - + EntityLivingBase entity = (EntityLivingBase)rayTrace.entityHit; - + // Sets the selected minion's target to the right-clicked entity - if(player.isSneaking() && WizardData.get(player) != null && WizardData.get(player).selectedMinion != null){ - - ISummonedCreature minion = WizardData.get(player).selectedMinion.get(); - - if(minion instanceof EntityLiving && minion != entity){ - // There is now only the new AI! (which greatly improves things) - ((EntityLiving)minion).setAttackTarget(entity); + if(player.isSneaking() && ExtendedPlayer.get(player) != null && ExtendedPlayer.get(player).selectedMinion != null){ + + EntitySummonedCreature minion = ExtendedPlayer.get(player).selectedMinion.get(); + + if(minion != null && minion != entity){ + // New AI + minion.setAttackTarget(entity); + // Old AI + minion.setTarget(entity); // Deselects the selected minion - WizardData.get(player).selectedMinion = null; + ExtendedPlayer.get(player).selectedMinion = null; return true; } } } - + return false; } + + @Override + public double getDurabilityForDisplay(ItemStack stack){ + return Wizardry.proxy.getWandDisplayDamage(stack); + } + + @Override + @SideOnly(Side.CLIENT) + public FontRenderer getFontRenderer(ItemStack stack){ + return Wizardry.proxy.getFontRenderer(stack); + } } diff --git a/src/main/java/electroblob/wizardry/item/ItemWizardArmour.java b/src/main/java/electroblob/wizardry/item/ItemWizardArmour.java index 97a18fee..1cdec683 100644 --- a/src/main/java/electroblob/wizardry/item/ItemWizardArmour.java +++ b/src/main/java/electroblob/wizardry/item/ItemWizardArmour.java @@ -1,157 +1,152 @@ package electroblob.wizardry.item; import java.util.List; +import java.util.Locale; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import electroblob.wizardry.EnumElement; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Constants; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.registry.WizardryTabs; -import electroblob.wizardry.spell.Petrify; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.client.model.ModelBiped; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.EnumAction; -import net.minecraft.item.Item; import net.minecraft.item.ItemArmor; import net.minecraft.item.ItemStack; +import net.minecraft.potion.Potion; import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumHandSide; +import net.minecraft.util.StatCollector; import net.minecraftforge.common.ISpecialArmor; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; public class ItemWizardArmour extends ItemArmor implements ISpecialArmor { + + /* + * In case I ever wonder what I was doing: what I think went wrong is that during development of wizardry 1.2, + * I did of course go through everything and make it dedicated server-compatible. I also fixed the lag spike bug + * caused by this very class. HOWEVER, I must have done that AFTER making everything dedicated server-compatible, + * and in my ignorance introduced a field which instantiated ModelBiped, which is of course client-only. This is + * now fixed and the fix is rolled back to 1.2.1 (but not 1.2), along with the arguably more important fix in + * EntityWizard. Now, for some reason importing ModelBiped in a common class is fine, as long as you don't + * instantiate it or reflect the class in question. In fact, the Item class does exactly this, and that's forge's + * doing, so it can't possibly break things. + */ - public Element element; + public EnumElement element; - public ItemWizardArmour(ArmorMaterial material, int renderIndex, EntityEquipmentSlot armourType, Element element) { + /** Armour types: 0 = helmet, 1 = chestplate, 2 = leggings, 3 = boots */ + public ItemWizardArmour(ArmorMaterial material, int renderIndex, int armourType, EnumElement element) { super(material, renderIndex, armourType); this.element = element; - this.setCreativeTab(WizardryTabs.WIZARDRY); - } - - @Override - @SideOnly(Side.CLIENT) - public void addInformation(ItemStack stack, EntityPlayer player, List tooltip, boolean advanced){ + this.setCreativeTab(Wizardry.tabWizardry); - if(stack.hasTagCompound() && stack.getTagCompound().getBoolean("legendary")) tooltip.add("\u00A7d" + net.minecraft.client.resources.I18n.format("item.wizardry:wizard_armour.legendary")); - if(element != null) tooltip.add("\u00A78" + net.minecraft.client.resources.I18n.format("item.wizardry:wizard_armour.buff", (int)(Constants.COST_REDUCTION_PER_ARMOUR*100) + "%", element.getDisplayName())); - tooltip.add("\u00A79" + net.minecraft.client.resources.I18n.format("item.wizardry:wizard_armour.mana", (this.getMaxDamage(stack) - this.getDamage(stack)), this.getMaxDamage(stack))); + // Sets item icon texture and unlocalised name according to element and armour type. + switch(armourType){ + case 0: + this.setTextureName(this.element == null ? "wizardry:wizard_hat" : + "wizardry:wizard_hat_" + this.element.unlocalisedName); + this.setUnlocalizedName(this.element == null ? "wizard_hat" : "wizard_hat_" + this.element.unlocalisedName); + break; + case 1: + this.setTextureName(this.element == null ? "wizardry:wizard_robe" : + "wizardry:wizard_robe_" + this.element.unlocalisedName); + this.setUnlocalizedName(this.element == null ? "wizard_robe" : "wizard_robe_" + this.element.unlocalisedName); + break; + case 2: + this.setTextureName(this.element == null ? "wizardry:wizard_leggings" : + "wizardry:wizard_leggings_" + this.element.unlocalisedName); + this.setUnlocalizedName(this.element == null ? "wizard_leggings" : "wizard_leggings_" + this.element.unlocalisedName); + break; + case 3: + this.setTextureName(this.element == null ? "wizardry:wizard_boots" : + "wizardry:wizard_boots_" + this.element.unlocalisedName); + this.setUnlocalizedName(this.element == null ? "wizard_boots" : "wizard_boots_" + this.element.unlocalisedName); + break; + } } @Override - public String getItemStackDisplayName(ItemStack stack){ - return ((this.element == null ? "" : this.element.getFormattingCode()) + super.getItemStackDisplayName(stack)); + public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4){ + + if(par1ItemStack.hasTagCompound() && par1ItemStack.stackTagCompound.getBoolean("legendary")) par3List.add("\u00A7d" + StatCollector.translateToLocal("item.wizardArmour.legendary")); + if(element != null) par3List.add("\u00A78" + StatCollector.translateToLocalFormatted("item.wizardArmour.buff", (int)(Wizardry.COST_REDUCTION_PER_ARMOUR*100) + "%", element.getDisplayName())); + par3List.add("\u00A79" + StatCollector.translateToLocalFormatted("item.wizardArmour.mana", (this.getMaxDamage(par1ItemStack) - this.getDamage(par1ItemStack)), this.getMaxDamage(par1ItemStack))); + } + + @Override + public String getItemStackDisplayName(ItemStack p_77653_1_){ + + return ((this.element == null ? "" : this.element.colour) + StatCollector.translateToLocal(this.getUnlocalizedNameInefficiently(p_77653_1_) + ".name")).trim(); } @Override - @SideOnly(Side.CLIENT) - public boolean hasEffect(ItemStack stack){ - return stack.hasTagCompound() && stack.getTagCompound().getBoolean("legendary"); + public boolean hasEffect(ItemStack stack, int pass){ + return stack.hasTagCompound() && stack.stackTagCompound.getBoolean("legendary"); } @Override @SideOnly(Side.CLIENT) - public net.minecraft.client.model.ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, EntityEquipmentSlot armourSlot, net.minecraft.client.model.ModelBiped _default){ + public ModelBiped getArmorModel(EntityLivingBase entityLiving, ItemStack itemStack, int armourSlot){ - net.minecraft.client.model.ModelBiped model = Wizardry.proxy.getWizardArmourModel(); + ModelBiped model = Wizardry.proxy.getWizardArmourModel(); // Legs use modelBiped - if(armourSlot == EntityEquipmentSlot.LEGS) return null; + if(armourSlot == 2) return null; if(model != null){ - - model.bipedHead.showModel = armourSlot == EntityEquipmentSlot.HEAD; + model.bipedHead.showModel = armourSlot == 0; model.bipedHeadwear.showModel = false; - model.bipedBody.showModel = armourSlot == EntityEquipmentSlot.CHEST || armourSlot == EntityEquipmentSlot.LEGS; - model.bipedRightArm.showModel = armourSlot == EntityEquipmentSlot.CHEST; - model.bipedLeftArm.showModel = armourSlot == EntityEquipmentSlot.CHEST; - model.bipedRightLeg.showModel = armourSlot == EntityEquipmentSlot.LEGS || armourSlot == EntityEquipmentSlot.FEET; - model.bipedLeftLeg.showModel = armourSlot == EntityEquipmentSlot.LEGS || armourSlot == EntityEquipmentSlot.FEET; + model.bipedBody.showModel = armourSlot == 1 || armourSlot == 2; + model.bipedRightArm.showModel = armourSlot == 1; + model.bipedLeftArm.showModel = armourSlot == 1; + model.bipedRightLeg.showModel = armourSlot == 2 || armourSlot == 3; + model.bipedLeftLeg.showModel = armourSlot == 2 || armourSlot == 3; model.isSneak = entityLiving.isSneaking(); model.isRiding = entityLiving.isRiding(); model.isChild = entityLiving.isChild(); + model.heldItemRight = entityLiving.getHeldItem() != null ? 1 : 0; - boolean leftHanded = entityLiving.getPrimaryHand() == EnumHandSide.LEFT; - - ItemStack itemstackR = leftHanded ? entityLiving.getHeldItemOffhand() : entityLiving.getHeldItemMainhand(); - ItemStack itemstackL = leftHanded ? entityLiving.getHeldItemMainhand() : entityLiving.getHeldItemOffhand(); - - if (itemstackR != null) - { - model.rightArmPose = net.minecraft.client.model.ModelBiped.ArmPose.ITEM; - - if (entityLiving.getItemInUseCount() > 0) - { - EnumAction enumaction = itemstackR.getItemUseAction(); - - if (enumaction == EnumAction.BLOCK) - { - model.rightArmPose = net.minecraft.client.model.ModelBiped.ArmPose.BLOCK; - } - else if (enumaction == EnumAction.BOW) - { - model.rightArmPose = net.minecraft.client.model.ModelBiped.ArmPose.BOW_AND_ARROW; - } - } - } - - if (itemstackL != null) - { - model.leftArmPose = net.minecraft.client.model.ModelBiped.ArmPose.ITEM; - - if (entityLiving.getItemInUseCount() > 0) - { - EnumAction enumaction1 = itemstackL.getItemUseAction(); - - if (enumaction1 == EnumAction.BLOCK) - { - model.leftArmPose = net.minecraft.client.model.ModelBiped.ArmPose.BLOCK; - } - else if (enumaction1 == EnumAction.BOW) - { - model.leftArmPose = net.minecraft.client.model.ModelBiped.ArmPose.BOW_AND_ARROW; - } - } - } + if(entityLiving instanceof EntityPlayer){ + if(entityLiving.getHeldItem() != null){ + if(entityLiving.getHeldItem().getItem().getItemUseAction(entityLiving.getHeldItem()) == EnumAction.bow){ + model.aimedBow = ((EntityPlayer)entityLiving).getItemInUseDuration() > 0; + } + if(entityLiving.getHeldItem().getItem().getItemUseAction(entityLiving.getHeldItem()) == EnumAction.block){ + if(((EntityPlayer)entityLiving).getItemInUseDuration() > 0) model.heldItemRight = 3; + } + } + } } return model; } @Override - public String getArmorTexture(ItemStack stack, Entity entity, EntityEquipmentSlot slot, String type) { - + public String getArmorTexture(ItemStack stack, Entity entity, int slot, String type){ + // Returns a completely transparent texture if the player is invisible. This is such an annoyingly easy // fix, considering how long I spent trying to do this before - a bit of lateral thinking was all it took. // Do note however that a texture pack could override this. - if(entity instanceof EntityLivingBase && ((EntityLivingBase)entity).isInvisible() - && !entity.getEntityData().getBoolean(Petrify.NBT_KEY)) return "wizardry:textures/armour/invisible_armour.png"; + if(entity instanceof EntityLivingBase && ((EntityLivingBase)entity).isInvisible()) return "wizardry:textures/armour/invisible_armour.png"; - if(slot == EntityEquipmentSlot.LEGS) return this.element == null ? "wizardry:textures/armour/wizard_armour_legs.png" : - "wizardry:textures/armour/wizard_armour_" + this.element.getUnlocalisedName() + "_legs.png"; + if(slot == 2) return this.element == null ? "wizardry:textures/armour/wizard_armour_legs.png" : + "wizardry:textures/armour/wizard_armour_" + this.element.unlocalisedName + "_legs.png"; return this.element == null ? "wizardry:textures/armour/wizard_armour.png" : - "wizardry:textures/armour/wizard_armour_" + this.element.getUnlocalisedName() + ".png"; - } + "wizardry:textures/armour/wizard_armour_" + this.element.unlocalisedName + ".png"; + } @Override - public boolean getIsRepairable(ItemStack stack, ItemStack par2ItemStack) + public boolean getIsRepairable(ItemStack par1ItemStack, ItemStack par2ItemStack) { return false; } @Override - public ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, double damage, int slotIndex){ - - EntityEquipmentSlot slot = getArmorSlotFromIndex(slotIndex); - + public ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, double damage, int slot){ if (!source.isUnblockable() && armor.getItemDamage() < armor.getMaxDamage()){ - if(armor.hasTagCompound() && armor.getTagCompound().getBoolean("legendary")){ + if(armor.hasTagCompound() && armor.stackTagCompound.getBoolean("legendary")){ // Legendary armour gives full 10 shields, like diamond. return new ArmorProperties(0, ArmorMaterial.DIAMOND.getDamageReductionAmount(slot) / 25D, armor.getMaxDamage() + 1 - armor.getItemDamage()); }else{ @@ -163,12 +158,9 @@ public class ItemWizardArmour extends ItemArmor implements ISpecialArmor { } @Override - public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slotIndex) { - - EntityEquipmentSlot slot = getArmorSlotFromIndex(slotIndex); - + public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slot) { if(armor.getItemDamage() < armor.getMaxDamage()){ - if(armor.hasTagCompound() && armor.getTagCompound().getBoolean("legendary")){ + if(armor.hasTagCompound() && armor.stackTagCompound.getBoolean("legendary")){ // Legendary armour gives full 10 shields, like diamond. return ArmorMaterial.DIAMOND.getDamageReductionAmount(slot); }else{ @@ -191,27 +183,5 @@ public class ItemWizardArmour extends ItemArmor implements ISpecialArmor { } } } - - @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item item, CreativeTabs tab, List subItems){ - subItems.add(new ItemStack(this, 1)); - } - - /** Returns the EntityEquipmentSlot for which index() returns an integer equal to the passed in slotIndex and - * which is an armour slot (not a hand slot). This only exists because the 1.10.2 version of Forge still uses - * an integer slot index in ISpecialArmor instead of an EntityEquipmentSlot. */ - // NOTE: Remove in 1.11.2 - private EntityEquipmentSlot getArmorSlotFromIndex(int slotIndex) { - // Had to pick something to begin with. - EntityEquipmentSlot slot = EntityEquipmentSlot.HEAD; - - for(EntityEquipmentSlot s : WizardryUtilities.ARMOUR_SLOTS){ - if(s.getIndex() == slotIndex){ - slot = s; - } - } - return slot; - } } diff --git a/src/main/java/electroblob/wizardry/item/ItemWizardHandbook.java b/src/main/java/electroblob/wizardry/item/ItemWizardHandbook.java index 3b7060db..01be5c44 100644 --- a/src/main/java/electroblob/wizardry/item/ItemWizardHandbook.java +++ b/src/main/java/electroblob/wizardry/item/ItemWizardHandbook.java @@ -4,43 +4,33 @@ import java.util.List; import electroblob.wizardry.Wizardry; import electroblob.wizardry.WizardryGuiHandler; -import electroblob.wizardry.registry.WizardryTabs; +import electroblob.wizardry.client.GuiWizardHandbook; +import electroblob.wizardry.spell.Spell; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.util.ActionResult; -import net.minecraft.util.EnumActionResult; -import net.minecraft.util.EnumHand; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -public class ItemWizardHandbook extends Item { - - // Yep, I hardcoded my own name into the mod. Don't want people changing it now, do I? - private static final String AUTHOR = "Electroblob"; +public class ItemWizardHandbook extends Item{ public ItemWizardHandbook() { super(); this.setMaxStackSize(1); - this.setCreativeTab(WizardryTabs.WIZARDRY); - } - - @Override - public void addInformation(ItemStack stack, EntityPlayer player, List tooltip, boolean advanced){ - tooltip.add("\u00A77" + net.minecraft.client.resources.I18n.format("item.wizardry:wizard_handbook.desc", AUTHOR)); - } - - @Override - public ActionResult onItemRightClick(ItemStack stack, World world, EntityPlayer player, EnumHand hand){ - player.openGui(Wizardry.instance, WizardryGuiHandler.WIZARD_HANDBOOK, world, 0, 0, 0); - return ActionResult.newResult(EnumActionResult.SUCCESS, stack); + this.setCreativeTab(Wizardry.tabWizardry); + this.setTextureName("wizardry:wizard_handbook"); + this.setUnlocalizedName("wizardHandbook"); } - @Override - @SideOnly(Side.CLIENT) - public void getSubItems(Item item, CreativeTabs tab, List items){ - items.add(new ItemStack(this, 1)); - } + public void addInformation(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, List par3List, boolean par4){ + Spell spell = Spell.get(par1ItemStack.getItemDamage()); + // Yep, I hardcoded my own name into the mod. Don't want people changing it now, do I? + par3List.add("\u00A77" + StatCollector.translateToLocalFormatted("item.wizardHandbook.desc", "Electroblob")); + } + + public ItemStack onItemRightClick(ItemStack par1ItemStack, World par2World, EntityPlayer par3EntityPlayer){ + par3EntityPlayer.openGui(Wizardry.instance, WizardryGuiHandler.WIZARD_HANDBOOK, par2World, 0, 0, 0); + return par1ItemStack; + } } diff --git a/src/main/java/electroblob/wizardry/loot/RandomSpell.java b/src/main/java/electroblob/wizardry/loot/RandomSpell.java deleted file mode 100644 index c068ccb7..00000000 --- a/src/main/java/electroblob/wizardry/loot/RandomSpell.java +++ /dev/null @@ -1,267 +0,0 @@ -package electroblob.wizardry.loot; - -import java.util.ArrayList; -import java.util.List; -import java.util.Random; - -import org.apache.commons.lang3.ArrayUtils; - -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSyntaxException; - -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.item.ItemScroll; -import electroblob.wizardry.item.ItemSpellBook; -import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.item.ItemStack; -import net.minecraft.util.JsonUtils; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.storage.loot.LootContext; -import net.minecraft.world.storage.loot.conditions.LootCondition; -import net.minecraft.world.storage.loot.functions.LootFunction; - -/** Loot function that allows spell books and scrolls to select a random spell based on the standard weighting. - * Automatically discounts continuous spells when the item in question is a scroll. Can be used as-is with no - * parameters, but several optional parameters are available for those wishing to customise further: - *

    - * - spells: A list of spells to choose from. Defaults to all enabled spells.
    - * - ignore_weighting: true to ignore the standard weighting and just pick a completely random spell. Defaults to - * false.
    - * - tiers: A list of tiers to choose from. Defaults to all tiers.
    - * - elements: A list of elements to choose from. Defaults to all elements. - *

    - * This class is effectively a loot table-friendly replacement for the standard weighting method in WizardryUtilities - * which was the basis of all the old loot systems (not counting wizard trades, which were - and still are - completely - * separate). - *

    - * Since spells are stored as metadata, this could be done by having an entry for each tier and letting it pick a - * random spell from that tier by setting the metadata to a random value in the range of values that correspond to that - * tier. However, this creates a two-fold problem: firstly, not all spells are in tier order, and secondly, if spells are - * added via addon mods the entries would have to be updated manually with the new numbers. - *

    - * (This reasoning is similar to that for the enchant_randomly function in vanilla Minecraft, since you can specify NBT - * data in loot tables, but using NBT in this way would be incredibly verbose and inflexible, hence the loot function.) - * @see WizardryUtilities#getStandardWeightedRandomSpellId(Random, boolean) - * @author Electroblob - * @since Wizardry 1.2 - */ -/* - * You could even use the yet more long-winded method of adding each spell as an individual entry, which would be - * stupidly long but would allow precise control over each individual spell... I'll leave that for pack makers to do - * if they have the patience! - * */ -public class RandomSpell extends LootFunction { - - private final List spells; - private final boolean ignoreWeighting; - private final List tiers; - private final List elements; - - protected RandomSpell(LootCondition[] conditions, List spells, boolean ignoreWeighting, List tiers, List elements){ - super(conditions); - this.spells = spells; - this.ignoreWeighting = ignoreWeighting; - this.tiers = tiers; - this.elements = elements; - } - - @Override - public ItemStack apply(ItemStack stack, Random random, LootContext context){ - - if(!(stack.getItem() instanceof ItemSpellBook) && !(stack.getItem() instanceof ItemScroll)) - Wizardry.logger.warn("Applying the random_spell loot function to an item that isn't a spell book or scroll."); - - Tier tier; - Element element; - - if(ignoreWeighting){ - if(tiers == null || tiers.isEmpty()){ - tier = Tier.values()[random.nextInt(Tier.values().length)]; - }else{ - tier = tiers.get(random.nextInt(tiers.size())); - } - }else{ - if(tiers == null || tiers.isEmpty()){ - tier = Tier.getWeightedRandomTier(random); - }else{ - tier = Tier.getWeightedRandomTier(random, tiers.toArray(new Tier[0])); - } - } - - // Elements aren't weighted - if(elements == null || elements.isEmpty()){ - // Element can only be MAGIC if tier is BASIC - if(tier == Tier.BASIC){ - element = Element.values()[random.nextInt(Element.values().length)]; - }else{ - Element[] elements = ArrayUtils.removeElement(Element.values(), Element.MAGIC); - element = elements[random.nextInt(elements.length)]; - } - }else{ - // In theory, swapping this line to the commented one should make absolutely no difference. - element = elements.get(random.nextInt(tiers.size())); - //element = null; - } - - // Here's a thought: does randomly selecting the element beforehand (as opposed to leaving it null and letting - // the spell randomiser use any element) change the overall outcome at all? - List spellsList = Spell.getSpells(new Spell.TierElementFilter(tier, element)); - if(stack.getItem() instanceof ItemScroll) spellsList.retainAll(Spell.getSpells(Spell.nonContinuousSpells)); - - // Ensures the tier chosen actually has spells in it, and if not uses BASIC instead. BASIC always has at least - // the NONE spell since this spell cannot be disabled. - // NOTE: Commented out for now because it will interfere with the ability to specify tiers and elements. - // To be honest, I may as well just say that if you disable enough spells to make this important, you deserve - // less loot! - /* - if(spells.isEmpty()){ - spellsList = Spell.getSpells(new Spell.TierElementFilter(EnumTier.BASIC, null)); - if(stack.getItem() instanceof ItemScroll) spellsList.retainAll(Spell.getSpells(Spell.nonContinuousSpells)); - } - */ - - if(spells != null && !spells.isEmpty()){ - spellsList.retainAll(spells); - } - - if(spellsList.isEmpty()){ - Wizardry.logger.warn("Tried to apply the random_spell loot function to an item, but no enabled spells" - + "matched the criteria specified. Substituting placeholder (metadata 0) item."); - stack.setItemDamage(0); - }else{ - stack.setItemDamage(spellsList.get(random.nextInt(spellsList.size())).id()); - } - - return stack; - } - - public static class Serializer extends LootFunction.Serializer{ - - public Serializer(){ - super(new ResourceLocation(Wizardry.MODID, "random_spell"), RandomSpell.class); - } - - public void serialize(JsonObject object, RandomSpell function, JsonSerializationContext serializationContext){ - - if(function.spells != null && !function.spells.isEmpty()){ - - JsonArray jsonarray = new JsonArray(); - - for(Spell spell : function.spells){ - jsonarray.add(new JsonPrimitive(spell.getRegistryName().toString())); - } - - object.add("spells", jsonarray); - } - - object.addProperty("ignore_weighting", function.ignoreWeighting); - - if(function.tiers != null && !function.tiers.isEmpty()){ - - JsonArray jsonarray = new JsonArray(); - - for(Tier tier : function.tiers){ - jsonarray.add(new JsonPrimitive(tier.getUnlocalisedName())); - } - - object.add("tiers", jsonarray); - } - - if(function.elements != null && !function.elements.isEmpty()){ - - JsonArray jsonarray = new JsonArray(); - - for(Element element : function.elements){ - jsonarray.add(new JsonPrimitive(element.getUnlocalisedName())); - } - - object.add("elements", jsonarray); - } - } - - public RandomSpell deserialize(JsonObject object, JsonDeserializationContext deserializationContext, LootCondition[] conditions){ - - List spells = null; - List tiers = null; - List elements = null; - - if(object.has("spells")){ - - // Vanilla Minecraft calls Lists.newArrayList() here, which is completely pointless. - spells = new ArrayList(); - - // Importantly, it is necessary to specify a default (the new JsonArray) here because otherwise the - // parameter will be mandatory, and the game will crash if it isn't present. - for (JsonElement element : JsonUtils.getJsonArray(object, "spells", new JsonArray())){ - - String string = JsonUtils.getString(element, "spell"); - - Spell spell = Spell.get(string); - - if(spell == null){ - throw new JsonSyntaxException("Unknown spell \'" + string + "\'"); - } - - spells.add(spell); - } - } - - boolean ignoreWeighting = JsonUtils.getBoolean(object, "ignore_weighting", false); - - if(object.has("tiers")){ - - // Vanilla Minecraft calls Lists.newArrayList() here, which is completely pointless. - tiers = new ArrayList(); - - jsonarray: - for(JsonElement element : JsonUtils.getJsonArray(object, "tiers", new JsonArray())){ - - String string = JsonUtils.getString(element, "tier"); - - // IDEA: If it is necessary to get tiers by name elsewhere in the future, move this to EnumTier. - for(Tier tier : Tier.values()){ - if(tier.getUnlocalisedName().equals(string)){ - tiers.add(tier); - continue jsonarray; - } - } - // If the string does not match any of the tiers, throws an exception. - throw new JsonSyntaxException("Unknown tier \'" + string + "\'"); - } - } - - if(object.has("elements")){ - - // Vanilla Minecraft calls Lists.newArrayList() here, which is completely pointless. - elements = new ArrayList(); - - jsonarray: - for(JsonElement jelement : JsonUtils.getJsonArray(object, "elements", new JsonArray())){ - - String string = JsonUtils.getString(jelement, "element"); - - // IDEA: If it is necessary to get elements by name elsewhere in the future, move this to EnumElement. - for(Element element : Element.values()){ - if(element.getUnlocalisedName().equals(string)){ - elements.add(element); - continue jsonarray; - } - } - // If the string does not match any of the elements, throws an exception. - throw new JsonSyntaxException("Unknown element \'" + string + "\'"); - } - } - - return new RandomSpell(conditions, spells, ignoreWeighting, tiers, elements); - } - } - -} diff --git a/src/main/java/electroblob/wizardry/loot/WizardSpell.java b/src/main/java/electroblob/wizardry/loot/WizardSpell.java deleted file mode 100644 index c52898b5..00000000 --- a/src/main/java/electroblob/wizardry/loot/WizardSpell.java +++ /dev/null @@ -1,65 +0,0 @@ -package electroblob.wizardry.loot; - -import java.util.List; -import java.util.Random; - -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonObject; -import com.google.gson.JsonSerializationContext; - -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.entity.living.ISpellCaster; -import electroblob.wizardry.item.ItemSpellBook; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.spell.Spell; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.storage.loot.LootContext; -import net.minecraft.world.storage.loot.conditions.LootCondition; -import net.minecraft.world.storage.loot.functions.LootFunction; - -/** - * Loot function that allows spell books to select a random spell from the spells used by the ISpellCaster that dropped - * them. - * @author Electroblob - * @since Wizardry 1.2 - */ -public class WizardSpell extends LootFunction { - - protected WizardSpell(LootCondition[] conditions){ - super(conditions); - } - - @Override - public ItemStack apply(ItemStack stack, Random random, LootContext context){ - - if(!(stack.getItem() instanceof ItemSpellBook)) - Wizardry.logger.warn("Applying the wizard_spell loot function to an item that isn't a spell book or scroll."); - - if(context.getLootedEntity() instanceof ISpellCaster){ - List spells = ((ISpellCaster)context.getLootedEntity()).getSpells(); - spells.remove(Spells.magic_missile); // Can't drop magic missile - stack.setItemDamage(spells.get(random.nextInt(spells.size())).id()); - }else{ - Wizardry.logger.warn("Applying the wizard_spell loot function to an entity that isn't a spell caster."); - } - - return stack; - } - - public static class Serializer extends LootFunction.Serializer{ - - public Serializer(){ - super(new ResourceLocation(Wizardry.MODID, "wizard_spell"), WizardSpell.class); - } - - public void serialize(JsonObject object, WizardSpell function, JsonSerializationContext serializationContext){ - - } - - public WizardSpell deserialize(JsonObject object, JsonDeserializationContext deserializationContext, LootCondition[] conditions){ - return new WizardSpell(conditions); - } - } - -} diff --git a/src/main/java/electroblob/wizardry/packet/PacketCastContinuousSpell.java b/src/main/java/electroblob/wizardry/packet/PacketCastContinuousSpell.java index 9ef22bae..b467526b 100644 --- a/src/main/java/electroblob/wizardry/packet/PacketCastContinuousSpell.java +++ b/src/main/java/electroblob/wizardry/packet/PacketCastContinuousSpell.java @@ -1,70 +1,82 @@ package electroblob.wizardry.packet; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; import electroblob.wizardry.Wizardry; import electroblob.wizardry.packet.PacketCastContinuousSpell.Message; -import electroblob.wizardry.util.SpellModifiers; +import electroblob.wizardry.spell.Spell; import io.netty.buffer.ByteBuf; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Item; +import net.minecraft.world.World; -/** [Server -> Client] This packet is sent when the /cast command is used with a continuous spell, in order to - * sync the relevant variables in {@link electroblob.wizardry.WizardData WizardData}. */ +/** This packet is sent when the /cast command is used with a continuous spell, in order to sync the relevant variables + * in ExtendedPlayer. */ public class PacketCastContinuousSpell implements IMessageHandler { - + @Override - public IMessage onMessage(Message message, MessageContext ctx){ - + public IMessage onMessage(Message message, MessageContext ctx) + { // Just to make sure that the side is correct if(ctx.side.isClient()){ - // Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy - // methods any more than necessary. - net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(new Runnable(){ - @Override - public void run() { - Wizardry.proxy.handleCastContinuousSpellPacket(message); - } - }); + Wizardry.proxy.handleCastContinuousSpellPacket(message); } return null; } - public static class Message implements IMessage { - + public static class Message implements IMessage + { // Note that range and blast multipliers are the only two that affect particle spawning, so they are the // only two that need to be sent. - + /** EntityID of the caster */ public int casterID; /** ID of the spell being cast */ public int spellID; - /** SpellModifiers for the spell */ - public SpellModifiers modifiers; + /** Range multiplier for the spell */ + public float damageMultiplier; + /** Range multiplier for the spell */ + public float rangeMultiplier; + /** Blast multiplier for the spell */ + public float blastMultiplier; // This constructor is required otherwise you'll get errors (used somewhere in fml through reflection) - public Message(){} + public Message() {} - public Message(int casterID, int spellID, SpellModifiers modifiers){ + public Message(int casterID, int spellID, float damageMultiplier, float rangeMultiplier, float blastMultiplier) + { this.casterID = casterID; this.spellID = spellID; - this.modifiers = modifiers; + this.damageMultiplier = damageMultiplier; + this.rangeMultiplier = rangeMultiplier; + this.blastMultiplier = blastMultiplier; } @Override - public void fromBytes(ByteBuf buf){ + public void fromBytes(ByteBuf buf) + { // The order is important this.casterID = buf.readInt(); this.spellID = buf.readInt(); - this.modifiers = new SpellModifiers(); - modifiers.read(buf); + this.damageMultiplier = buf.readFloat(); + this.rangeMultiplier = buf.readFloat(); + this.blastMultiplier = buf.readFloat(); } @Override - public void toBytes(ByteBuf buf){ + public void toBytes(ByteBuf buf) + { buf.writeInt(casterID); buf.writeInt(spellID); - this.modifiers.write(buf); + buf.writeFloat(damageMultiplier); + buf.writeFloat(rangeMultiplier); + buf.writeFloat(blastMultiplier); } } } diff --git a/src/main/java/electroblob/wizardry/packet/PacketCastSpell.java b/src/main/java/electroblob/wizardry/packet/PacketCastSpell.java index cf57872c..e12badae 100644 --- a/src/main/java/electroblob/wizardry/packet/PacketCastSpell.java +++ b/src/main/java/electroblob/wizardry/packet/PacketCastSpell.java @@ -1,80 +1,92 @@ package electroblob.wizardry.packet; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; import electroblob.wizardry.Wizardry; import electroblob.wizardry.packet.PacketCastSpell.Message; -import electroblob.wizardry.util.SpellModifiers; +import electroblob.wizardry.spell.Spell; import io.netty.buffer.ByteBuf; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; import net.minecraft.item.Item; -import net.minecraft.util.EnumHand; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import net.minecraft.world.World; -/** [Server -> Client] This packet is sent when a spell is cast by a player and returns true, and is sent to other - * clients so they can spawn the particles themselves. What sending this packet effectively does is make the - * {@link Item#onItemRightClick} method client-consistent just for the item that sends it. Interestingly, - * {@link Item#onUsingTick} is client-consistent already, so continuous spells don't need to send packets from there - * (this is probably something to do with eating particles or usage actions). */ +/** This packet is sent when a spell is actually cast and returns true, and is sent to other clients so they can spawn + * the particles themselves. What sending this packet effectively does is make the {@link Item#onItemRightClick} method client-consistent + * just for the item that sends it. Interestingly, {@link Item#onUsingTick} is client-consistent already, so continuous + * spells don't ever need to send packets (this is probably something to do with eating particles or usage actions). */ public class PacketCastSpell implements IMessageHandler { - - @Override - public IMessage onMessage(Message message, MessageContext ctx){ + @Override + public IMessage onMessage(Message message, MessageContext ctx) + { // Just to make sure that the side is correct if(ctx.side.isClient()){ - // Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy - // methods any more than necessary. - net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(new Runnable(){ - @Override - public void run(){ - Wizardry.proxy.handleCastSpellPacket(message); - } - }); + Wizardry.proxy.handleCastSpellPacket(message); } return null; } - public static class Message implements IMessage { - + public static class Message implements IMessage + { + // Note that range and blast multipliers are the only two that affect particle spawning, so they are the + // only two that need to be sent. + /** EntityID of the caster */ public int casterID; + /** EntityID of the target */ + public int targetID; /** ID of the spell being cast */ public int spellID; - /** SpellModifiers for the spell */ - public SpellModifiers modifiers; - /** The hand that is holding the itemstack used to cast the spell. Defaults to MAIN_HAND. */ - public EnumHand hand; + // Do these really need to be here or can I just get them from the wand nbt at the other end? + // ... have I tried that before? + // You do now, because of the /cast command. + /** Range multiplier for the spell */ + public float damageMultiplier; + /** Range multiplier for the spell */ + public float rangeMultiplier; + /** Blast multiplier for the spell */ + public float blastMultiplier; // This constructor is required otherwise you'll get errors (used somewhere in fml through reflection) - public Message(){} + public Message() {} - public Message(int casterID, EnumHand hand, int spellID, SpellModifiers modifiers){ - + public Message(int casterID, int targetID, int spellID, float damageMultiplier, float rangeMultiplier, float blastMultiplier) + { this.casterID = casterID; + this.targetID = targetID; this.spellID = spellID; - this.modifiers = modifiers; - this.hand = hand == null ? EnumHand.MAIN_HAND : hand; + this.damageMultiplier = damageMultiplier; + this.rangeMultiplier = rangeMultiplier; + this.blastMultiplier = blastMultiplier; } @Override - public void fromBytes(ByteBuf buf){ - + public void fromBytes(ByteBuf buf) + { // The order is important this.casterID = buf.readInt(); + this.targetID = buf.readInt(); this.spellID = buf.readInt(); - this.modifiers = new SpellModifiers(); - this.modifiers.read(buf); - this.hand = buf.readBoolean() ? EnumHand.OFF_HAND : EnumHand.MAIN_HAND; + this.damageMultiplier = buf.readFloat(); + this.rangeMultiplier = buf.readFloat(); + this.blastMultiplier = buf.readFloat(); } @Override - public void toBytes(ByteBuf buf){ - + public void toBytes(ByteBuf buf) + { buf.writeInt(casterID); + buf.writeInt(targetID); buf.writeInt(spellID); - this.modifiers.write(buf); - buf.writeBoolean(this.hand == EnumHand.OFF_HAND); + buf.writeFloat(damageMultiplier); + buf.writeFloat(rangeMultiplier); + buf.writeFloat(blastMultiplier); } } } diff --git a/src/main/java/electroblob/wizardry/packet/PacketClairvoyance.java b/src/main/java/electroblob/wizardry/packet/PacketClairvoyance.java index f7f350bd..3daab7b3 100644 --- a/src/main/java/electroblob/wizardry/packet/PacketClairvoyance.java +++ b/src/main/java/electroblob/wizardry/packet/PacketClairvoyance.java @@ -3,17 +3,17 @@ package electroblob.wizardry.packet; import java.util.ArrayList; import java.util.List; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; import electroblob.wizardry.Wizardry; import electroblob.wizardry.packet.PacketClairvoyance.Message; import io.netty.buffer.ByteBuf; -import net.minecraft.pathfinding.Path; +import net.minecraft.pathfinding.PathEntity; import net.minecraft.pathfinding.PathPoint; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; -/** [Server -> Client] This packet is sent when a player casts the clairvoyance spell to allow pathing to chunks - * outside the render distance. */ +/** This packet is sent when a player casts the clairvoyance spell to allow pathing to chunks outside the render + * distance. */ public class PacketClairvoyance implements IMessageHandler { @Override @@ -21,14 +21,7 @@ public class PacketClairvoyance implements IMessageHandler { { // Just to make sure that the side is correct if(ctx.side.isClient()){ - // Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy - // methods any more than necessary. - net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(new Runnable(){ - @Override - public void run(){ - Wizardry.proxy.handleClairvoyancePacket(message); - } - }); + Wizardry.proxy.handleClairvoyancePacket(message); } return null; @@ -36,13 +29,13 @@ public class PacketClairvoyance implements IMessageHandler { public static class Message implements IMessage { - public Path path; + public PathEntity path; public float durationMultiplier; // This constructor is required otherwise you'll get errors (used somewhere in fml through reflection) public Message() {} - public Message(Path path, float durationMultiplier){ + public Message(PathEntity path, float durationMultiplier){ this.path = path; this.durationMultiplier = durationMultiplier; @@ -60,7 +53,7 @@ public class PacketClairvoyance implements IMessageHandler { points.add(new PathPoint(buf.readInt(), buf.readInt(), buf.readInt())); } - this.path = new Path(points.toArray(new PathPoint[0])); + this.path = new PathEntity(points.toArray(new PathPoint[points.size()])); } @Override diff --git a/src/main/java/electroblob/wizardry/packet/PacketControlInput.java b/src/main/java/electroblob/wizardry/packet/PacketControlInput.java index afa52a4f..056782c8 100644 --- a/src/main/java/electroblob/wizardry/packet/PacketControlInput.java +++ b/src/main/java/electroblob/wizardry/packet/PacketControlInput.java @@ -1,100 +1,282 @@ package electroblob.wizardry.packet; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.WandHelper; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryRegistry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.item.ItemWand; +import electroblob.wizardry.item.ItemWizardArmour; import electroblob.wizardry.packet.PacketControlInput.Message; +import electroblob.wizardry.spell.Spell; import electroblob.wizardry.tileentity.ContainerArcaneWorkbench; -import electroblob.wizardry.util.WandHelper; +import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench; import io.netty.buffer.ByteBuf; -import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; - -/** [Client -> Server] This packet is for control events such as buttons in GUIs and key presses. */ -public class PacketControlInput implements IMessageHandler { +import net.minecraft.nbt.NBTTagCompound; +/** This packet is for control events such as buttons in GUIs and key presses. */ +public class PacketControlInput implements IMessageHandler +{ @Override - public IMessage onMessage(Message message, MessageContext ctx){ - + public IMessage onMessage(Message message, MessageContext ctx) + { // Just to make sure that the side is correct - if(ctx.side.isServer()){ + if (ctx.side.isServer()) + { + int eventID = message.eventID; + EntityPlayer entityplayer = ctx.getServerHandler().playerEntity; + + if(eventID == 0){ + // Note: the following long line of code gets the itemstack in a roundabout way because it needs + // to access the tile entity rather than the container to actually get to the items. + TileEntityArcaneWorkbench tileentity = ((ContainerArcaneWorkbench)entityplayer.openContainer).tileEntityArcaneWorkbench; + + ItemStack wand = tileentity.getStackInSlot(ContainerArcaneWorkbench.WAND_SLOT); + ItemStack[] spellBooks = new ItemStack[ContainerArcaneWorkbench.CRYSTAL_SLOT]; + for(int i=0; i 0){ + for(int i=0; i ((ItemWand)wand.getItem()).tier.level)){ + spells[i] = Spell.get(spellBooks[i].getItemDamage()); + } + } + WandHelper.setSpells(wand, spells); + + // Charges wand by appropriate amount + if(crystals != null){ + int chargeDepleted = wand.getItemDamage(); + //System.out.println("Charge depleted: " + chargeDepleted); + //System.out.println("Crystals found: " + crystals.stackSize); + if(crystals.stackSize * Wizardry.MANA_PER_CRYSTAL < chargeDepleted){ + //System.out.println("charging"); + wand.setItemDamage(chargeDepleted - crystals.stackSize * Wizardry.MANA_PER_CRYSTAL); + tileentity.decrStackSize(ContainerArcaneWorkbench.CRYSTAL_SLOT, crystals.stackSize); + }else if(chargeDepleted != 0){ + //System.out.println((int)Math.ceil(((double)chargeDepleted)/50)); + tileentity.decrStackSize(ContainerArcaneWorkbench.CRYSTAL_SLOT, (int)Math.ceil(((double)chargeDepleted)/Wizardry.MANA_PER_CRYSTAL)); + wand.setItemDamage(0); + } + } + + // Armour + }else if(wand != null && wand.getItem() instanceof ItemWizardArmour){ + // Applies legendary upgrade + if(upgrade != null && upgrade.getItem() == Wizardry.armourUpgrade){ + if(!wand.hasTagCompound()){ + wand.stackTagCompound = new NBTTagCompound(); + } + if(!wand.stackTagCompound.hasKey("legendary")){ + wand.stackTagCompound.setBoolean("legendary", true); + tileentity.setInventorySlotContents(ContainerArcaneWorkbench.UPGRADE_SLOT, null); + entityplayer.triggerAchievement(Wizardry.legendary); + } + } + // Charges armour by appropriate amount + if(crystals != null){ + int chargeDepleted = wand.getItemDamage(); + if(crystals.stackSize * Wizardry.MANA_PER_CRYSTAL < chargeDepleted){ + wand.setItemDamage(chargeDepleted - crystals.stackSize * Wizardry.MANA_PER_CRYSTAL); + tileentity.decrStackSize(ContainerArcaneWorkbench.CRYSTAL_SLOT, crystals.stackSize); + }else if(chargeDepleted != 0){ + tileentity.decrStackSize(ContainerArcaneWorkbench.CRYSTAL_SLOT, (int)Math.ceil(((double)chargeDepleted)/Wizardry.MANA_PER_CRYSTAL)); + wand.setItemDamage(0); + } + } + + // Scrolls + }else if(wand != null && wand.getItem() == Wizardry.blankScroll){ + // Spells can only be bound to scrolls if the player has already cast them (prevents casting of master spells without getting a master wand) + // This restriction does not apply in creative mode + if(spellBooks[0] != null && (entityplayer.capabilities.isCreativeMode || (ExtendedPlayer.get(entityplayer) != null + && ExtendedPlayer.get(entityplayer).hasSpellBeenDiscovered(Spell.get(spellBooks[0].getItemDamage())))) + && crystals != null && crystals.stackSize * Wizardry.MANA_PER_CRYSTAL > Spell.get(spellBooks[0].getItemDamage()).cost){ - public void run() { + tileentity.decrStackSize(ContainerArcaneWorkbench.CRYSTAL_SLOT, (int)Math.ceil(((double)Spell.get(spellBooks[0].getItemDamage()).cost)/Wizardry.MANA_PER_CRYSTAL)); + tileentity.setInventorySlotContents(ContainerArcaneWorkbench.WAND_SLOT, new ItemStack(Wizardry.scroll, 1, spellBooks[0].getItemDamage())); + } + } + + ////////////////////////////////////////////////////////////////////////////////////////////// + + }else if(eventID == 1){ + if(entityplayer.inventory.getCurrentItem() != null && + entityplayer.inventory.getCurrentItem().getItem() instanceof ItemWand){ + + ItemStack wand = entityplayer.inventory.getCurrentItem(); + + if(wand != null) WandHelper.selectNextSpell(wand); + + // This line fixes the bug with continuous spells casting when they shouldn't be + entityplayer.clearItemInUse(); + } + + ////////////////////////////////////////////////////////////////////////////////////////////// + + }else if(eventID == 2){ + if(entityplayer.inventory.getCurrentItem() != null && + entityplayer.inventory.getCurrentItem().getItem() instanceof ItemWand){ + + ItemStack wand = entityplayer.inventory.getCurrentItem(); + + if(wand != null) WandHelper.selectPreviousSpell(wand); - ItemStack wand = player.getHeldItemMainhand(); - - if(wand == null || !(wand.getItem() instanceof ItemWand)){ - wand = player.getHeldItemOffhand(); - } - - switch(message.controlType){ - - case APPLY_BUTTON: - - ((ContainerArcaneWorkbench)player.openContainer).onApplyButtonPressed(player); - break; - - case NEXT_SPELL_KEY: - - if(wand != null && wand.getItem() instanceof ItemWand){ - - WandHelper.selectNextSpell(wand); - // This line fixes the bug with continuous spells casting when they shouldn't be - player.stopActiveHand(); - } - - break; - - case PREVIOUS_SPELL_KEY: - - if(wand != null && wand.getItem() instanceof ItemWand){ - - WandHelper.selectPreviousSpell(wand); - // This line fixes the bug with continuous spells casting when they shouldn't be - player.stopActiveHand(); - } - - break; - } - } - } - ); + // This line fixes the bug with continuous spells casting when they shouldn't be + entityplayer.clearItemInUse(); + } + } } return null; } - public static enum ControlType { - APPLY_BUTTON, - NEXT_SPELL_KEY, - PREVIOUS_SPELL_KEY; - } - - public static class Message implements IMessage { - - private ControlType controlType; + public static class Message implements IMessage + { + /** 0 = Apply button in arcane workbench, 1 = N key, 2 = B key */ + private int eventID; // This constructor is required otherwise you'll get errors (used somewhere in fml through reflection) public Message() {} - public Message(ControlType type){ - this.controlType = type; + public Message(int eventID) + { + this.eventID = eventID; } @Override - public void fromBytes(ByteBuf buf){ + public void fromBytes(ByteBuf buf) + { // The order is important - this.controlType = ControlType.values()[buf.readInt()]; + this.eventID = buf.readInt(); } @Override - public void toBytes(ByteBuf buf){ - buf.writeInt(controlType.ordinal()); + public void toBytes(ByteBuf buf) + { + buf.writeInt(eventID); } } } diff --git a/src/main/java/electroblob/wizardry/packet/PacketGlyphData.java b/src/main/java/electroblob/wizardry/packet/PacketGlyphData.java index 7f7191e5..cb3cc818 100644 --- a/src/main/java/electroblob/wizardry/packet/PacketGlyphData.java +++ b/src/main/java/electroblob/wizardry/packet/PacketGlyphData.java @@ -3,38 +3,31 @@ package electroblob.wizardry.packet; import java.util.ArrayList; import java.util.List; +import cpw.mods.fml.common.network.ByteBufUtils; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; import electroblob.wizardry.Wizardry; import electroblob.wizardry.packet.PacketGlyphData.Message; import io.netty.buffer.ByteBuf; -import net.minecraftforge.fml.common.network.ByteBufUtils; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; -/** [Server -> Client] This packet is sent each time a player joins a world to synchronise the client-side spell - * glyph names with the server-side ones. */ +/** This packet is sent each time a player joins a world to synchronise the client-side spell glyph names with + * the server-side ones. */ public class PacketGlyphData implements IMessageHandler { - + @Override public IMessage onMessage(Message message, MessageContext ctx) { // Just to make sure that the side is correct if(ctx.side.isClient()){ - // Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy - // methods any more than necessary. - net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(new Runnable(){ - @Override - public void run(){ - Wizardry.proxy.handleGlyphDataPacket(message); - } - }); + Wizardry.proxy.handleGlyphDataPacket(message); } return null; } public static class Message implements IMessage { - + /** The list of randomised spell names. */ public List names; /** The list of randomised spell descriptions. */ diff --git a/src/main/java/electroblob/wizardry/packet/PacketNPCCastSpell.java b/src/main/java/electroblob/wizardry/packet/PacketNPCCastSpell.java deleted file mode 100644 index ea2e049f..00000000 --- a/src/main/java/electroblob/wizardry/packet/PacketNPCCastSpell.java +++ /dev/null @@ -1,80 +0,0 @@ -package electroblob.wizardry.packet; - -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.entity.living.ISpellCaster; -import electroblob.wizardry.packet.PacketNPCCastSpell.Message; -import electroblob.wizardry.util.SpellModifiers; -import io.netty.buffer.ByteBuf; -import net.minecraft.util.EnumHand; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; - -/** [Server -> Client] This packet is sent when an {@link ISpellCaster} casts a spell which returns true, and is - * sent to clients so they can spawn the particles. Unlike the player packets, this is for both continuous and - * non-continuous spells. */ -public class PacketNPCCastSpell implements IMessageHandler { - - @Override - public IMessage onMessage(Message message, MessageContext ctx){ - - // Just to make sure that the side is correct - if(ctx.side.isClient()){ - // Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy - // methods any more than necessary. - net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(new Runnable(){ - @Override - public void run(){ - Wizardry.proxy.handleNPCCastSpellPacket(message); - } - }); - } - - return null; - } - - public static class Message implements IMessage { - - /** EntityID of the caster */ - public int casterID; - /** EntityID of the target, or -1 if there is none */ - public int targetID; - /** ID of the spell being cast */ - public int spellID; - /** SpellModifiers for the spell */ - public SpellModifiers modifiers; - /** The hand that is holding the itemstack used to cast the spell. Defaults to MAIN_HAND. */ - public EnumHand hand; - - // This constructor is required otherwise you'll get errors (used somewhere in fml through reflection) - public Message(){} - - public Message(int casterID, int targetID, EnumHand hand, int spellID, SpellModifiers modifiers){ - this.casterID = casterID; - this.targetID = targetID; - this.spellID = spellID; - this.modifiers = modifiers; - this.hand = hand == null ? EnumHand.MAIN_HAND : hand; - } - - @Override - public void fromBytes(ByteBuf buf){ - // The order is important - this.casterID = buf.readInt(); - this.targetID = buf.readInt(); - this.spellID = buf.readInt(); - this.modifiers = new SpellModifiers(); - this.modifiers.read(buf); - this.hand = buf.readBoolean() ? EnumHand.OFF_HAND : EnumHand.MAIN_HAND; - } - - @Override - public void toBytes(ByteBuf buf){ - buf.writeInt(casterID); - buf.writeInt(targetID); - buf.writeInt(spellID); - this.modifiers.write(buf); - buf.writeBoolean(this.hand == EnumHand.OFF_HAND); - } - } -} diff --git a/src/main/java/electroblob/wizardry/packet/PacketParticleSpawn.java b/src/main/java/electroblob/wizardry/packet/PacketParticleSpawn.java new file mode 100644 index 00000000..8edb2e7a --- /dev/null +++ b/src/main/java/electroblob/wizardry/packet/PacketParticleSpawn.java @@ -0,0 +1,157 @@ +package electroblob.wizardry.packet; + +import cpw.mods.fml.common.network.ByteBufUtils; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; +import electroblob.wizardry.client.particle.EntityBlizzardFX; +import electroblob.wizardry.client.particle.EntityDarkMagicFX; +import electroblob.wizardry.client.particle.EntityDustFX; +import electroblob.wizardry.client.particle.EntityLeafFX; +import electroblob.wizardry.client.particle.EntityMagicBubbleFX; +import electroblob.wizardry.client.particle.EntityMagicFireFX; +import electroblob.wizardry.client.particle.EntitySnowFX; +import electroblob.wizardry.client.particle.EntitySparkFX; +import electroblob.wizardry.client.particle.EntitySparkleFX; +import electroblob.wizardry.client.particle.EntityTornadoFX; +import electroblob.wizardry.packet.PacketParticleSpawn.Message; +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.world.World; + +/** This packet is for spawning particles from any method which is client-inconsistent, such as Item#onItemRightClick. + * It can also be used as a lazy fix when the particles depend on conditions which are not synchronised (though it is + * strictly better to synchronise the conditions themselves, in practice it isn't usually worth it unless there are + * loads of particles) + *

    + * DEPRECATED in favour of an 'event packet' based system. */ +@Deprecated +public class PacketParticleSpawn implements IMessageHandler { + + @Override + public IMessage onMessage(Message message, MessageContext ctx) + { + // Just to make sure that the side is correct + if(ctx.side.isClient()){ + + World world = Minecraft.getMinecraft().theWorld; + + if(message.name == EntityBlizzardFX.NAME){ + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityBlizzardFX(world, message.r, message.g, message.b, message.maxAge, message.x, message.z, message.velY, message.y)); + } + else if(message.name == EntityDarkMagicFX.NAME){ + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityDarkMagicFX(world, message.x, message.y, message.z, message.velX, message.velY, message.velZ, message.r, message.g, message.b)); + } + else if(message.name == EntityDustFX.NAME){ + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityDustFX(world, message.x, message.y, message.z, message.velX, message.velY, message.velZ, message.r, message.g, message.b, false)); + } + else if(message.name == EntityLeafFX.NAME){ + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityLeafFX(world, message.x, message.y, message.z, message.velX, message.velY, message.velZ, message.maxAge)); + } + else if(message.name == EntityMagicBubbleFX.NAME){ + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityMagicBubbleFX(world, message.x, message.y, message.z, message.velX, message.velY, message.velZ)); + } + else if(message.name == EntityMagicFireFX.NAME){ + Minecraft.getMinecraft().effectRenderer.addEffect(new EntityMagicFireFX(world, message.x, message.y, message.z, message.velX, message.velY, message.velZ, message.maxAge, 1)); + } + else if(message.name == EntitySnowFX.NAME){ + Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySnowFX(world, message.x, message.y, message.z, message.velX, message.velY, message.velZ, message.maxAge)); + } + else if(message.name == EntitySparkFX.NAME){ + Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySparkFX(world, message.x, message.y, message.z, message.velX, message.velY, message.velZ)); + } + else if(message.name == EntitySparkleFX.NAME){ + Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySparkleFX(world, message.x, message.y, message.z, message.velX, message.velY, message.velZ, message.r, message.g, message.b, message.maxAge, false)); + } + else if(message.name == EntitySparkleFX.NAME_GRAVITY){ + Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySparkleFX(world, message.x, message.y, message.z, message.velX, message.velY, message.velZ, message.r, message.g, message.b, message.maxAge, true)); + } + else{ + world.spawnParticle(message.name, message.x, message.y, message.z, message.velX, message.velY, message.velZ); + } + } + + return null; + } + + public static class Message implements IMessage + { + // Some of these fields have multiple uses depending on the particle type. This is to save on packet + // size as much as possible. + + /** Particle name. Either a vanilla name (see RenderGlobal) or one of the custom particles' NAME field. */ + private String name; + + /** Usually the x position of the particle, but a few particles use it differently. */ + private double x; + /** Usually the y position of the particle, but a few particles use it differently. */ + private double y; + /** Usually the z position of the particle, but a few particles use it differently. */ + private double z; + + /** Usually the x velocity of the particle, but a few particles use it differently. */ + private double velX; + /** Usually the y velocity of the particle, but a few particles use it differently - + * for example, tornado and blizzard fx use this as the radius. */ + private double velY; + /** Usually the z velocity of the particle, but a few particles use it differently. */ + private double velZ; + + private int maxAge; + + private float r; + private float g; + private float b; + + // This constructor is required otherwise you'll get errors (used somewhere in fml through reflection) + public Message() {} + + public Message(String name, double x, double y, double z, double velX, double velY, double velZ, int maxAge, float r, float g, float b) + { + this.name = name; + this.x = x; + this.y = y; + this.z = z; + this.velX = velX; + this.velY = velY; + this.velZ = velZ; + this.maxAge = maxAge; + this.r = r; + this.g = g; + this.b = b; + } + + @Override + public void fromBytes(ByteBuf buf) + { + // The order is important + this.name = ByteBufUtils.readUTF8String(buf); + this.x = buf.readDouble(); + this.y = buf.readDouble(); + this.z = buf.readDouble(); + this.velX = buf.readDouble(); + this.velY = buf.readDouble(); + this.velZ = buf.readDouble(); + this.maxAge = buf.readInt(); + this.r = buf.readFloat(); + this.g = buf.readFloat(); + this.b = buf.readFloat(); + } + + @Override + public void toBytes(ByteBuf buf) + { + ByteBufUtils.writeUTF8String(buf, name); + buf.writeDouble(x); + buf.writeDouble(y); + buf.writeDouble(z); + buf.writeDouble(velX); + buf.writeDouble(velY); + buf.writeDouble(velZ); + buf.writeInt(maxAge); + buf.writeFloat(r); + buf.writeFloat(g); + buf.writeFloat(b); + } + } +} diff --git a/src/main/java/electroblob/wizardry/packet/PacketPlayerSync.java b/src/main/java/electroblob/wizardry/packet/PacketPlayerSync.java index d58dfbe4..154c88a0 100644 --- a/src/main/java/electroblob/wizardry/packet/PacketPlayerSync.java +++ b/src/main/java/electroblob/wizardry/packet/PacketPlayerSync.java @@ -1,49 +1,39 @@ package electroblob.wizardry.packet; import java.util.HashSet; -import java.util.Set; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; import electroblob.wizardry.Wizardry; import electroblob.wizardry.packet.PacketPlayerSync.Message; import electroblob.wizardry.spell.Spell; import io.netty.buffer.ByteBuf; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; -/** [Server -> Client] This packet is sent to synchronise any fields that need synchronising in - * {@link electroblob.wizardry.WizardData WizardData}. This packet is not sent often enough and is too small to warrant - * having separate packets for each field that needs synchronising. */ +/** This packet is sent to synchronise extended player data. */ public class PacketPlayerSync implements IMessageHandler { - + @Override public IMessage onMessage(Message message, MessageContext ctx) { // Just to make sure that the side is correct if(ctx.side.isClient()){ - // Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy - // methods any more than necessary. - net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(new Runnable(){ - @Override - public void run(){ - Wizardry.proxy.handlePlayerSyncPacket(message); - } - }); + Wizardry.proxy.handlePlayerSyncPacket(message); } return null; } public static class Message implements IMessage { - - public Set spellsDiscovered; + + public HashSet spellsDiscovered; public int selectedMinionID; // This constructor is required otherwise you'll get errors (used somewhere in fml through reflection) public Message() {} - public Message(Set spellsDiscovered2, int selectedMinionID){ - this.spellsDiscovered = spellsDiscovered2; + public Message(HashSet spellsDiscovered, int selectedMinionID){ + this.spellsDiscovered = spellsDiscovered; this.selectedMinionID = selectedMinionID; } @@ -58,11 +48,11 @@ public class PacketPlayerSync implements IMessageHandler { @Override public void toBytes(ByteBuf buf){ - + buf.writeInt(selectedMinionID); - + if(this.spellsDiscovered == null) return; - + for(Spell spell : this.spellsDiscovered){ buf.writeInt(spell.id()); } diff --git a/src/main/java/electroblob/wizardry/packet/PacketSyncSettings.java b/src/main/java/electroblob/wizardry/packet/PacketSyncSettings.java deleted file mode 100644 index bed891c6..00000000 --- a/src/main/java/electroblob/wizardry/packet/PacketSyncSettings.java +++ /dev/null @@ -1,90 +0,0 @@ -package electroblob.wizardry.packet; - -import electroblob.wizardry.Settings; -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.packet.PacketSyncSettings.Message; -import io.netty.buffer.ByteBuf; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; - -/** [Server -> Client] This packet is sent to synchronise the config settings with clients on player login. - * @see Settings */ -public class PacketSyncSettings implements IMessageHandler { - - @Override - public IMessage onMessage(Message message, MessageContext ctx){ - - if(ctx.side.isClient()){ - // Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy - // any more than necessary. - net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(new Runnable(){ - @Override - public void run(){ - copySettings(message); - } - }); - - } - - return null; - } - - private static void copySettings(Message message){ - Wizardry.settings.firebombIsCraftable = message.settings.firebombIsCraftable; - Wizardry.settings.poisonBombIsCraftable = message.settings.poisonBombIsCraftable; - Wizardry.settings.smokeBombIsCraftable = message.settings.smokeBombIsCraftable; - Wizardry.settings.useAlternateScrollRecipe = message.settings.useAlternateScrollRecipe; - Wizardry.settings.discoveryMode = message.settings.discoveryMode; -// Wizardry.settings.maxSpellCommandMultiplier = message.settings.maxSpellCommandMultiplier; -// Wizardry.settings.castCommandName = message.settings.castCommandName; -// Wizardry.settings.discoverspellCommandName = message.settings.discoverspellCommandName; -// Wizardry.settings.allyCommandName = message.settings.allyCommandName; -// Wizardry.settings.alliesCommandName = message.settings.alliesCommandName; - } - - public static class Message implements IMessage { - - /** EntityID of the caster */ - public Settings settings; - - // This constructor is required otherwise you'll get errors (used somewhere in fml through reflection) - public Message(){} - - public Message(Settings settings){ - this.settings = settings; - } - - @Override - public void fromBytes(ByteBuf buf){ - // I'm guessing the settings field will be null here, so it needs initialising. - // This is also a great reason to have the settings as an actual object. - settings = new Settings(); - // The order is important - settings.firebombIsCraftable = buf.readBoolean(); - settings.poisonBombIsCraftable = buf.readBoolean(); - settings.smokeBombIsCraftable = buf.readBoolean(); - settings.useAlternateScrollRecipe = buf.readBoolean(); - settings.discoveryMode = buf.readBoolean(); -// settings.maxSpellCommandMultiplier = buf.readDouble(); -// settings.castCommandName = ByteBufUtils.readUTF8String(buf); -// settings.discoverspellCommandName = ByteBufUtils.readUTF8String(buf); -// settings.allyCommandName = ByteBufUtils.readUTF8String(buf); -// settings.alliesCommandName = ByteBufUtils.readUTF8String(buf); - } - - @Override - public void toBytes(ByteBuf buf){ - buf.writeBoolean(settings.firebombIsCraftable); - buf.writeBoolean(settings.poisonBombIsCraftable); - buf.writeBoolean(settings.smokeBombIsCraftable); - buf.writeBoolean(settings.useAlternateScrollRecipe); - buf.writeBoolean(settings.discoveryMode); -// buf.writeDouble(settings.maxSpellCommandMultiplier); -// ByteBufUtils.writeUTF8String(buf, settings.castCommandName); -// ByteBufUtils.writeUTF8String(buf, settings.discoverspellCommandName); -// ByteBufUtils.writeUTF8String(buf, settings.allyCommandName); -// ByteBufUtils.writeUTF8String(buf, settings.alliesCommandName); - } - } -} diff --git a/src/main/java/electroblob/wizardry/packet/PacketTransportation.java b/src/main/java/electroblob/wizardry/packet/PacketTransportation.java index 7a7085c8..e440c524 100644 --- a/src/main/java/electroblob/wizardry/packet/PacketTransportation.java +++ b/src/main/java/electroblob/wizardry/packet/PacketTransportation.java @@ -1,29 +1,29 @@ package electroblob.wizardry.packet; +import cpw.mods.fml.common.network.simpleimpl.IMessage; +import cpw.mods.fml.common.network.simpleimpl.IMessageHandler; +import cpw.mods.fml.common.network.simpleimpl.MessageContext; import electroblob.wizardry.Wizardry; import electroblob.wizardry.packet.PacketTransportation.Message; +import electroblob.wizardry.spell.Spell; import io.netty.buffer.ByteBuf; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Item; +import net.minecraft.world.World; -/** [Server -> Client] This packet is sent when a player is teleported due to the transportation spell to spawn - * the particles. */ +/** This packet is sent when a player is teleported due to the transportation spell to spawn the particles. */ public class PacketTransportation implements IMessageHandler { - + @Override public IMessage onMessage(Message message, MessageContext ctx) { // Just to make sure that the side is correct if(ctx.side.isClient()){ - // Using a fully qualified name is a good course of action here; we don't really want to clutter the proxy - // methods any more than necessary. - net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(new Runnable(){ - @Override - public void run(){ - Wizardry.proxy.handleTransportationPacket(message); - } - }); + Wizardry.proxy.handleTransportationPacket(message); } return null; diff --git a/src/main/java/electroblob/wizardry/packet/WizardryPacketHandler.java b/src/main/java/electroblob/wizardry/packet/WizardryPacketHandler.java index dedaead6..29bab1a5 100644 --- a/src/main/java/electroblob/wizardry/packet/WizardryPacketHandler.java +++ b/src/main/java/electroblob/wizardry/packet/WizardryPacketHandler.java @@ -1,11 +1,9 @@ package electroblob.wizardry.packet; +import cpw.mods.fml.common.network.NetworkRegistry; +import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper; +import cpw.mods.fml.relauncher.Side; import electroblob.wizardry.Wizardry; -import net.minecraftforge.fml.common.network.NetworkRegistry; -import net.minecraftforge.fml.common.network.simpleimpl.IMessage; -import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; -import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; -import net.minecraftforge.fml.relauncher.Side; public class WizardryPacketHandler { @@ -15,19 +13,18 @@ public class WizardryPacketHandler { { net = NetworkRegistry.INSTANCE.newSimpleChannel(Wizardry.MODID.toUpperCase()); registerMessage(PacketControlInput.class, PacketControlInput.Message.class); + //registerMessage(PacketParticleSpawn.class, PacketParticleSpawn.Message.class); registerMessage(PacketCastSpell.class, PacketCastSpell.Message.class); registerMessage(PacketTransportation.class, PacketTransportation.Message.class); registerMessage(PacketPlayerSync.class, PacketPlayerSync.Message.class); registerMessage(PacketGlyphData.class, PacketGlyphData.Message.class); registerMessage(PacketCastContinuousSpell.class, PacketCastContinuousSpell.Message.class); registerMessage(PacketClairvoyance.class, PacketClairvoyance.Message.class); - registerMessage(PacketSyncSettings.class, PacketSyncSettings.Message.class); - registerMessage(PacketNPCCastSpell.class, PacketNPCCastSpell.Message.class); } private static int nextPacketId = 0; - private static void registerMessage(Class> packet, Class message) + private static void registerMessage(Class packet, Class message) { net.registerMessage(packet, message, nextPacketId, Side.CLIENT); net.registerMessage(packet, message, nextPacketId, Side.SERVER); diff --git a/src/main/java/electroblob/wizardry/potion/ICustomPotionParticles.java b/src/main/java/electroblob/wizardry/potion/ICustomPotionParticles.java deleted file mode 100644 index dcb19997..00000000 --- a/src/main/java/electroblob/wizardry/potion/ICustomPotionParticles.java +++ /dev/null @@ -1,45 +0,0 @@ -package electroblob.wizardry.potion; - -import net.minecraft.potion.PotionEffect; -import net.minecraft.world.World; -import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; - -/** - * Interface for potion effects that spawn custom particles instead of (or as well as) the vanilla 'swirly' particles. - * @author Electroblob - * @since Wizardry 1.2 - */ -// TODO: Backport. -@Mod.EventBusSubscriber -public interface ICustomPotionParticles { - - /** - * Called from the event handler to spawn a single custom potion particle. To get an instance of - * Random inside this method, use world.rand. - * @param world The world to spawn the particle in. - * @param x The x coordinate of the particle, already set to a random value within the entity's bounding box. - * @param y The y coordinate of the particle, already set to a random value within the entity's bounding box. - * @param z The z coordinate of the particle, already set to a random value within the entity's bounding box. - */ - void spawnCustomParticle(World world, double x, double y, double z); - - @SubscribeEvent - public static void onLivingUpdateEvent(LivingUpdateEvent event){ - if(event.getEntityLiving().worldObj.isRemote){ - // Behold the power of interfaces! - for(PotionEffect effect : event.getEntityLiving().getActivePotionEffects()){ - - if(effect.getPotion() instanceof ICustomPotionParticles && effect.doesShowParticles()){ - - double x = event.getEntityLiving().posX + (event.getEntityLiving().worldObj.rand.nextDouble() - 0.5)*event.getEntityLiving().width; - double y = event.getEntityLiving().getEntityBoundingBox().minY + event.getEntityLiving().worldObj.rand.nextDouble()*event.getEntityLiving().height; - double z = event.getEntityLiving().posZ + (event.getEntityLiving().worldObj.rand.nextDouble() - 0.5)*event.getEntityLiving().width; - - ((ICustomPotionParticles)effect.getPotion()).spawnCustomParticle(event.getEntityLiving().worldObj, x, y, z); - } - } - } - } -} diff --git a/src/main/java/electroblob/wizardry/potion/PotionDecay.java b/src/main/java/electroblob/wizardry/potion/PotionDecay.java index 6e767866..e8746fee 100644 --- a/src/main/java/electroblob/wizardry/potion/PotionDecay.java +++ b/src/main/java/electroblob/wizardry/potion/PotionDecay.java @@ -1,30 +1,21 @@ package electroblob.wizardry.potion; -import java.util.List; - import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Constants; -import electroblob.wizardry.entity.construct.EntityDecay; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.DamageSource; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; public class PotionDecay extends Potion { - private static final ResourceLocation ICON = new ResourceLocation(Wizardry.MODID, "textures/gui/decay_icon.png"); + private static final ResourceLocation potionIcon = new ResourceLocation(Wizardry.MODID, "textures/gui/decay_icon.png"); - public PotionDecay(boolean isBadEffect, int liquidColour) { - super(isBadEffect, liquidColour); - // This needs to be here because registerPotionAttributeModifier doesn't like it if the potion has no name yet. - this.setPotionName("potion.wizardry:decay"); - this.registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED, "85602e0b-4801-4a87-94f3-bf617c97014e", -Constants.DECAY_SLOWNESS_PER_LEVEL, 2); + public PotionDecay(int id, boolean isBadEffect, int liquidColour) { + super(id, isBadEffect, liquidColour); + this.setPotionName("potion.decay"); + this.func_111184_a(SharedMonsterAttributes.movementSpeed, "85602e0b-4801-4a87-94f3-bf617c97014e", -Wizardry.DECAY_SLOWNESS_PER_LEVEL, 2); } @Override @@ -36,39 +27,40 @@ public class PotionDecay extends Potion { } @Override - public void performEffect(EntityLivingBase target, int strength) { - - target.attackEntityFrom(DamageSource.wither, 1); - - if(target.onGround && target.ticksExisted % Constants.DECAY_SPREAD_INTERVAL == 0){ - - List entities = target.worldObj.getEntitiesWithinAABBExcludingEntity(target, target.getEntityBoundingBox()); - - boolean flag = true; - - for(Entity entity : entities){ - if(entity instanceof EntityDecay) flag = false; - } - - if(flag){ - // The victim spreading the decay is the 'caster' here, so that it can actually wear off, otherwise it just gets infected with its own decay and the effect lasts forever. - target.worldObj.spawnEntityInWorld(new EntityDecay(target.worldObj, target.posX, target.posY, target.posZ, target)); - } - } + public void performEffect(EntityLivingBase entitylivingbase, int strength) { + entitylivingbase.attackEntityFrom(DamageSource.wither, 1); } @Override - @SideOnly(Side.CLIENT) public void renderInventoryEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc) { - mc.renderEngine.bindTexture(ICON); - WizardryUtilities.drawTexturedRect(x + 6, y + 7, 0, 0, 18, 18, 18, 18); + + mc.renderEngine.bindTexture(potionIcon); + this.drawTexturedRect(x + 6, y + 7, 0, 0, 18, 18, 18, 18); + } - @Override - @SideOnly(Side.CLIENT) - public void renderHUDEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc, float alpha) { - mc.renderEngine.bindTexture(ICON); - WizardryUtilities.drawTexturedRect(x + 3, y + 3, 0, 0, 18, 18, 18, 18); + /** + * Draws a textured rectangle, taking the size of the image and the bit needed into account. Client side only, of course. + * @param x The x position of the rectangle + * @param y The y position of the rectangle + * @param u The x position of the top left corner of the section of the image wanted + * @param v The y position of the top left corner of the section of the image wanted + * @param width The width of the section + * @param height The height of the section + * @param textureWidth The width of the actual image. + * @param textureHeight The height of the actual image. + */ + public static void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight) + { + float f = 1F / (float)textureWidth; + float f1 = 1F / (float)textureHeight; + net.minecraft.client.renderer.Tessellator tessellator = net.minecraft.client.renderer.Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV((double)(x), (double)(y + height), 0, (double)((float)(u) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y + height), 0, (double)((float)(u + width) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y), 0, (double)((float)(u + width) * f), (double)((float)(v) * f1)); + tessellator.addVertexWithUV((double)(x), (double)(y), 0, (double)((float)(u) * f), (double)((float)(v) * f1)); + tessellator.draw(); } } diff --git a/src/main/java/electroblob/wizardry/potion/PotionFrost.java b/src/main/java/electroblob/wizardry/potion/PotionFrost.java index 152adfab..9953f4c6 100644 --- a/src/main/java/electroblob/wizardry/potion/PotionFrost.java +++ b/src/main/java/electroblob/wizardry/potion/PotionFrost.java @@ -1,66 +1,59 @@ package electroblob.wizardry.potion; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Constants; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; -import net.minecraftforge.event.entity.player.PlayerEvent.BreakSpeed; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -@Mod.EventBusSubscriber -public class PotionFrost extends Potion implements ICustomPotionParticles { +public class PotionFrost extends Potion { - private static final ResourceLocation ICON = new ResourceLocation(Wizardry.MODID, "textures/gui/frost_icon.png"); + private static final ResourceLocation potionIcon = new ResourceLocation(Wizardry.MODID, "textures/gui/frost_icon.png"); - public PotionFrost(boolean isBadEffect, int liquidColour) { - super(isBadEffect, liquidColour); - // This needs to be here because registerPotionAttributeModifier doesn't like it if the potion has no name yet. - this.setPotionName("potion.wizardry:frost"); + public PotionFrost(int id, boolean isBadEffect, int liquidColour) { + super(id, isBadEffect, liquidColour); + this.setPotionName("potion.frost"); // With -0.5 as the 'amount', frost 1 slows the entity down by a half and frost 2 roots it to the spot - this.registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED, "35dded48-2f19-4541-8510-b29e2dc2cd51", -Constants.FROST_SLOWNESS_PER_LEVEL, 2); - // More UUIDs: 85602e0b-4801-4a87-94f3-bf617c97014e + this.func_111184_a(SharedMonsterAttributes.movementSpeed, "35dded48-2f19-4541-8510-b29e2dc2cd51", -Wizardry.FROST_SLOWNESS_PER_LEVEL, 2); + //More UUIDs: 85602e0b-4801-4a87-94f3-bf617c97014e } @Override public void performEffect(EntityLivingBase entitylivingbase, int strength) { // Nothing here because this potion works on attribute modifiers. } - - @Override - public void spawnCustomParticle(World world, double x, double y, double z) { - Wizardry.proxy.spawnParticle(WizardryParticleType.SNOW, world, x, y, z, 0, -0.02, 0, 15 + world.rand.nextInt(5)); - } @Override - @SideOnly(Side.CLIENT) public void renderInventoryEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc) { - mc.renderEngine.bindTexture(ICON); - WizardryUtilities.drawTexturedRect(x + 6, y + 7, 0, 0, 18, 18, 18, 18); + + mc.renderEngine.bindTexture(potionIcon); + this.drawTexturedRect(x + 6, y + 7, 0, 0, 18, 18, 18, 18); + } - @Override - @SideOnly(Side.CLIENT) - public void renderHUDEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc, float alpha) { - mc.renderEngine.bindTexture(ICON); - WizardryUtilities.drawTexturedRect(x + 3, y + 3, 0, 0, 18, 18, 18, 18); - } - - @SubscribeEvent - public static void onBreakSpeedEvent(BreakSpeed event){ - if(event.getEntityPlayer().isPotionActive(WizardryPotions.frost)){ - // Amplifier + 1 because it starts at 0 - event.setNewSpeed(event.getOriginalSpeed() * (1 - Constants.FROST_FATIGUE_PER_LEVEL*(event.getEntityPlayer().getActivePotionEffect(WizardryPotions.frost).getAmplifier() + 1))); - } + /** + * Draws a textured rectangle, taking the size of the image and the bit needed into account. Client side only, of course. + * @param x The x position of the rectangle + * @param y The y position of the rectangle + * @param u The x position of the top left corner of the section of the image wanted + * @param v The y position of the top left corner of the section of the image wanted + * @param width The width of the section + * @param height The height of the section + * @param textureWidth The width of the actual image. + * @param textureHeight The height of the actual image. + */ + public static void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight) + { + float f = 1F / (float)textureWidth; + float f1 = 1F / (float)textureHeight; + net.minecraft.client.renderer.Tessellator tessellator = net.minecraft.client.renderer.Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV((double)(x), (double)(y + height), 0, (double)((float)(u) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y + height), 0, (double)((float)(u + width) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y), 0, (double)((float)(u + width) * f), (double)((float)(v) * f1)); + tessellator.addVertexWithUV((double)(x), (double)(y), 0, (double)((float)(u) * f), (double)((float)(v) * f1)); + tessellator.draw(); } } diff --git a/src/main/java/electroblob/wizardry/potion/PotionMagicEffect.java b/src/main/java/electroblob/wizardry/potion/PotionMagicEffect.java index bba9a646..f31df1b9 100644 --- a/src/main/java/electroblob/wizardry/potion/PotionMagicEffect.java +++ b/src/main/java/electroblob/wizardry/potion/PotionMagicEffect.java @@ -1,22 +1,21 @@ package electroblob.wizardry.potion; +import org.lwjgl.opengl.GL11; + import electroblob.wizardry.Wizardry; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -/** Class for all potions that work on events only. */ public class PotionMagicEffect extends Potion { - private static final ResourceLocation ICONS = new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons.png"); + private static final ResourceLocation potionIcons = new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons.png"); private final int textureIndex; - public PotionMagicEffect(boolean isBadEffect, int liquidColour, int textureIndex) { - super(isBadEffect, liquidColour); + public PotionMagicEffect(int id, boolean isBadEffect, int liquidColour, int textureIndex) { + super(id, isBadEffect, liquidColour); this.textureIndex = textureIndex; } @@ -26,17 +25,42 @@ public class PotionMagicEffect extends Potion { } @Override - @SideOnly(Side.CLIENT) - public void renderInventoryEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc){ - mc.renderEngine.bindTexture(ICONS); - WizardryUtilities.drawTexturedRect(x + 6, y + 7, 18*(textureIndex%4), 18*(textureIndex/4), 18, 18, 72, 72); + public void renderInventoryEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc) { + + GL11.glPushMatrix(); + GL11.glEnable(GL11.GL_BLEND); + GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + + mc.renderEngine.bindTexture(potionIcons); + this.drawTexturedRect(x + 6, y + 7, 18*(textureIndex%4), 18*(textureIndex/4), 18, 18, 72, 72); + + GL11.glDisable(GL11.GL_BLEND); + GL11.glPopMatrix(); + } - @Override - @SideOnly(Side.CLIENT) - public void renderHUDEffect(int x, int y, PotionEffect effect, net.minecraft.client.Minecraft mc, float alpha) { - mc.renderEngine.bindTexture(ICONS); - WizardryUtilities.drawTexturedRect(x + 3, y + 3, 18*(textureIndex%4), 18*(textureIndex/4), 18, 18, 72, 72); + /** + * Draws a textured rectangle, taking the size of the image and the bit needed into account. Client side only, of course. + * @param x The x position of the rectangle + * @param y The y position of the rectangle + * @param u The x position of the top left corner of the section of the image wanted + * @param v The y position of the top left corner of the section of the image wanted + * @param width The width of the section + * @param height The height of the section + * @param textureWidth The width of the actual image. + * @param textureHeight The height of the actual image. + */ + public static void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight) + { + float f = 1F / (float)textureWidth; + float f1 = 1F / (float)textureHeight; + net.minecraft.client.renderer.Tessellator tessellator = net.minecraft.client.renderer.Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV((double)(x), (double)(y + height), 0, (double)((float)(u) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y + height), 0, (double)((float)(u + width) * f), (double)((float)(v + height) * f1)); + tessellator.addVertexWithUV((double)(x + width), (double)(y), 0, (double)((float)(u + width) * f), (double)((float)(v) * f1)); + tessellator.addVertexWithUV((double)(x), (double)(y), 0, (double)((float)(u) * f), (double)((float)(v) * f1)); + tessellator.draw(); } } diff --git a/src/main/java/electroblob/wizardry/potion/PotionMagicEffectParticles.java b/src/main/java/electroblob/wizardry/potion/PotionMagicEffectParticles.java deleted file mode 100644 index b9eac023..00000000 --- a/src/main/java/electroblob/wizardry/potion/PotionMagicEffectParticles.java +++ /dev/null @@ -1,11 +0,0 @@ -package electroblob.wizardry.potion; - -/** Same as {@link PotionMagicEffect}, but also implements {@link ICustomPotionParticles} to allow anonymous classes - * to extend it and add their own particles. */ -public abstract class PotionMagicEffectParticles extends PotionMagicEffect implements ICustomPotionParticles { - - public PotionMagicEffectParticles(boolean isBadEffect, int liquidColour, int textureIndex){ - super(isBadEffect, liquidColour, textureIndex); - } - -} diff --git a/src/main/java/electroblob/wizardry/registry/Spells.java b/src/main/java/electroblob/wizardry/registry/Spells.java deleted file mode 100644 index a59e7538..00000000 --- a/src/main/java/electroblob/wizardry/registry/Spells.java +++ /dev/null @@ -1,352 +0,0 @@ -package electroblob.wizardry.registry; - -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.spell.*; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.registry.GameRegistry.ObjectHolder; -import net.minecraftforge.fml.common.registry.IForgeRegistry; -import net.minecraftforge.fml.common.registry.RegistryBuilder; - -/** - * Class responsible for defining, storing and registering all of wizardry's spells. - * @author Electroblob - * @since Wizardry 2.1 - */ -// In case anyone was wondering, the reason @ObjectHolder is useful within one mod is that it allows you to initialise -// stuff during the registry events (or whenever), whilst still having a final field (which is important, not only -// because it makes the text go bold, but also because it stops anyone fiddling with your fields). "Why would I want to -// initialise things within the registry events?", I hear you ask - well, for one, custom registries don't like it if -// you haven't created the registry before you start calling constructors of classes extending IForgeRegistryEntry.Impl, -// and secondly, -@ObjectHolder(Wizardry.MODID) -@Mod.EventBusSubscriber -public final class Spells { - - // This is here because this class is already an event handler. - @SubscribeEvent - public static void createRegistry(RegistryEvent.NewRegistry event){ - - // Beats me why we need both of these. Surely the type parameter means it already knows? - RegistryBuilder builder = new RegistryBuilder(); - builder.setType(Spell.class); - builder.setName(new ResourceLocation(Wizardry.MODID, "spells")); - builder.setIDRange(0, 5000); // Is there any penalty for using a larger number? - - Spell.registry = builder.create(); - } - - // Wizardry 1.0 spells - - public static final Spell none = null; - public static final Spell magic_missile = null; - public static final Spell ignite = null; - public static final Spell freeze = null; - public static final Spell snowball = null; - public static final Spell arc = null; - public static final Spell thunderbolt = null; - public static final Spell summon_zombie = null; - public static final Spell snare = null; - public static final Spell dart = null; - public static final Spell light = null; - public static final Spell telekinesis = null; - public static final Spell heal = null; - - public static final Spell fireball = null; - public static final Spell flame_ray = null; - public static final Spell firebomb = null; - public static final Spell fire_sigil = null; - public static final Spell firebolt = null; - public static final Spell frost_ray = null; - public static final Spell summon_snow_golem = null; - public static final Spell ice_shard = null; - public static final Spell ice_statue = null; - public static final Spell frost_sigil = null; - public static final Spell lightning_ray = null; - public static final Spell spark_bomb = null; - public static final Spell homing_spark = null; - public static final Spell lightning_sigil = null; - public static final Spell lightning_arrow = null; - public static final Spell life_drain = null; - public static final Spell summon_skeleton = null; - public static final Spell metamorphosis = null; - public static final Spell wither = null; - public static final Spell poison = null; - public static final Spell growth_aura = null; - public static final Spell bubble = null; - public static final Spell whirlwind = null; - public static final Spell poison_bomb = null; - public static final Spell summon_spirit_wolf = null; - public static final Spell blink = null; - public static final Spell agility = null; - public static final Spell conjure_sword = null; - public static final Spell conjure_pickaxe = null; - public static final Spell conjure_bow = null; - public static final Spell force_arrow = null; - public static final Spell shield = null; - public static final Spell replenish_hunger = null; - public static final Spell cure_effects = null; - public static final Spell heal_ally = null; - - public static final Spell summon_blaze = null; - public static final Spell ring_of_fire = null; - public static final Spell detonate = null; - public static final Spell fire_resistance = null; - public static final Spell fireskin = null; - public static final Spell flaming_axe = null; - public static final Spell blizzard = null; - public static final Spell summon_ice_wraith = null; - public static final Spell ice_shroud = null; - public static final Spell ice_charge = null; - public static final Spell frost_axe = null; - public static final Spell invoke_weather = null; - public static final Spell chain_lightning = null; - public static final Spell lightning_bolt = null; - public static final Spell summon_lightning_wraith = null; - public static final Spell static_aura = null; - public static final Spell lightning_disc = null; - public static final Spell mind_control = null; - public static final Spell summon_wither_skeleton = null; - public static final Spell entrapment = null; - public static final Spell wither_skull = null; - public static final Spell darkness_orb = null; - public static final Spell shadow_ward = null; - public static final Spell decay = null; - public static final Spell water_breathing = null; - public static final Spell tornado = null; - public static final Spell glide = null; - public static final Spell summon_spirit_horse = null; - public static final Spell spider_swarm = null; - public static final Spell slime = null; - public static final Spell petrify = null; - public static final Spell invisibility = null; - public static final Spell levitation = null; - public static final Spell force_orb = null; - public static final Spell transportation = null; - public static final Spell spectral_pathway = null; - public static final Spell phase_step = null; - public static final Spell vanishing_box = null; - public static final Spell greater_heal = null; - public static final Spell healing_aura = null; - public static final Spell forcefield = null; - public static final Spell ironflesh = null; - public static final Spell transience = null; - - public static final Spell meteor = null; - public static final Spell firestorm = null; - public static final Spell summon_phoenix = null; - public static final Spell ice_age = null; - public static final Spell wall_of_frost = null; - public static final Spell summon_ice_giant = null; - public static final Spell thunderstorm = null; - public static final Spell lightning_hammer = null; - public static final Spell plague_of_darkness = null; - public static final Spell summon_skeleton_legion = null; - public static final Spell summon_shadow_wraith = null; - public static final Spell forests_curse = null; - public static final Spell flight = null; - public static final Spell silverfish_swarm = null; - public static final Spell black_hole = null; - public static final Spell shockwave = null; - public static final Spell summon_iron_golem = null; - public static final Spell arrow_rain = null; - public static final Spell diamondflesh = null; - public static final Spell font_of_vitality = null; - - // Wizardry 1.1 spells - - public static final Spell smoke_bomb = null; - public static final Spell mind_trick = null; - public static final Spell leap = null; - - public static final Spell pocket_furnace = null; - public static final Spell intimidate = null; - public static final Spell banish = null; - public static final Spell sixth_sense = null; - public static final Spell darkvision = null; - public static final Spell clairvoyance = null; - public static final Spell pocket_workbench = null; - public static final Spell imbue_weapon = null; - public static final Spell invigorating_presence = null; - public static final Spell oakflesh = null; - - public static final Spell greater_fireball = null; - public static final Spell flaming_weapon = null; - public static final Spell ice_lance = null; - public static final Spell freezing_weapon = null; - public static final Spell ice_spikes = null; - public static final Spell lightning_pulse = null; - public static final Spell curse_of_soulbinding = null; - public static final Spell cobwebs = null; - public static final Spell decoy = null; - public static final Spell arcane_jammer = null; - public static final Spell conjure_armour = null; - public static final Spell group_heal = null; - - public static final Spell hailstorm = null; - public static final Spell lightning_web = null; - public static final Spell summon_storm_elemental = null; - public static final Spell earthquake = null; - public static final Spell font_of_mana = null; - - @SubscribeEvent - public static void register(RegistryEvent.Register event){ - - IForgeRegistry registry = event.getRegistry(); - - // event.getRegistry should always equal Spell.registry. - registry.register(new None()); - registry.register(new MagicMissile()); - registry.register(new Ignite()); - registry.register(new Freeze()); - registry.register(new Snowball()); - registry.register(new Arc()); - registry.register(new Thunderbolt()); - registry.register(new SummonZombie()); - registry.register(new Snare()); - registry.register(new Dart()); - registry.register(new Light()); - registry.register(new Telekinesis()); - registry.register(new Heal()); - - registry.register(new Fireball()); - registry.register(new FlameRay()); - registry.register(new Firebomb()); - registry.register(new FireSigil()); - registry.register(new Firebolt()); - registry.register(new FrostRay()); - registry.register(new SummonSnowGolem()); - registry.register(new IceShard()); - registry.register(new IceStatue()); - registry.register(new FrostSigil()); - registry.register(new LightningRay()); - registry.register(new SparkBomb()); - registry.register(new HomingSpark()); - registry.register(new LightningSigil()); - registry.register(new LightningArrow()); - registry.register(new LifeDrain()); - registry.register(new SummonSkeleton()); - registry.register(new Metamorphosis()); - registry.register(new Wither()); - registry.register(new Poison()); - registry.register(new GrowthAura()); - registry.register(new Bubble()); - registry.register(new Whirlwind()); - registry.register(new PoisonBomb()); - registry.register(new SummonSpiritWolf()); - registry.register(new Blink()); - registry.register(new Agility()); - registry.register(new ConjureSword()); - registry.register(new ConjurePickaxe()); - registry.register(new ConjureBow()); - registry.register(new ForceArrow()); - registry.register(new Shield()); - registry.register(new ReplenishHunger()); - registry.register(new CureEffects()); - registry.register(new HealAlly()); - - registry.register(new SummonBlaze()); - registry.register(new RingOfFire()); - registry.register(new Detonate()); - registry.register(new FireResistance()); - registry.register(new Fireskin()); - registry.register(new FlamingAxe()); - registry.register(new Blizzard()); - registry.register(new SummonIceWraith()); - registry.register(new IceShroud()); - registry.register(new IceCharge()); - registry.register(new FrostAxe()); - registry.register(new InvokeWeather()); - registry.register(new ChainLightning()); - registry.register(new LightningBolt()); - registry.register(new SummonLightningWraith()); - registry.register(new StaticAura()); - registry.register(new LightningDisc()); - registry.register(new MindControl()); - registry.register(new SummonWitherSkeleton()); - registry.register(new Entrapment()); - registry.register(new WitherSkull()); - registry.register(new DarknessOrb()); - registry.register(new ShadowWard()); - registry.register(new Decay()); - registry.register(new WaterBreathing()); - registry.register(new Tornado()); - registry.register(new Glide()); - registry.register(new SummonSpiritHorse()); - registry.register(new SpiderSwarm()); - registry.register(new Slime()); - registry.register(new Petrify()); - registry.register(new Invisibility()); - registry.register(new Levitation()); - registry.register(new ForceOrb()); - registry.register(new Transportation()); - registry.register(new SpectralPathway()); - registry.register(new PhaseStep()); - registry.register(new VanishingBox()); - registry.register(new GreaterHeal()); - registry.register(new HealingAura()); - registry.register(new Forcefield()); - registry.register(new Ironflesh()); - registry.register(new Transience()); - - registry.register(new Meteor()); - registry.register(new Firestorm()); - registry.register(new SummonPhoenix()); - registry.register(new IceAge()); - registry.register(new WallOfFrost()); - registry.register(new SummonIceGiant()); - registry.register(new Thunderstorm()); - registry.register(new LightningHammer()); - registry.register(new PlagueOfDarkness()); - registry.register(new SummonSkeletonLegion()); - registry.register(new SummonShadowWraith()); - registry.register(new ForestsCurse()); - registry.register(new Flight()); - registry.register(new SilverfishSwarm()); - registry.register(new BlackHole()); - registry.register(new Shockwave()); - registry.register(new SummonIronGolem()); - registry.register(new ArrowRain()); - registry.register(new Diamondflesh()); - registry.register(new FontOfVitality()); - - // Wizardry 1.1 spells - - registry.register(new SmokeBomb()); - registry.register(new MindTrick()); - registry.register(new Leap()); - - registry.register(new PocketFurnace()); - registry.register(new Intimidate()); - registry.register(new Banish()); - registry.register(new SixthSense()); - registry.register(new Darkvision()); - registry.register(new Clairvoyance()); - registry.register(new PocketWorkbench()); - registry.register(new ImbueWeapon()); - registry.register(new InvigoratingPresence()); - registry.register(new Oakflesh()); - - registry.register(new GreaterFireball()); - registry.register(new FlamingWeapon()); - registry.register(new IceLance()); - registry.register(new FreezingWeapon()); - registry.register(new IceSpikes()); - registry.register(new LightningPulse()); - registry.register(new CurseOfSoulbinding()); - registry.register(new Cobwebs()); - registry.register(new Decoy()); - registry.register(new ArcaneJammer()); - registry.register(new ConjureArmour()); - registry.register(new GroupHeal()); - - registry.register(new Hailstorm()); - registry.register(new LightningWeb()); - registry.register(new SummonStormElemental()); - registry.register(new Earthquake()); - registry.register(new FontOfMana()); - } - -} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/registry/WizardryAchievements.java b/src/main/java/electroblob/wizardry/registry/WizardryAchievements.java deleted file mode 100644 index 2e3ab165..00000000 --- a/src/main/java/electroblob/wizardry/registry/WizardryAchievements.java +++ /dev/null @@ -1,47 +0,0 @@ -package electroblob.wizardry.registry; - -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.stats.Achievement; -import net.minecraftforge.common.AchievementPage; - -/** - * Class responsible for defining, storing and registering all of wizardry's achievements (achievements don't have a - * registry, but it make sense to do them the same way as everything else). - * @author Electroblob - * @since Wizardry 2.1 - */ -public final class WizardryAchievements { - - public static final Achievement crystal = new Achievement("crystal", "crystal", -1, -1, WizardryItems.magic_crystal, null).registerStat(); - public static final Achievement arcane_initiate = new Achievement("arcane_initiate", "arcane_initiate", 2, -1, WizardryItems.magic_wand, crystal).registerStat(); - public static final Achievement apprentice = new Achievement("apprentice", "apprentice", 2, 3, WizardryItems.apprentice_wand, arcane_initiate).registerStat(); - public static final Achievement master = new Achievement("master", "master", 3, 6, WizardryItems.master_wand, apprentice).registerStat(); - public static final Achievement all_spells = new Achievement("all_spells", "all_spells", 5, 7, WizardryItems.wizard_handbook, master).registerStat().setSpecial(); - public static final Achievement wizard_trade = new Achievement("wizard_trade", "wizard_trade", 2, -5, Items.EMERALD, arcane_initiate).registerStat(); - public static final Achievement buy_master_spell = new Achievement("buy_master_spell", "buy_master_spell", 5, -5, WizardryItems.spell_book, wizard_trade).registerStat().setSpecial(); - public static final Achievement freeze_blaze = new Achievement("freeze_blaze", "freeze_blaze", -1, 3, Blocks.ICE, apprentice).registerStat(); - public static final Achievement charge_creeper = new Achievement("charge_creeper", "charge_creeper", -1, 1, Items.GUNPOWDER, arcane_initiate).registerStat(); - public static final Achievement frankenstein = new Achievement("frankenstein", "frankenstein", -3, 1, WizardryItems.advanced_lightning_wand, charge_creeper).registerStat().setSpecial(); - public static final Achievement special_upgrade = new Achievement("special_upgrade", "special_upgrade", 4, 1, WizardryItems.condenser_upgrade, arcane_initiate).registerStat(); - public static final Achievement craft_flask = new Achievement("craft_flask", "craft_flask", 4, -2, WizardryItems.mana_flask, arcane_initiate).registerStat(); - public static final Achievement elemental = new Achievement("elemental", "elemental", 6, -1, WizardryItems.basic_fire_wand, arcane_initiate).registerStat(); - public static final Achievement armour_set = new Achievement("armour_set", "armour_set", 0, -4, WizardryItems.wizard_hat, arcane_initiate).registerStat(); - public static final Achievement legendary = new Achievement("legendary", "legendary", -2, -5, WizardryItems.armour_upgrade, armour_set).registerStat().setSpecial(); - public static final Achievement self_destruct = new Achievement("self_destruct", "self_destruct", 1, 0, Blocks.PUMPKIN, arcane_initiate).registerStat(); - public static final Achievement pig_tornado = new Achievement("pig_tornado", "pig_tornado", 6, 3, Items.SADDLE, apprentice).registerStat().setSpecial(); - public static final Achievement jam_wizard = new Achievement("jam_wizard", "jam_wizard", 4, 4, Blocks.WEB, apprentice).registerStat(); - public static final Achievement slime_skeleton = new Achievement("slime_skeleton", "slime_skeleton", 1, 5, Items.SLIME_BALL, apprentice).registerStat(); - public static final Achievement anger_wizard = new Achievement("anger_wizard", "anger_wizard", 1, -7, Items.IRON_SWORD, wizard_trade).registerStat(); - public static final Achievement defeat_evil_wizard = new Achievement("defeat_evil_wizard", "defeat_evil_wizard", 4, -7, WizardryItems.wizard_boots_necromancy, wizard_trade).registerStat(); - public static final Achievement max_out_wand = new Achievement("max_out_wand", "max_out_wand", 7, 1, WizardryItems.arcane_tome, special_upgrade).registerStat().setSpecial(); - public static final Achievement element_master = new Achievement("element_master", "element_master", 7, -3, WizardryItems.master_ice_wand, elemental).registerStat().setSpecial(); - public static final Achievement identify_spell = new Achievement("identify_spell", "identify_spell", -2, -3, WizardryItems.identification_scroll, arcane_initiate).registerStat(); - - private static final Achievement[] ACHIEVEMENTS_LIST = {crystal, arcane_initiate, apprentice, master, all_spells, wizard_trade, buy_master_spell, freeze_blaze, charge_creeper, - frankenstein, special_upgrade, craft_flask, elemental, armour_set, legendary, self_destruct, pig_tornado, jam_wizard, slime_skeleton, anger_wizard, defeat_evil_wizard, - max_out_wand, element_master, identify_spell}; - - public static final AchievementPage WIZARDRY_ACHIEVEMENT_PAGE = new AchievementPage("Wizardry", ACHIEVEMENTS_LIST); - -} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/registry/WizardryBlocks.java b/src/main/java/electroblob/wizardry/registry/WizardryBlocks.java deleted file mode 100644 index b1efa21a..00000000 --- a/src/main/java/electroblob/wizardry/registry/WizardryBlocks.java +++ /dev/null @@ -1,92 +0,0 @@ -package electroblob.wizardry.registry; - -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.block.BlockArcaneWorkbench; -import electroblob.wizardry.block.BlockCrystalFlower; -import electroblob.wizardry.block.BlockCrystalOre; -import electroblob.wizardry.block.BlockMagicLight; -import electroblob.wizardry.block.BlockSnare; -import electroblob.wizardry.block.BlockSpectral; -import electroblob.wizardry.block.BlockStatue; -import electroblob.wizardry.block.BlockTransportationStone; -import electroblob.wizardry.block.BlockVanishingCobweb; -import net.minecraft.block.Block; -import net.minecraft.block.material.Material; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.registry.IForgeRegistry; - -/** - * Class responsible for defining, storing and registering all of wizardry's blocks. - * @author Electroblob - * @since Wizardry 2.1 - */ -@Mod.EventBusSubscriber -public final class WizardryBlocks { - - // I get registry events, they make sense - even I doubted myself with when to do various things in the load process, - // so I can see why the folks at Forge wanted to save us having to think about it. - // What I do not understand is why you would use @ObjectHolder for your own blocks and items. What's the point in - // making your code longer and more complicated, when you can just define the blocks as constants and register them - // later? - - // Found a very nice way of registering things using arrays, which might make @ObjectHolder actually useful. - // http://www.minecraftforge.net/forum/topic/49497-1112-is-using-registryevent-this-way-ok/ - - // Anything set to use the material 'air' will not render, even with a TESR! - - // setSoundType should be public, but in this particular version it isn't... which is a bit of a pain. - - public static final Block arcane_workbench = new BlockArcaneWorkbench().setHardness(1.0F).setCreativeTab(WizardryTabs.WIZARDRY); - public static final Block crystal_ore = new BlockCrystalOre(Material.ROCK).setHardness(3.0F).setCreativeTab(WizardryTabs.WIZARDRY); - public static final Block petrified_stone = new BlockStatue(Material.ROCK).setHardness(1.5F).setResistance(10.0F); - public static final Block ice_statue = new BlockStatue(Material.ICE).setHardness(0.5F).setLightOpacity(3); - public static final Block magic_light = new BlockMagicLight(Material.CIRCUITS); - public static final Block crystal_flower = new BlockCrystalFlower(Material.PLANTS).setHardness(0.0F).setCreativeTab(WizardryTabs.WIZARDRY); - public static final Block snare = new BlockSnare(Material.PLANTS).setHardness(0.0F); - public static final Block transportation_stone = new BlockTransportationStone(Material.ROCK).setHardness(0.0F).setLightLevel(0.5f).setLightOpacity(0).setCreativeTab(WizardryTabs.WIZARDRY); - public static final Block spectral_block = new BlockSpectral(Material.GLASS).setLightLevel(0.7f).setLightOpacity(0).setBlockUnbreakable().setResistance(6000000.0F); - public static final Block crystal_block = new Block(Material.IRON).setHardness(5.0F).setResistance(10.0F).setCreativeTab(WizardryTabs.WIZARDRY); - public static final Block meteor = new Block(Material.ROCK).setLightLevel(1); - public static final Block vanishing_cobweb = new BlockVanishingCobweb(Material.WEB).setLightOpacity(1).setHardness(4.0F); - - static { - // This is here because Block#setHarvestLevel isn't chainable. - crystal_block.setHarvestLevel("pickaxe", 2); - } - - /** - * Sets both the registry and unlocalised names of the given block, then registers it with the given registry. Use - * this instead of {@link Block#setRegistryName(String)} and {@link Block#setUnlocalizedName(String)} during - * construction, for convenience and consistency. - * @param registry The registry to register the given block to. - * @param item The block to register. - * @param name The name of the block, without the mod ID or the .name stuff. The registry name will be - * {@code wizardry:[name]}. The unlocalised name will be {@code tile.wizardry:[name].name}. - */ - public static void registerBlock(IForgeRegistry registry, Block block, String name){ - block.setRegistryName(Wizardry.MODID, name); - block.setUnlocalizedName(block.getRegistryName().toString()); - registry.register(block); - } - - @SubscribeEvent - public static void register(RegistryEvent.Register event){ - - IForgeRegistry registry = event.getRegistry(); - - registerBlock(registry, arcane_workbench, "arcane_workbench"); - registerBlock(registry, crystal_ore, "crystal_ore"); - registerBlock(registry, petrified_stone, "petrified_stone"); - registerBlock(registry, ice_statue, "ice_statue"); - registerBlock(registry, magic_light, "magic_light"); - registerBlock(registry, crystal_flower, "crystal_flower"); - registerBlock(registry, snare, "snare"); - registerBlock(registry, transportation_stone, "transportation_stone"); - registerBlock(registry, spectral_block, "spectral_block"); - registerBlock(registry, crystal_block, "crystal_block"); - registerBlock(registry, meteor, "meteor"); - registerBlock(registry, vanishing_cobweb, "vanishing_cobweb"); - } -} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/registry/WizardryEnchantments.java b/src/main/java/electroblob/wizardry/registry/WizardryEnchantments.java deleted file mode 100644 index e34ca427..00000000 --- a/src/main/java/electroblob/wizardry/registry/WizardryEnchantments.java +++ /dev/null @@ -1,41 +0,0 @@ -package electroblob.wizardry.registry; - -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.enchantment.EnchantmentMagicSword; -import electroblob.wizardry.enchantment.EnchantmentTimed; -import net.minecraft.enchantment.Enchantment; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; - -/** - * Class responsible for defining, storing and registering all of wizardry's enchantments. - * @author Electroblob - * @since Wizardry 2.1 - */ -@Mod.EventBusSubscriber -public final class WizardryEnchantments { - - // At the moment these enchantments generate on books in dungeon chests due to a bad bit of code (EnchantRandomly:50). - // No idea how to fix this because I have no way of hooking into that code... removing the enchantments from the - // registry works, but breaks everything else! - - // TODO: For the time being, a dynamic solution will have to do, i.e. intercept the book when it is generated and - // reassign its enchantment. - - // All of these have custom classes, so the unlocalised name (referred to simply as 'name' for enchantments) is - // dealt with inside those classes. - public static final Enchantment magic_sword = new EnchantmentMagicSword().setRegistryName(Wizardry.MODID, "magic_sword"); - public static final Enchantment magic_bow = new EnchantmentTimed().setRegistryName(Wizardry.MODID, "magic_bow"); - public static final Enchantment flaming_weapon = new EnchantmentTimed().setRegistryName(Wizardry.MODID, "flaming_weapon"); - public static final Enchantment freezing_weapon = new EnchantmentTimed().setRegistryName(Wizardry.MODID, "freezing_weapon"); - - @SubscribeEvent - public static void register(RegistryEvent.Register event){ - event.getRegistry().register(magic_sword); - event.getRegistry().register(magic_bow); - event.getRegistry().register(flaming_weapon); - event.getRegistry().register(freezing_weapon); - } - -} diff --git a/src/main/java/electroblob/wizardry/registry/WizardryItems.java b/src/main/java/electroblob/wizardry/registry/WizardryItems.java deleted file mode 100644 index 89b053dd..00000000 --- a/src/main/java/electroblob/wizardry/registry/WizardryItems.java +++ /dev/null @@ -1,419 +0,0 @@ -package electroblob.wizardry.registry; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; - -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.item.ItemArcaneTome; -import electroblob.wizardry.item.ItemArmourUpgrade; -import electroblob.wizardry.item.ItemFirebomb; -import electroblob.wizardry.item.ItemFlamingAxe; -import electroblob.wizardry.item.ItemFrostAxe; -import electroblob.wizardry.item.ItemIdentificationScroll; -import electroblob.wizardry.item.ItemPoisonBomb; -import electroblob.wizardry.item.ItemScroll; -import electroblob.wizardry.item.ItemSmokeBomb; -import electroblob.wizardry.item.ItemSpectralArmour; -import electroblob.wizardry.item.ItemSpectralBow; -import electroblob.wizardry.item.ItemSpectralPickaxe; -import electroblob.wizardry.item.ItemSpectralSword; -import electroblob.wizardry.item.ItemSpellBook; -import electroblob.wizardry.item.ItemWand; -import electroblob.wizardry.item.ItemWizardArmour; -import electroblob.wizardry.item.ItemWizardHandbook; -import net.minecraft.block.Block; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; -import net.minecraft.inventory.EntityEquipmentSlot; -import net.minecraft.item.Item; -import net.minecraft.item.Item.ToolMaterial; -import net.minecraft.item.ItemArmor.ArmorMaterial; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.world.World; -import net.minecraftforge.common.util.EnumHelper; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.registry.IForgeRegistry; - -/** - * Class responsible for defining, storing and registering all of wizardry's items. Also registers the ItemBlocks for - * wizardry's blocks. - * @author Electroblob - * @since Wizardry 2.1 - */ -@Mod.EventBusSubscriber -public final class WizardryItems { - - public static final Item magic_crystal = new Item().setCreativeTab(WizardryTabs.WIZARDRY); - - public static final Item magic_wand = new ItemWand(Tier.BASIC, null); - public static final Item apprentice_wand = new ItemWand(Tier.APPRENTICE, null); - public static final Item advanced_wand = new ItemWand(Tier.ADVANCED, null); - public static final Item master_wand = new ItemWand(Tier.MASTER, null); - - public static final Item arcane_tome = new ItemArcaneTome(); - public static final Item wizard_handbook = new ItemWizardHandbook(); - public static final Item spell_book = new ItemSpellBook(); - - public static final Item basic_fire_wand = new ItemWand(Tier.BASIC, Element.FIRE); - public static final Item basic_ice_wand = new ItemWand(Tier.BASIC, Element.ICE); - public static final Item basic_lightning_wand = new ItemWand(Tier.BASIC, Element.LIGHTNING); - public static final Item basic_necromancy_wand = new ItemWand(Tier.BASIC, Element.NECROMANCY); - public static final Item basic_earth_wand = new ItemWand(Tier.BASIC, Element.EARTH); - public static final Item basic_sorcery_wand = new ItemWand(Tier.BASIC, Element.SORCERY); - public static final Item basic_healing_wand = new ItemWand(Tier.BASIC, Element.HEALING); - - public static final Item apprentice_fire_wand = new ItemWand(Tier.APPRENTICE, Element.FIRE); - public static final Item apprentice_ice_wand = new ItemWand(Tier.APPRENTICE, Element.ICE); - public static final Item apprentice_lightning_wand = new ItemWand(Tier.APPRENTICE, Element.LIGHTNING); - public static final Item apprentice_necromancy_wand = new ItemWand(Tier.APPRENTICE, Element.NECROMANCY); - public static final Item apprentice_earth_wand = new ItemWand(Tier.APPRENTICE, Element.EARTH); - public static final Item apprentice_sorcery_wand = new ItemWand(Tier.APPRENTICE, Element.SORCERY); - public static final Item apprentice_healing_wand = new ItemWand(Tier.APPRENTICE, Element.HEALING); - - public static final Item advanced_fire_wand = new ItemWand(Tier.ADVANCED, Element.FIRE); - public static final Item advanced_ice_wand = new ItemWand(Tier.ADVANCED, Element.ICE); - public static final Item advanced_lightning_wand = new ItemWand(Tier.ADVANCED, Element.LIGHTNING); - public static final Item advanced_necromancy_wand = new ItemWand(Tier.ADVANCED, Element.NECROMANCY); - public static final Item advanced_earth_wand = new ItemWand(Tier.ADVANCED, Element.EARTH); - public static final Item advanced_sorcery_wand = new ItemWand(Tier.ADVANCED, Element.SORCERY); - public static final Item advanced_healing_wand = new ItemWand(Tier.ADVANCED, Element.HEALING); - - public static final Item master_fire_wand = new ItemWand(Tier.MASTER, Element.FIRE); - public static final Item master_ice_wand = new ItemWand(Tier.MASTER, Element.ICE); - public static final Item master_lightning_wand = new ItemWand(Tier.MASTER, Element.LIGHTNING); - public static final Item master_necromancy_wand = new ItemWand(Tier.MASTER, Element.NECROMANCY); - public static final Item master_earth_wand = new ItemWand(Tier.MASTER, Element.EARTH); - public static final Item master_sorcery_wand = new ItemWand(Tier.MASTER, Element.SORCERY); - public static final Item master_healing_wand = new ItemWand(Tier.MASTER, Element.HEALING); - - public static final Item spectral_sword = new ItemSpectralSword(ToolMaterial.IRON); - public static final Item spectral_pickaxe = new ItemSpectralPickaxe(ToolMaterial.IRON); - public static final Item spectral_bow = new ItemSpectralBow(); - - public static final Item mana_flask = new Item(){ - @Override - public void onCreated(ItemStack par1ItemStack, World par2World, EntityPlayer entityplayer){ - entityplayer.addStat(WizardryAchievements.craft_flask); - } - }.setCreativeTab(WizardryTabs.WIZARDRY); - - public static final Item storage_upgrade = new Item().setCreativeTab(WizardryTabs.WIZARDRY); - public static final Item siphon_upgrade = new Item().setCreativeTab(WizardryTabs.WIZARDRY); - public static final Item condenser_upgrade = new Item().setCreativeTab(WizardryTabs.WIZARDRY); - public static final Item range_upgrade = new Item().setCreativeTab(WizardryTabs.WIZARDRY); - public static final Item duration_upgrade = new Item().setCreativeTab(WizardryTabs.WIZARDRY); - public static final Item cooldown_upgrade = new Item().setCreativeTab(WizardryTabs.WIZARDRY); - public static final Item blast_upgrade = new Item().setCreativeTab(WizardryTabs.WIZARDRY); - public static final Item attunement_upgrade = new Item().setCreativeTab(WizardryTabs.WIZARDRY); - - public static final Item magic_silk = new Item().setCreativeTab(WizardryTabs.WIZARDRY); - - public static final Item.ToolMaterial MAGICAL = EnumHelper.addToolMaterial("MAGICAL", 3, 1000, 8.0f, 4.0f, 0); - - public static final Item flaming_axe = new ItemFlamingAxe(MAGICAL); - public static final Item frost_axe = new ItemFrostAxe(MAGICAL); - - public static final Item firebomb = new ItemFirebomb(); - public static final Item poison_bomb = new ItemPoisonBomb(); - - public static final Item blank_scroll = new Item().setCreativeTab(WizardryTabs.WIZARDRY); - public static final Item scroll = new ItemScroll().setCreativeTab(WizardryTabs.SPELLS); - - // The only way to get these is in dungeon chests (They are legendary, after all. Wizards don't just have them. - // Also if they were sold you could buy four from the same wizard - and that's no fun at all!) - public static final Item armour_upgrade = new ItemArmourUpgrade(); - - public static final ArmorMaterial SILK = EnumHelper.addArmorMaterial("SILK", "wizardry/textures/armour/wizard_armour", - 15, new int[]{2, 5, 4, 2}, 0, SoundEvents.ITEM_ARMOR_EQUIP_LEATHER, 0.0F); - // Saw a post somewhere that said you have to put these in the init methods rather than defining them as constants. - // I *think* that's because the post was for a newer Minecraft version, where custom armour has its own renderer or - // something, meaning it would be done a lot like the entity rendering registry in ClientProxy. This is all working - // fine it seems, so I'm not going to fiddle with it, but it might be useful to know if I update versions again. - public static final Item wizard_hat = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.HEAD, null); - public static final Item wizard_robe = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.CHEST, null); - public static final Item wizard_leggings = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.LEGS, null); - public static final Item wizard_boots = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.FEET, null); - - public static final Item wizard_hat_fire = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.HEAD, Element.FIRE); - public static final Item wizard_robe_fire = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.CHEST, Element.FIRE); - public static final Item wizard_leggings_fire = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.LEGS, Element.FIRE); - public static final Item wizard_boots_fire = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.FEET, Element.FIRE); - - public static final Item wizard_hat_ice = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.HEAD, Element.ICE); - public static final Item wizard_robe_ice = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.CHEST, Element.ICE); - public static final Item wizard_leggings_ice = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.LEGS, Element.ICE); - public static final Item wizard_boots_ice = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.FEET, Element.ICE); - - public static final Item wizard_hat_lightning = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.HEAD, Element.LIGHTNING); - public static final Item wizard_robe_lightning = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.CHEST, Element.LIGHTNING); - public static final Item wizard_leggings_lightning = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.LEGS, Element.LIGHTNING); - public static final Item wizard_boots_lightning = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.FEET, Element.LIGHTNING); - - public static final Item wizard_hat_necromancy = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.HEAD, Element.NECROMANCY); - public static final Item wizard_robe_necromancy = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.CHEST, Element.NECROMANCY); - public static final Item wizard_leggings_necromancy = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.LEGS, Element.NECROMANCY); - public static final Item wizard_boots_necromancy = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.FEET, Element.NECROMANCY); - - public static final Item wizard_hat_earth = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.HEAD, Element.EARTH); - public static final Item wizard_robe_earth = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.CHEST, Element.EARTH); - public static final Item wizard_leggings_earth = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.LEGS, Element.EARTH); - public static final Item wizard_boots_earth = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.FEET, Element.EARTH); - - public static final Item wizard_hat_sorcery = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.HEAD, Element.SORCERY); - public static final Item wizard_robe_sorcery = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.CHEST, Element.SORCERY); - public static final Item wizard_leggings_sorcery = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.LEGS, Element.SORCERY); - public static final Item wizard_boots_sorcery = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.FEET, Element.SORCERY); - - public static final Item wizard_hat_healing = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.HEAD, Element.HEALING); - public static final Item wizard_robe_healing = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.CHEST, Element.HEALING); - public static final Item wizard_leggings_healing = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.LEGS, Element.HEALING); - public static final Item wizard_boots_healing = new ItemWizardArmour(SILK, 1, EntityEquipmentSlot.FEET, Element.HEALING); - - public static final Item spectral_helmet = new ItemSpectralArmour(ArmorMaterial.IRON, 1, EntityEquipmentSlot.HEAD); - public static final Item spectral_chestplate = new ItemSpectralArmour(ArmorMaterial.IRON, 1, EntityEquipmentSlot.CHEST); - public static final Item spectral_leggings = new ItemSpectralArmour(ArmorMaterial.IRON, 1, EntityEquipmentSlot.LEGS); - public static final Item spectral_boots = new ItemSpectralArmour(ArmorMaterial.IRON, 1, EntityEquipmentSlot.FEET); - - public static final Item smoke_bomb = new ItemSmokeBomb(); - - public static final Item identification_scroll = new ItemIdentificationScroll(); - - public static final Map, Item> WAND_MAP = new HashMap<>(); - public static final Map, Item> ARMOUR_MAP = new HashMap<>(); - - static { - - WAND_MAP.put(ImmutablePair.of(Tier.BASIC, Element.MAGIC), magic_wand); - WAND_MAP.put(ImmutablePair.of(Tier.BASIC, Element.FIRE), basic_fire_wand); - WAND_MAP.put(ImmutablePair.of(Tier.BASIC, Element.ICE), basic_ice_wand); - WAND_MAP.put(ImmutablePair.of(Tier.BASIC, Element.LIGHTNING), basic_lightning_wand); - WAND_MAP.put(ImmutablePair.of(Tier.BASIC, Element.NECROMANCY), basic_necromancy_wand); - WAND_MAP.put(ImmutablePair.of(Tier.BASIC, Element.EARTH), basic_earth_wand); - WAND_MAP.put(ImmutablePair.of(Tier.BASIC, Element.SORCERY), basic_sorcery_wand); - WAND_MAP.put(ImmutablePair.of(Tier.BASIC, Element.HEALING), basic_healing_wand); - WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.MAGIC), apprentice_wand); - WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.FIRE), apprentice_fire_wand); - WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.ICE), apprentice_ice_wand); - WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.LIGHTNING), apprentice_lightning_wand); - WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.NECROMANCY), apprentice_necromancy_wand); - WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.EARTH), apprentice_earth_wand); - WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.SORCERY), apprentice_sorcery_wand); - WAND_MAP.put(ImmutablePair.of(Tier.APPRENTICE, Element.HEALING), apprentice_healing_wand); - WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.MAGIC), advanced_wand); - WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.FIRE), advanced_fire_wand); - WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.ICE), advanced_ice_wand); - WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.LIGHTNING), advanced_lightning_wand); - WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.NECROMANCY), advanced_necromancy_wand); - WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.EARTH), advanced_earth_wand); - WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.SORCERY), advanced_sorcery_wand); - WAND_MAP.put(ImmutablePair.of(Tier.ADVANCED, Element.HEALING), advanced_healing_wand); - WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.MAGIC), master_wand); - WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.FIRE), master_fire_wand); - WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.ICE), master_ice_wand); - WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.LIGHTNING), master_lightning_wand); - WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.NECROMANCY), master_necromancy_wand); - WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.EARTH), master_earth_wand); - WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.SORCERY), master_sorcery_wand); - WAND_MAP.put(ImmutablePair.of(Tier.MASTER, Element.HEALING), master_healing_wand); - - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.MAGIC), wizard_hat); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.FIRE), wizard_hat_fire); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.ICE), wizard_hat_ice); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.LIGHTNING), wizard_hat_lightning); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.NECROMANCY), wizard_hat_necromancy); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.EARTH), wizard_hat_earth); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.SORCERY), wizard_hat_sorcery); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.HEAD, Element.HEALING), wizard_hat_healing); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.MAGIC), wizard_robe); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.FIRE), wizard_robe_fire); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.ICE), wizard_robe_ice); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.LIGHTNING), wizard_robe_lightning); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.NECROMANCY), wizard_robe_necromancy); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.EARTH), wizard_robe_earth); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.SORCERY), wizard_robe_sorcery); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.CHEST, Element.HEALING), wizard_robe_healing); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.MAGIC), wizard_leggings); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.FIRE), wizard_leggings_fire); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.ICE), wizard_leggings_ice); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.LIGHTNING), wizard_leggings_lightning); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.NECROMANCY), wizard_leggings_necromancy); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.EARTH), wizard_leggings_earth); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.SORCERY), wizard_leggings_sorcery); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.LEGS, Element.HEALING), wizard_leggings_healing); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.MAGIC), wizard_boots); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.FIRE), wizard_boots_fire); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.ICE), wizard_boots_ice); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.LIGHTNING), wizard_boots_lightning); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.NECROMANCY), wizard_boots_necromancy); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.EARTH), wizard_boots_earth); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.SORCERY), wizard_boots_sorcery); - ARMOUR_MAP.put(ImmutablePair.of(EntityEquipmentSlot.FEET, Element.HEALING), wizard_boots_healing); - } - - /** - * Sets both the registry and unlocalised names of the given item, then registers it with the given registry. Use - * this instead of {@link Item#setRegistryName(String)} and {@link Item#setUnlocalizedName(String)} during - * construction, for convenience and consistency. - * @param registry The registry to register the given item to. - * @param item The item to register. - * @param name The name of the item, without the mod ID or the .name stuff. The registry name will be - * {@code wizardry:[name]}. The unlocalised name will be {@code item.wizardry:[name].name}. - */ - public static void registerItem(IForgeRegistry registry, Item item, String name){ - item.setRegistryName(Wizardry.MODID, name); - item.setUnlocalizedName(item.getRegistryName().toString()); - registry.register(item); - } - - /** Registers an ItemBlock afor the given block, with the same registry name as that block. */ - private static void registerItemBlock(IForgeRegistry registry, Block block){ - // We don't need to keep a reference to the ItemBlock, so this can all be done in one line. - registry.register(new ItemBlock(block).setRegistryName(block.getRegistryName())); - } - - @SubscribeEvent - public static void register(RegistryEvent.Register event){ - - IForgeRegistry registry = event.getRegistry(); - - // ItemBlocks - - // Not all blocks need an ItemBlock - registerItemBlock(registry, WizardryBlocks.arcane_workbench); - registerItemBlock(registry, WizardryBlocks.crystal_ore); - registerItemBlock(registry, WizardryBlocks.crystal_flower); - registerItemBlock(registry, WizardryBlocks.transportation_stone); - registerItemBlock(registry, WizardryBlocks.crystal_block); - - // Items - - registerItem(registry, magic_crystal, "magic_crystal"); - - registerItem(registry, magic_wand, "magic_wand"); - registerItem(registry, apprentice_wand, "apprentice_wand"); - registerItem(registry, advanced_wand, "advanced_wand"); - registerItem(registry, master_wand, "master_wand"); - - registerItem(registry, spell_book, "spell_book"); - registerItem(registry, arcane_tome, "arcane_tome"); - registerItem(registry, wizard_handbook, "wizard_handbook"); - - registerItem(registry, basic_fire_wand, "basic_fire_wand"); - registerItem(registry, basic_ice_wand, "basic_ice_wand"); - registerItem(registry, basic_lightning_wand, "basic_lightning_wand"); - registerItem(registry, basic_necromancy_wand, "basic_necromancy_wand"); - registerItem(registry, basic_earth_wand, "basic_earth_wand"); - registerItem(registry, basic_sorcery_wand, "basic_sorcery_wand"); - registerItem(registry, basic_healing_wand, "basic_healing_wand"); - - registerItem(registry, apprentice_fire_wand, "apprentice_fire_wand"); - registerItem(registry, apprentice_ice_wand, "apprentice_ice_wand"); - registerItem(registry, apprentice_lightning_wand, "apprentice_lightning_wand"); - registerItem(registry, apprentice_necromancy_wand, "apprentice_necromancy_wand"); - registerItem(registry, apprentice_earth_wand, "apprentice_earth_wand"); - registerItem(registry, apprentice_sorcery_wand, "apprentice_sorcery_wand"); - registerItem(registry, apprentice_healing_wand, "apprentice_healing_wand"); - - registerItem(registry, advanced_fire_wand, "advanced_fire_wand"); - registerItem(registry, advanced_ice_wand, "advanced_ice_wand"); - registerItem(registry, advanced_lightning_wand, "advanced_lightning_wand"); - registerItem(registry, advanced_necromancy_wand, "advanced_necromancy_wand"); - registerItem(registry, advanced_earth_wand, "advanced_earth_wand"); - registerItem(registry, advanced_sorcery_wand, "advanced_sorcery_wand"); - registerItem(registry, advanced_healing_wand, "advanced_healing_wand"); - - registerItem(registry, master_fire_wand, "master_fire_wand"); - registerItem(registry, master_ice_wand, "master_ice_wand"); - registerItem(registry, master_lightning_wand, "master_lightning_wand"); - registerItem(registry, master_necromancy_wand, "master_necromancy_wand"); - registerItem(registry, master_earth_wand, "master_earth_wand"); - registerItem(registry, master_sorcery_wand, "master_sorcery_wand"); - registerItem(registry, master_healing_wand, "master_healing_wand"); - - registerItem(registry, spectral_sword, "spectral_sword"); - registerItem(registry, spectral_pickaxe, "spectral_pickaxe"); - registerItem(registry, spectral_bow, "spectral_bow"); - - registerItem(registry, mana_flask, "mana_flask"); - - registerItem(registry, storage_upgrade, "storage_upgrade"); - registerItem(registry, siphon_upgrade, "siphon_upgrade"); - registerItem(registry, condenser_upgrade, "condenser_upgrade"); - registerItem(registry, range_upgrade, "range_upgrade"); - registerItem(registry, duration_upgrade, "duration_upgrade"); - registerItem(registry, cooldown_upgrade, "cooldown_upgrade"); - registerItem(registry, blast_upgrade, "blast_upgrade"); - registerItem(registry, attunement_upgrade, "attunement_upgrade"); - - registerItem(registry, flaming_axe, "flaming_axe"); - registerItem(registry, frost_axe, "frost_axe"); - - registerItem(registry, firebomb, "firebomb"); - registerItem(registry, poison_bomb, "poison_bomb"); - - registerItem(registry, blank_scroll, "blank_scroll"); - registerItem(registry, scroll, "scroll"); - - registerItem(registry, armour_upgrade, "armour_upgrade"); - - registerItem(registry, magic_silk, "magic_silk"); - - registerItem(registry, wizard_hat, "wizard_hat"); - registerItem(registry, wizard_robe, "wizard_robe"); - registerItem(registry, wizard_leggings, "wizard_leggings"); - registerItem(registry, wizard_boots, "wizard_boots"); - - registerItem(registry, wizard_hat_fire, "wizard_hat_fire"); - registerItem(registry, wizard_robe_fire, "wizard_robe_fire"); - registerItem(registry, wizard_leggings_fire, "wizard_leggings_fire"); - registerItem(registry, wizard_boots_fire, "wizard_boots_fire"); - - registerItem(registry, wizard_hat_ice, "wizard_hat_ice"); - registerItem(registry, wizard_robe_ice, "wizard_robe_ice"); - registerItem(registry, wizard_leggings_ice, "wizard_leggings_ice"); - registerItem(registry, wizard_boots_ice, "wizard_boots_ice"); - - registerItem(registry, wizard_hat_lightning, "wizard_hat_lightning"); - registerItem(registry, wizard_robe_lightning, "wizard_robe_lightning"); - registerItem(registry, wizard_leggings_lightning, "wizard_leggings_lightning"); - registerItem(registry, wizard_boots_lightning, "wizard_boots_lightning"); - - registerItem(registry, wizard_hat_necromancy, "wizard_hat_necromancy"); - registerItem(registry, wizard_robe_necromancy, "wizard_robe_necromancy"); - registerItem(registry, wizard_leggings_necromancy, "wizard_leggings_necromancy"); - registerItem(registry, wizard_boots_necromancy, "wizard_boots_necromancy"); - - registerItem(registry, wizard_hat_earth, "wizard_hat_earth"); - registerItem(registry, wizard_robe_earth, "wizard_robe_earth"); - registerItem(registry, wizard_leggings_earth, "wizard_leggings_earth"); - registerItem(registry, wizard_boots_earth, "wizard_boots_earth"); - - registerItem(registry, wizard_hat_sorcery, "wizard_hat_sorcery"); - registerItem(registry, wizard_robe_sorcery, "wizard_robe_sorcery"); - registerItem(registry, wizard_leggings_sorcery, "wizard_leggings_sorcery"); - registerItem(registry, wizard_boots_sorcery, "wizard_boots_sorcery"); - - registerItem(registry, wizard_hat_healing, "wizard_hat_healing"); - registerItem(registry, wizard_robe_healing, "wizard_robe_healing"); - registerItem(registry, wizard_leggings_healing, "wizard_leggings_healing"); - registerItem(registry, wizard_boots_healing, "wizard_boots_healing"); - - registerItem(registry, spectral_helmet, "spectral_helmet"); - registerItem(registry, spectral_chestplate, "spectral_chestplate"); - registerItem(registry, spectral_leggings, "spectral_leggings"); - registerItem(registry, spectral_boots, "spectral_boots"); - - registerItem(registry, smoke_bomb, "smoke_bomb"); - - registerItem(registry, identification_scroll, "identification_scroll"); - } - -} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/registry/WizardryPotions.java b/src/main/java/electroblob/wizardry/registry/WizardryPotions.java deleted file mode 100644 index 4b51a675..00000000 --- a/src/main/java/electroblob/wizardry/registry/WizardryPotions.java +++ /dev/null @@ -1,113 +0,0 @@ -package electroblob.wizardry.registry; - -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.potion.PotionDecay; -import electroblob.wizardry.potion.PotionFrost; -import electroblob.wizardry.potion.PotionMagicEffect; -import electroblob.wizardry.potion.PotionMagicEffectParticles; -import electroblob.wizardry.util.WizardryParticleType; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.potion.Potion; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.world.World; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.registry.IForgeRegistry; - -/** - * Class responsible for defining, storing and registering all of wizardry's potion effects. - * @author Electroblob - * @since Wizardry 2.1 - */ -@Mod.EventBusSubscriber -public final class WizardryPotions { - - /* Interestingly, setting the colour to black stops the particles from rendering. This is great, however, the black - * colour then 'mixes' with other potions that are applied. Whilst this is a bit annoying, for the amount it is - * likely to get noticed it is certainly preferable to always making showParticles false, because now I can give - * the user the option (via commands) of having one of my potion effects without particles, and more importantly - * the potion effect HUD still gets displayed. TODO: Backport to 1.7.10, assuming it also works in that version. - * This means also changing whenever the potion effect is added such that it is NOT ambient. */ - - public static final Potion frost = new PotionFrost(true, 0); // Colour was 0x38ddec (was arbitrary anyway) - - public static final Potion transience = new PotionMagicEffectParticles(false, 0, 0){ - @Override - public void spawnCustomParticle(World world, double x, double y, double z){ - Wizardry.proxy.spawnParticle(WizardryParticleType.DUST, world, x, y, z, 0, 0, 0, (int)(16.0D / (Math.random() * 0.8D + 0.2D)), 0.8f, 0.8f, 1.0f); - } - }.setBeneficial(); //0xffe89b - - public static final Potion fireskin = new PotionMagicEffectParticles(false, 0, 1){ - @Override - public void spawnCustomParticle(World world, double x, double y, double z){ - world.spawnParticle(EnumParticleTypes.FLAME, x, y, z, 0, 0, 0); - } - @Override - public void performEffect(EntityLivingBase entitylivingbase, int strength){ - entitylivingbase.extinguish(); // Stops melee mobs that are on fire from setting the player on fire, - // without allowing the player to actually stand in fire or swim in lava without taking damage. - }; - }.setBeneficial(); //0xff2f02 - - public static final Potion ice_shroud = new PotionMagicEffectParticles(false, 0, 2){ - @Override - public void spawnCustomParticle(World world, double x, double y, double z){ - float brightness = 0.5f + (world.rand.nextFloat()/2); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x, y, z, 0, 0, 0, 48 + world.rand.nextInt(12), brightness, brightness + 0.1f, 1.0f, true, 0); - Wizardry.proxy.spawnParticle(WizardryParticleType.SNOW, world, x, y, z, 0, -0.02, 0, 40 + world.rand.nextInt(10)); - } - }.setBeneficial(); //0x52f1ff - - public static final Potion static_aura = new PotionMagicEffectParticles(false, 0, 3){ - @Override - public void spawnCustomParticle(World world, double x, double y, double z){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, x, y, z, 0, 0, 0, 3); - } - }.setBeneficial(); //0x0070ff - - public static final Potion decay = new PotionDecay(true, 0x3c006c); - public static final Potion sixth_sense = new PotionMagicEffect(false, 0xc6ff01, 4).setBeneficial(); - public static final Potion arcane_jammer = new PotionMagicEffect(false, 0xcf4aa2, 5); - public static final Potion mind_trick = new PotionMagicEffect(true, 0x601683, 6); - public static final Potion mind_control = new PotionMagicEffect(true, 0x320b44, 7); - public static final Potion font_of_mana = new PotionMagicEffect(false, 0xffe5bb, 8).setBeneficial(); - public static final Potion fear = new PotionMagicEffect(true, 0xbd0100, 9); - - /** - * Sets both the registry and unlocalised names of the given potion, then registers it with the given registry. Use - * this instead of {@link potion#setRegistryName(String)} and {@link potion#setUnlocalizedName(String)} during - * construction, for convenience and consistency. - * @param registry The registry to register the given potion to. - * @param potion The potion to register. - * @param name The name of the potion, without the mod ID or the .name stuff. The registry name will be - * {@code wizardry:[name]}. The unlocalised name will be {@code potion.wizardry:[name].name}. - */ - public static void registerPotion(IForgeRegistry registry, Potion potion, String name){ - potion.setRegistryName(Wizardry.MODID, name); - // For some reason, Potion#getName() doesn't prepend "potion." itself, so it has to be done here. - potion.setPotionName("potion." + potion.getRegistryName().toString()); - registry.register(potion); - } - - @SubscribeEvent - public static void register(RegistryEvent.Register event){ - - IForgeRegistry registry = event.getRegistry(); - - registerPotion(registry, frost, "frost"); - registerPotion(registry, transience, "transience"); - registerPotion(registry, fireskin, "fireskin"); - registerPotion(registry, ice_shroud, "ice_shroud"); - registerPotion(registry, static_aura, "static_aura"); - registerPotion(registry, decay, "decay"); - registerPotion(registry, sixth_sense, "sixth_sense"); - registerPotion(registry, arcane_jammer, "arcane_jammer"); - registerPotion(registry, mind_trick, "mind_trick"); - registerPotion(registry, mind_control, "mind_control"); - registerPotion(registry, font_of_mana, "font_of_mana"); - registerPotion(registry, fear, "fear"); - } - -} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/registry/WizardryRegistry.java b/src/main/java/electroblob/wizardry/registry/WizardryRegistry.java deleted file mode 100644 index f8103bf1..00000000 --- a/src/main/java/electroblob/wizardry/registry/WizardryRegistry.java +++ /dev/null @@ -1,320 +0,0 @@ -package electroblob.wizardry.registry; - -import java.util.ArrayList; -import java.util.List; - -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.entity.EntityArc; -import electroblob.wizardry.entity.EntityMeteor; -import electroblob.wizardry.entity.EntityShield; -import electroblob.wizardry.entity.construct.EntityArrowRain; -import electroblob.wizardry.entity.construct.EntityBlackHole; -import electroblob.wizardry.entity.construct.EntityBlizzard; -import electroblob.wizardry.entity.construct.EntityBubble; -import electroblob.wizardry.entity.construct.EntityDecay; -import electroblob.wizardry.entity.construct.EntityEarthquake; -import electroblob.wizardry.entity.construct.EntityFireRing; -import electroblob.wizardry.entity.construct.EntityFireSigil; -import electroblob.wizardry.entity.construct.EntityForcefield; -import electroblob.wizardry.entity.construct.EntityFrostSigil; -import electroblob.wizardry.entity.construct.EntityHailstorm; -import electroblob.wizardry.entity.construct.EntityHammer; -import electroblob.wizardry.entity.construct.EntityHealAura; -import electroblob.wizardry.entity.construct.EntityIceSpike; -import electroblob.wizardry.entity.construct.EntityLightningPulse; -import electroblob.wizardry.entity.construct.EntityLightningSigil; -import electroblob.wizardry.entity.construct.EntityTornado; -import electroblob.wizardry.entity.living.EntityBlazeMinion; -import electroblob.wizardry.entity.living.EntityDecoy; -import electroblob.wizardry.entity.living.EntityEvilWizard; -import electroblob.wizardry.entity.living.EntityIceGiant; -import electroblob.wizardry.entity.living.EntityIceWraith; -import electroblob.wizardry.entity.living.EntityLightningWraith; -import electroblob.wizardry.entity.living.EntityMagicSlime; -import electroblob.wizardry.entity.living.EntityPhoenix; -import electroblob.wizardry.entity.living.EntityShadowWraith; -import electroblob.wizardry.entity.living.EntitySilverfishMinion; -import electroblob.wizardry.entity.living.EntitySkeletonMinion; -import electroblob.wizardry.entity.living.EntitySpiderMinion; -import electroblob.wizardry.entity.living.EntitySpiritHorse; -import electroblob.wizardry.entity.living.EntitySpiritWolf; -import electroblob.wizardry.entity.living.EntityStormElemental; -import electroblob.wizardry.entity.living.EntityWizard; -import electroblob.wizardry.entity.living.EntityZombieMinion; -import electroblob.wizardry.entity.projectile.EntityDarknessOrb; -import electroblob.wizardry.entity.projectile.EntityDart; -import electroblob.wizardry.entity.projectile.EntityFirebolt; -import electroblob.wizardry.entity.projectile.EntityFirebomb; -import electroblob.wizardry.entity.projectile.EntityForceArrow; -import electroblob.wizardry.entity.projectile.EntityForceOrb; -import electroblob.wizardry.entity.projectile.EntityIceCharge; -import electroblob.wizardry.entity.projectile.EntityIceLance; -import electroblob.wizardry.entity.projectile.EntityIceShard; -import electroblob.wizardry.entity.projectile.EntityLightningArrow; -import electroblob.wizardry.entity.projectile.EntityLightningDisc; -import electroblob.wizardry.entity.projectile.EntityMagicMissile; -import electroblob.wizardry.entity.projectile.EntityPoisonBomb; -import electroblob.wizardry.entity.projectile.EntitySmokeBomb; -import electroblob.wizardry.entity.projectile.EntitySpark; -import electroblob.wizardry.entity.projectile.EntitySparkBomb; -import electroblob.wizardry.entity.projectile.EntityThunderbolt; -import electroblob.wizardry.loot.RandomSpell; -import electroblob.wizardry.loot.WizardSpell; -import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench; -import electroblob.wizardry.tileentity.TileEntityMagicLight; -import electroblob.wizardry.tileentity.TileEntityPlayerSave; -import electroblob.wizardry.tileentity.TileEntityStatue; -import electroblob.wizardry.tileentity.TileEntityTimer; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.entity.EnumCreatureType; -import net.minecraft.init.Biomes; -import net.minecraft.init.Blocks; -import net.minecraft.init.Items; -import net.minecraft.inventory.EntityEquipmentSlot; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.biome.Biome; -import net.minecraft.world.storage.loot.LootTableList; -import net.minecraft.world.storage.loot.functions.LootFunctionManager; -import net.minecraftforge.fml.common.registry.EntityRegistry; -import net.minecraftforge.fml.common.registry.GameRegistry; -import net.minecraftforge.oredict.OreDictionary; - -/** - * Class responsible for registering all the things that don't have (or need) instances: entities, loot tables, - * recipes, etc. - * @author Electroblob - * @since Wizardry 1.0 - */ -public final class WizardryRegistry { - - // NOTE: In 1.12, recipes have a registry (they can still stay here though since we don't keep references to them) - - /** Called from the preInit method in the main mod class to register the custom dungeon loot. */ - public static void registerLoot(){ - - /* Loot tables work as follows: - * Minecraft goes through each pool in turn. For each pool, it does a certain number or rolls, which can either - * be set to always be one number or a random number from a range. Each roll, it generates one stack of a single - * random entry in that pool, weighted according to the weights of the entries. Functions allow properties of - * that stack (stack size, damage, nbt) to be set, and even allow it to be replaced dynamically with a - * completely different item (though there's very little point in doing that as it could be achieved just as - * easily with more entries, which makes me think it would be bad practice). - * You can also use conditions to control whether an entry or pool is used at all, which is mostly for mob drops - * under specific conditions, but one of them is simply a random chance, meaning you could use it to make a pool - * that only gets rolled sometimes. - * All in all, this can get rather confusing, because stackable items can have 5 stages of randomness applied - * to them at once: a random chance for the pool, a random number of rolls for the pool, the weighted random - * chance of choosing that particular entry, a random chance for that entry, and a random stack size, and that's - * before you take functions into account. - * - * ...oh, and entries can be entire loot tables in themselves, allowing for potentially infinite levels of - * randomness. Yeah. - * - * Translating to the new system: - * ChestGenHooks.SOME_NAME -> loot table json file - * ??? -> loot pool (I don't think it was split up like this before) - * ChestGenHooks.addItem() -> entry in a loot pool - * Stack sizes in WeightedRandomChestContent -> set_count function for entries - * Weight in WeightedRandomChestContent -> weight of entries - * Custom WeightedRandomChestContent implementations -> custom loot functions, but only for complex/dynamic - * stuff - things that serve to allow the chance for a category of items (like armour) to be specified but still - * have a random chance for which exact item you get should be done with nested loot tables. - */ - - // Always registers the loot tables, but only injects the additions into vanilla if the appropriate option is - // enabled in the config (see WizardryEventHandler). - LootFunctionManager.registerFunction(new RandomSpell.Serializer()); - LootFunctionManager.registerFunction(new WizardSpell.Serializer()); - LootTableList.register(new ResourceLocation(Wizardry.MODID, "chests/wizard_tower")); - LootTableList.register(new ResourceLocation(Wizardry.MODID, "chests/dungeon_additions")); - LootTableList.register(new ResourceLocation(Wizardry.MODID, "subsets/novice_wands")); - LootTableList.register(new ResourceLocation(Wizardry.MODID, "subsets/wizard_armour")); - LootTableList.register(new ResourceLocation(Wizardry.MODID, "subsets/arcane_tomes")); - LootTableList.register(new ResourceLocation(Wizardry.MODID, "subsets/wand_upgrades")); - LootTableList.register(new ResourceLocation(Wizardry.MODID, "entities/evil_wizard")); - // TODO: At the moment this is not used anywhere because I can't find a way to add it to all mobs. - //LootTableList.register(new ResourceLocation(Wizardry.MODID, "entities/mob_additions")); - - } - - /** Called from the preInit method in the main mod class to register all the tile entities. */ - public static void registerTileEntities(){ - - GameRegistry.registerTileEntity(TileEntityArcaneWorkbench.class, Wizardry.MODID + "ArcaneWorkbenchTileEntity"); - GameRegistry.registerTileEntity(TileEntityStatue.class, Wizardry.MODID + "PetrifiedStoneTileEntity"); - GameRegistry.registerTileEntity(TileEntityMagicLight.class, Wizardry.MODID + "MagicLightTileEntity"); - GameRegistry.registerTileEntity(TileEntityTimer.class, Wizardry.MODID + "TimerTileEntity"); - GameRegistry.registerTileEntity(TileEntityPlayerSave.class, Wizardry.MODID + "TileEntityPlayerSave"); - } - - /** Not actually the frequency at all; smaller numbers are more frequent. Vanilla uses 3 I think. */ - private static final int LIVING_UPDATE_INTERVAL = 3; - /** Not actually the frequency at all; smaller numbers are more frequent. */ - private static final int PROJECTILE_UPDATE_INTERVAL = 10; - - /** Called from the preInit method in the main mod class to register all the entities. */ - public static void registerEntities(Wizardry wizardry){ - - int id = 0; // Incrementable index for the mod specific entity id. - - EntityRegistry.registerModEntity(EntityZombieMinion.class, "zombie_minion", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityMagicMissile.class, "magic_missile", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - // TODO: This should be a particle - EntityRegistry.registerModEntity(EntityArc.class, "arc", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, false); - EntityRegistry.registerModEntity(EntitySkeletonMinion.class, "skeleton_minion", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntitySparkBomb.class, "spark_bomb", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntitySpiritWolf.class, "spirit_wolf", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityIceShard.class, "ice_shard", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityBlazeMinion.class, "blaze_minion", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityIceWraith.class, "ice_wraith", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityLightningWraith.class, "lightning_wraith", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityBlackHole.class, "black_hole", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, false); - EntityRegistry.registerModEntity(EntityShield.class, "shield", id++, wizardry, 128, 1, true); - EntityRegistry.registerModEntity(EntityMeteor.class, "meteor", id++, wizardry, 128, 5, true); - EntityRegistry.registerModEntity(EntityBlizzard.class, "blizzard", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, false); - EntityRegistry.registerModEntity(EntityWizard.class, "wizard", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityBubble.class, "bubble", id++, wizardry, 128, 3, false); - EntityRegistry.registerModEntity(EntityTornado.class, "tornado", id++, wizardry, 128, 1, false); - EntityRegistry.registerModEntity(EntityHammer.class, "lightning_hammer", id++, wizardry, 128, 1, true); - EntityRegistry.registerModEntity(EntityFirebomb.class, "firebomb", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityForceOrb.class, "force_orb", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityArrowRain.class, "arrow_rain", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, false); - EntityRegistry.registerModEntity(EntitySpark.class, "spark", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityShadowWraith.class, "shadow_wraith", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityDarknessOrb.class, "darkness_orb", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntitySpiderMinion.class, "spider_minion", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityHealAura.class, "healing_aura", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, false); - EntityRegistry.registerModEntity(EntityFireSigil.class, "fire_sigil", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, false); - EntityRegistry.registerModEntity(EntityFrostSigil.class, "frost_sigil", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, false); - EntityRegistry.registerModEntity(EntityLightningSigil.class, "lightning_sigil", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, false); - EntityRegistry.registerModEntity(EntityLightningArrow.class, "lightning_arrow", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityFirebolt.class, "firebolt", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityPoisonBomb.class, "poison_bomb", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityIceCharge.class, "ice_charge", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityForceArrow.class, "force_arrow", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityDart.class, "dart", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityMagicSlime.class, "magic_slime", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityForcefield.class, "forcefield", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, false); - EntityRegistry.registerModEntity(EntityFireRing.class, "ring_of_fire", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, false); - EntityRegistry.registerModEntity(EntityLightningDisc.class, "lightning_disc", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityThunderbolt.class, "thunderbolt", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityIceGiant.class, "ice_giant", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntitySpiritHorse.class, "spirit_horse", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityPhoenix.class, "phoenix", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntitySilverfishMinion.class, "silverfish_minion", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityDecay.class, "decay", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, false); - EntityRegistry.registerModEntity(EntityStormElemental.class, "storm_elemental", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityEarthquake.class, "earthquake", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, false); - EntityRegistry.registerModEntity(EntityIceLance.class, "ice_lance", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityHailstorm.class, "hailstorm", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, false); - EntityRegistry.registerModEntity(EntitySmokeBomb.class, "smoke_bomb", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityEvilWizard.class, "evil_wizard", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityDecoy.class, "decoy", id++, wizardry, 128, LIVING_UPDATE_INTERVAL, true); - EntityRegistry.registerModEntity(EntityIceSpike.class, "ice_spike", id++, wizardry, 128, 1, true); - // TODO: This should be a particle. - EntityRegistry.registerModEntity(EntityLightningPulse.class, "lightning_pulse", id++, wizardry, 128, PROJECTILE_UPDATE_INTERVAL, false); - - EntityRegistry.registerEgg(EntityWizard.class, 0x19295e, 0xee9312); - EntityRegistry.registerEgg(EntityEvilWizard.class, 0x290404, 0xee9312); - - // TODO: May need fixing - List biomes = new ArrayList(); - for(Biome biome : Biome.EXPLORATION_BIOMES_LIST){ - if(biome != null){ - biomes.add(biome); - } - } - biomes.remove(Biomes.MUSHROOM_ISLAND); - biomes.remove(Biomes.MUSHROOM_ISLAND_SHORE); - // For reference: 5, 1, 1 are the parameters for the witch in vanilla. - EntityRegistry.addSpawn(EntityEvilWizard.class, 3, 1, 1, EnumCreatureType.MONSTER, biomes.toArray(new Biome[biomes.size()])); - - } - - /** Called from the init method in the main mod class to register all the recipes. */ - public static void registerRecipes(){ - - ItemStack magicCrystalStack = new ItemStack(WizardryItems.magic_crystal); - ItemStack magicWandStack = new ItemStack(WizardryItems.magic_wand, 1, Tier.BASIC.maxCharge); - ItemStack goldNuggetStack = new ItemStack(Items.GOLD_NUGGET); - ItemStack stickStack = new ItemStack(Items.STICK); - ItemStack bookStack = new ItemStack(Items.BOOK); - ItemStack stringStack = new ItemStack(Items.STRING); - ItemStack spellBookStack = new ItemStack(WizardryItems.spell_book, 1, Spells.magic_missile.id()); - ItemStack arcaneWorkbenchStack = new ItemStack(WizardryBlocks.arcane_workbench); - ItemStack stoneStack = new ItemStack(Blocks.STONE); - ItemStack lapisBlockStack = new ItemStack(Blocks.LAPIS_BLOCK); - ItemStack purpleCarpetStack = new ItemStack(Blocks.CARPET, 1, 10); - ItemStack wizardHandbookStack = new ItemStack(WizardryItems.wizard_handbook); - ItemStack crystalFlowerStack = new ItemStack(WizardryBlocks.crystal_flower); - ItemStack magicCrystalStack1 = new ItemStack(WizardryItems.magic_crystal, 2); - ItemStack magicCrystalStack2 = new ItemStack(WizardryItems.magic_crystal, 9); - ItemStack crystalBlockStack = new ItemStack(WizardryBlocks.crystal_block); - ItemStack manaFlaskStack = new ItemStack(WizardryItems.mana_flask); - ItemStack bottleStack = new ItemStack(Items.GLASS_BOTTLE); - ItemStack gunpowderStack = new ItemStack(Items.GUNPOWDER); - ItemStack blazePowderStack = new ItemStack(Items.BLAZE_POWDER); - ItemStack spiderEyeStack = new ItemStack(Items.SPIDER_EYE); - // Coal or charcoal is equally fine, hence the wildcard value - ItemStack coalStack = new ItemStack(Items.COAL, 1, OreDictionary.WILDCARD_VALUE); - ItemStack firebombStack = new ItemStack(WizardryItems.firebomb, 3); - ItemStack poisonBombStack = new ItemStack(WizardryItems.poison_bomb, 3); - ItemStack smokeBombStack = new ItemStack(WizardryItems.smoke_bomb, 3); - ItemStack transportationStoneStack = new ItemStack(WizardryBlocks.transportation_stone, 2); - ItemStack silkStack = new ItemStack(WizardryItems.magic_silk); - ItemStack silkStack1 = new ItemStack(WizardryItems.magic_silk, 2); - ItemStack hatStack = new ItemStack(WizardryItems.wizard_hat); - ItemStack robeStack = new ItemStack(WizardryItems.wizard_robe); - ItemStack leggingsStack = new ItemStack(WizardryItems.wizard_leggings); - ItemStack bootsStack = new ItemStack(WizardryItems.wizard_boots); - ItemStack scrollStack = new ItemStack(WizardryItems.blank_scroll); - ItemStack paperStack = new ItemStack(Items.PAPER); - - GameRegistry.addRecipe(magicWandStack, " x", " y ", "z ", 'x', magicCrystalStack, 'y', stickStack, 'z', goldNuggetStack); - GameRegistry.addRecipe(spellBookStack, " x ", "xyx", " x ", 'x', magicCrystalStack, 'y', bookStack); - GameRegistry.addRecipe(arcaneWorkbenchStack, "vwv", "xyx", "zzz", 'v', goldNuggetStack, 'w', purpleCarpetStack, 'x', magicCrystalStack, 'y', lapisBlockStack, 'z', stoneStack); - GameRegistry.addRecipe(manaFlaskStack, "yyy", "yxy", "yyy", 'x', bottleStack, 'y', magicCrystalStack); - GameRegistry.addRecipe(transportationStoneStack, " x ", "xyx", " x ", 'x', stoneStack, 'y', magicCrystalStack); - GameRegistry.addRecipe(hatStack, "yyy", "y y", 'y', silkStack); - GameRegistry.addRecipe(robeStack, "y y", "yyy", "yyy", 'y', silkStack); - GameRegistry.addRecipe(leggingsStack, "yyy", "y y", "y y", 'y', silkStack); - GameRegistry.addRecipe(bootsStack, "y y", "y y", 'y', silkStack); - GameRegistry.addRecipe(silkStack1, " x ", "xyx", " x ", 'x', stringStack, 'y', magicCrystalStack); - GameRegistry.addRecipe(crystalBlockStack, "zzz", "zzz", "zzz", 'z', magicCrystalStack); - - GameRegistry.addShapelessRecipe(wizardHandbookStack, bookStack, magicCrystalStack); - GameRegistry.addShapelessRecipe(magicCrystalStack1, crystalFlowerStack); - GameRegistry.addShapelessRecipe(magicCrystalStack2, crystalBlockStack); - if(Wizardry.settings.firebombIsCraftable) GameRegistry.addShapelessRecipe(firebombStack, bottleStack, gunpowderStack, blazePowderStack, blazePowderStack); - if(Wizardry.settings.poisonBombIsCraftable) GameRegistry.addShapelessRecipe(poisonBombStack, bottleStack, gunpowderStack, spiderEyeStack, spiderEyeStack); - if(Wizardry.settings.smokeBombIsCraftable) GameRegistry.addShapelessRecipe(smokeBombStack, bottleStack, gunpowderStack, coalStack, coalStack); - if(Wizardry.settings.useAlternateScrollRecipe){ - GameRegistry.addShapelessRecipe(scrollStack, paperStack, stringStack, magicCrystalStack); - }else{ - GameRegistry.addShapelessRecipe(scrollStack, paperStack, stringStack); - } - - // Mana flask recipes - ItemStack miscWandStack; - - for(Element element : Element.values()){ - for(Tier tier : Tier.values()){ - miscWandStack = new ItemStack(WizardryUtilities.getWand(tier, element), 1, OreDictionary.WILDCARD_VALUE); - GameRegistry.addShapelessRecipe(miscWandStack, miscWandStack, manaFlaskStack); - } - } - - ItemStack miscArmourStack; - - for(Element element : Element.values()){ - for(EntityEquipmentSlot slot : WizardryUtilities.ARMOUR_SLOTS){ - miscArmourStack = new ItemStack(WizardryUtilities.getArmour(element, slot), 1, OreDictionary.WILDCARD_VALUE); - GameRegistry.addShapelessRecipe(miscArmourStack, miscArmourStack, manaFlaskStack); - } - } - } - -} diff --git a/src/main/java/electroblob/wizardry/registry/WizardrySounds.java b/src/main/java/electroblob/wizardry/registry/WizardrySounds.java deleted file mode 100644 index d006add1..00000000 --- a/src/main/java/electroblob/wizardry/registry/WizardrySounds.java +++ /dev/null @@ -1,68 +0,0 @@ -package electroblob.wizardry.registry; - -import electroblob.wizardry.Wizardry; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.SoundEvent; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; - -/** - * Class responsible for defining, storing and registering all of wizardry's sound events. For some reason, these - * worked in the beta versions despite not being registered... - * @author Electroblob - * @since Wizardry 2.1 - */ -@Mod.EventBusSubscriber -public final class WizardrySounds { - - // Anything with LOOP in its name is intended to be played in a continuous loop. - public static final SoundEvent SPELL_SPARK = createSound("arc"); - public static final SoundEvent SPELL_CONJURATION = createSound("aura"); - public static final SoundEvent SPELL_SHOCKWAVE = createSound("boom"); - public static final SoundEvent SPELL_LOOP_CRACKLE = createSound("crackle"); - public static final SoundEvent SPELL_SUMMONING = createSound("darkaura"); - public static final SoundEvent SPELL_DEFLECTION = createSound("effect"); - public static final SoundEvent SPELL_LIGHTNING = createSound("electricitya"); - public static final SoundEvent SPELL_LOOP_LIGHTNING = createSound("electricityb"); - public static final SoundEvent SPELL_LOOP_FIRE = createSound("flameray"); - public static final SoundEvent SPELL_FREEZE = createSound("freeze"); - public static final SoundEvent SPELL_LOOP_ICE = createSound("frostray"); - public static final SoundEvent SPELL_HEAL = createSound("heal"); - public static final SoundEvent SPELL_ICE = createSound("ice"); - public static final SoundEvent SPELL_CONJURATION_LARGE = createSound("largeaura"); - public static final SoundEvent SPELL_MAGIC = createSound("magic"); - public static final SoundEvent SPELL_LOOP_SPARKLE = createSound("sparkle"); - public static final SoundEvent SPELL_LOOP_WIND = createSound("wind"); - public static final SoundEvent SPELL_EARTHQUAKE = createSound("rumble"); - public static final SoundEvent SPELL_FORCE = createSound("force"); - - /** Trick borrowed from the Twilight Forest, makes things neater. */ - public static SoundEvent createSound(String name){ - // All the setRegistryName methods delegate to this one, it doesn't matter which you use. - return new SoundEvent(new ResourceLocation(Wizardry.MODID, name)).setRegistryName(name); - } - - @SubscribeEvent - public static void register(RegistryEvent.Register event){ - event.getRegistry().register(SPELL_SPARK); - event.getRegistry().register(SPELL_CONJURATION); - event.getRegistry().register(SPELL_SHOCKWAVE); - event.getRegistry().register(SPELL_LOOP_CRACKLE); - event.getRegistry().register(SPELL_SUMMONING); - event.getRegistry().register(SPELL_DEFLECTION); - event.getRegistry().register(SPELL_LIGHTNING); - event.getRegistry().register(SPELL_LOOP_LIGHTNING); - event.getRegistry().register(SPELL_LOOP_FIRE); - event.getRegistry().register(SPELL_FREEZE); - event.getRegistry().register(SPELL_LOOP_ICE); - event.getRegistry().register(SPELL_HEAL); - event.getRegistry().register(SPELL_ICE); - event.getRegistry().register(SPELL_CONJURATION_LARGE); - event.getRegistry().register(SPELL_MAGIC); - event.getRegistry().register(SPELL_LOOP_SPARKLE); - event.getRegistry().register(SPELL_LOOP_WIND); - event.getRegistry().register(SPELL_EARTHQUAKE); - event.getRegistry().register(SPELL_FORCE); - } -} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/registry/WizardryTabs.java b/src/main/java/electroblob/wizardry/registry/WizardryTabs.java deleted file mode 100644 index 6eeb9fc6..00000000 --- a/src/main/java/electroblob/wizardry/registry/WizardryTabs.java +++ /dev/null @@ -1,175 +0,0 @@ -package electroblob.wizardry.registry; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; - -import com.google.common.base.Function; -import com.google.common.collect.Ordering; - -import electroblob.wizardry.item.ItemScroll; -import electroblob.wizardry.item.ItemSpellBook; -import electroblob.wizardry.spell.Spell; -import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -/** - * Class responsible for defining and storing all of wizardry's creative tabs. Also handles sorting of the items. - * @author Electroblob - * @since Wizardry 2.1 - */ -public final class WizardryTabs { - - private static Comparator itemSorter; - private static Comparator spellItemSorter; - - // Creative Tabs - public static final CreativeTabs WIZARDRY = new CreativeTabs("wizardry"){ - - @Override - @SideOnly(Side.CLIENT) - public Item getTabIconItem() { - return WizardryItems.wizard_handbook; - } - - @Override - @SideOnly(Side.CLIENT) - public void displayAllRelevantItems(List items) { - super.displayAllRelevantItems(items); - Collections.sort(items, itemSorter); - } - }; - public static final CreativeTabs SPELLS = new CreativeTabs("wizardryspells"){ - - @Override - @SideOnly(Side.CLIENT) - public Item getTabIconItem() { - return WizardryItems.spell_book; - } - - @Override - @SideOnly(Side.CLIENT) - public void displayAllRelevantItems(List items) { - super.displayAllRelevantItems(items); - Collections.sort(items, spellItemSorter); - } - - @Override - public boolean hasSearchBar() { - return true; - } - - @Override - @SideOnly(Side.CLIENT) - public String getBackgroundImageName() { - return "item_search.png"; - } - }; - - /** Initialises the item sorters for the creative tabs. */ - public static void sort(){ - - List orderedItemList = Arrays.asList( - - Item.getItemFromBlock(WizardryBlocks.arcane_workbench), - Item.getItemFromBlock(WizardryBlocks.crystal_ore), - Item.getItemFromBlock(WizardryBlocks.crystal_block), - Item.getItemFromBlock(WizardryBlocks.crystal_flower), - Item.getItemFromBlock(WizardryBlocks.transportation_stone), - WizardryItems.magic_crystal, - WizardryItems.magic_wand, - WizardryItems.apprentice_wand, - WizardryItems.advanced_wand, - WizardryItems.master_wand, - WizardryItems.arcane_tome, - WizardryItems.wizard_handbook, - WizardryItems.basic_fire_wand, - WizardryItems.basic_ice_wand, - WizardryItems.basic_lightning_wand, - WizardryItems.basic_necromancy_wand, - WizardryItems.basic_earth_wand, - WizardryItems.basic_sorcery_wand, - WizardryItems.basic_healing_wand, - WizardryItems.smoke_bomb, - WizardryItems.firebomb, - WizardryItems.poison_bomb, - WizardryItems.blank_scroll, - WizardryItems.identification_scroll, - WizardryItems.mana_flask, - WizardryItems.storage_upgrade, - WizardryItems.siphon_upgrade, - WizardryItems.condenser_upgrade, - WizardryItems.range_upgrade, - WizardryItems.duration_upgrade, - WizardryItems.cooldown_upgrade, - WizardryItems.blast_upgrade, - WizardryItems.attunement_upgrade, - WizardryItems.magic_silk, - WizardryItems.armour_upgrade, - WizardryItems.wizard_hat, - WizardryItems.wizard_robe, - WizardryItems.wizard_leggings, - WizardryItems.wizard_boots, - WizardryItems.wizard_hat_fire, - WizardryItems.wizard_robe_fire, - WizardryItems.wizard_leggings_fire, - WizardryItems.wizard_boots_fire, - WizardryItems.wizard_hat_ice, - WizardryItems.wizard_robe_ice, - WizardryItems.wizard_leggings_ice, - WizardryItems.wizard_boots_ice, - WizardryItems.wizard_hat_lightning, - WizardryItems.wizard_robe_lightning, - WizardryItems.wizard_leggings_lightning, - WizardryItems.wizard_boots_lightning, - WizardryItems.wizard_hat_necromancy, - WizardryItems.wizard_robe_necromancy, - WizardryItems.wizard_leggings_necromancy, - WizardryItems.wizard_boots_necromancy, - WizardryItems.wizard_hat_earth, - WizardryItems.wizard_robe_earth, - WizardryItems.wizard_leggings_earth, - WizardryItems.wizard_boots_earth, - WizardryItems.wizard_hat_sorcery, - WizardryItems.wizard_robe_sorcery, - WizardryItems.wizard_leggings_sorcery, - WizardryItems.wizard_boots_sorcery, - WizardryItems.wizard_hat_healing, - WizardryItems.wizard_robe_healing, - WizardryItems.wizard_leggings_healing, - WizardryItems.wizard_boots_healing); - - itemSorter = Ordering.explicit(orderedItemList).onResultOf(new Function() { - @Override - public Item apply(ItemStack input) { - return input.getItem(); - } - }); - - spellItemSorter = new Comparator(){ - @Override - public int compare(ItemStack stack1, ItemStack stack2) { - - if((stack1.getItem() instanceof ItemSpellBook && stack2.getItem() instanceof ItemSpellBook) - || (stack1.getItem() instanceof ItemScroll && stack2.getItem() instanceof ItemScroll)){ - - Spell spell1 = Spell.get(stack1.getItemDamage()); - Spell spell2 = Spell.get(stack2.getItemDamage()); - - return spell1.compareTo(spell2); - - }else if(stack1.getItem() instanceof ItemScroll){ - return 1; - }else if(stack2.getItem() instanceof ItemScroll){ - return -1; - } - return 0; - } - }; - } - -} diff --git a/src/main/java/electroblob/wizardry/spell/Agility.java b/src/main/java/electroblob/wizardry/spell/Agility.java index db01f4a4..b1d7de76 100644 --- a/src/main/java/electroblob/wizardry/spell/Agility.java +++ b/src/main/java/electroblob/wizardry/spell/Agility.java @@ -1,44 +1,39 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class Agility extends Spell { public Agility() { - super(Tier.APPRENTICE, 20, Element.SORCERY, "agility", SpellType.UTILITY, 40, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 20, EnumElement.SORCERY, "agility", EnumSpellType.UTILITY, 40, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - // 1.10 allows the particles to be completely hidden. - caster.addPotionEffect(new PotionEffect(MobEffects.SPEED, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 1, false, false)); - caster.addPotionEffect(new PotionEffect(MobEffects.JUMP_BOOST, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 1, false, false)); + caster.addPotionEffect(new PotionEffect(Potion.moveSpeed.id, (int)(600*durationMultiplier), 1, true)); + caster.addPotionEffect(new PotionEffect(Potion.jump.id, (int)(600*durationMultiplier), 1, true)); for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); if(world.isRemote){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.6f, 0.6f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.6f, 0.6f, 1.0f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Arc.java b/src/main/java/electroblob/wizardry/spell/Arc.java index 372911d4..9f9dceed 100644 --- a/src/main/java/electroblob/wizardry/spell/Arc.java +++ b/src/main/java/electroblob/wizardry/spell/Arc.java @@ -1,26 +1,24 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.entity.EntityArc; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.entity.living.EntityLightningWraith; +import electroblob.wizardry.entity.living.EntityStormElemental; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityCreeper; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; // This spell was the 'guinea pig' for damage types, so to speak, so there's a bit of commentary on them here that may @@ -28,13 +26,13 @@ import net.minecraft.world.World; public class Arc extends Spell { public Arc() { - super(Tier.BASIC, 5, Element.LIGHTNING, "arc", SpellType.ATTACK, 15, EnumAction.NONE, false); + super(EnumTier.BASIC, 5, EnumElement.LIGHTNING, "arc", EnumSpellType.ATTACK, 15, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 8*modifiers.get(WizardryItems.range_upgrade), 4.0f); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 8*rangeMultiplier, 4.0f); if(rayTrace != null && rayTrace.entityHit != null && rayTrace.entityHit instanceof EntityLivingBase){ @@ -47,20 +45,20 @@ public class Arc extends Spell { world.spawnEntityInWorld(arc); }else{ for(int i=0;i<8;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, target.posX + world.rand.nextFloat() - 0.5, target.getEntityBoundingBox().minY + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); - world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, target.posX + world.rand.nextFloat() - 0.5, target.getEntityBoundingBox().minY + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, world, target.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(target) + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); + world.spawnParticle("largesmoke", target.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(target) + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); } } // This is a lot neater than it was, thanks to the damage type system. if(MagicDamage.isEntityImmune(DamageType.SHOCK, target)){ - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", target.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", target.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else{ - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 3.0f * modifiers.get(SpellModifiers.DAMAGE)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 3.0f * damageMultiplier); } - - caster.swingArm(hand); - target.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); + + caster.swingItem(); + world.playSoundAtEntity(target, "wizardry:arc", 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); return true; } @@ -68,7 +66,7 @@ public class Arc extends Spell { } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ @@ -79,17 +77,17 @@ public class Arc extends Spell { world.spawnEntityInWorld(arc); }else{ for(int i=0;i<8;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, target.posX + world.rand.nextFloat() - 0.5, target.getEntityBoundingBox().minY + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); - world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, target.posX + world.rand.nextFloat() - 0.5, target.getEntityBoundingBox().minY + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, world, target.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(target) + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); + world.spawnParticle("largesmoke", target.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(target) + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); } } // What's great about the damage type system is that, because I don't need to know if the creature resisted // the damage here, I can simply call this without having to check for immunities at all. - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 3.0f * modifiers.get(SpellModifiers.DAMAGE)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 3.0f * damageMultiplier); - caster.swingArm(hand); - target.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); + caster.swingItem(); + world.playSoundAtEntity(target, "wizardry:arc", 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/ArcaneJammer.java b/src/main/java/electroblob/wizardry/spell/ArcaneJammer.java index 163e2f42..0daa0d98 100644 --- a/src/main/java/electroblob/wizardry/spell/ArcaneJammer.java +++ b/src/main/java/electroblob/wizardry/spell/ArcaneJammer.java @@ -1,72 +1,63 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntityWizard; -import electroblob.wizardry.event.SpellCastEvent; -import electroblob.wizardry.registry.WizardryAchievements; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; +import net.minecraft.util.Vec3; import net.minecraft.world.World; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -@Mod.EventBusSubscriber public class ArcaneJammer extends Spell { public ArcaneJammer() { - super(Tier.ADVANCED, 30, Element.HEALING, "arcane_jammer", SpellType.ATTACK, 50, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 30, EnumElement.HEALING, "arcane_jammer", EnumSpellType.ATTACK, 50, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - Vec3d look = caster.getLookVec(); + Vec3 look = caster.getLookVec(); - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ EntityLivingBase entity = (EntityLivingBase) rayTrace.entityHit; - if(entity instanceof EntityWizard) caster.addStat(WizardryAchievements.jam_wizard); + if(entity instanceof EntityWizard) caster.triggerAchievement(Wizardry.jamWizard); if(!world.isRemote){ - entity.addPotionEffect(new PotionEffect(WizardryPotions.arcane_jammer, (int)(300*modifiers.get(WizardryItems.duration_upgrade)), 0)); + entity.addPotionEffect(new PotionEffect(Wizardry.arcaneJammer.id, (int)(300*durationMultiplier), 0)); } } if(world.isRemote){ - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ double x1 = caster.posX + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.9f, 0.3f, 0.7f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.9f, 0.3f, 0.7f); } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_DEFLECTION, 0.7F, world.rand.nextFloat() * 0.4F + 0.8F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:effect", 0.7F, world.rand.nextFloat() * 0.4F + 0.8F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - target.addPotionEffect(new PotionEffect(WizardryPotions.arcane_jammer, (int)(300*modifiers.get(WizardryItems.duration_upgrade)), 0)); + target.addPotionEffect(new PotionEffect(Wizardry.arcaneJammer.id, (int)(300*durationMultiplier), 0)); } if(world.isRemote){ @@ -75,17 +66,17 @@ public class ArcaneJammer extends Spell { double dy = (target.posY - caster.posY)/caster.getDistanceToEntity(target); double dz = (target.posZ - caster.posZ)/caster.getDistanceToEntity(target); - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ double x1 = caster.posX + dx*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = caster.posY + caster.getEyeHeight() - 0.4f + dy*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + dz*i/2 + world.rand.nextFloat()/5 - 0.1f; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.9f, 0.3f, 0.7f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.9f, 0.3f, 0.7f); } } - caster.swingArm(hand); - caster.playSound(WizardrySounds.SPELL_DEFLECTION, 0.7F, world.rand.nextFloat() * 0.4F + 0.8F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:effect", 0.7F, world.rand.nextFloat() * 0.4F + 0.8F); } return false; @@ -95,11 +86,5 @@ public class ArcaneJammer extends Spell { public boolean canBeCastByNPCs(){ return true; } - - @SubscribeEvent - public static void onSpellCastPreEvent(SpellCastEvent.Pre event){ - // Arcane jammer prevents spell casting. - if(event.getEntityLiving().isPotionActive(WizardryPotions.arcane_jammer)) event.setCanceled(true); - } } diff --git a/src/main/java/electroblob/wizardry/spell/ArrowRain.java b/src/main/java/electroblob/wizardry/spell/ArrowRain.java index b8c8f210..5d040b82 100644 --- a/src/main/java/electroblob/wizardry/spell/ArrowRain.java +++ b/src/main/java/electroblob/wizardry/spell/ArrowRain.java @@ -1,23 +1,20 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.construct.EntityArrowRain; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class ArrowRain extends Spell { public ArrowRain() { - super(Tier.MASTER, 75, Element.SORCERY, "arrow_rain", SpellType.ATTACK, 300, EnumAction.NONE, false); + super(EnumTier.MASTER, 75, EnumElement.SORCERY, "arrow_rain", EnumSpellType.ATTACK, 300, EnumAction.none, false); } @Override @@ -26,15 +23,15 @@ public class ArrowRain extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(20*modifiers.get(WizardryItems.range_upgrade), world, caster, false); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(20*rangeMultiplier, world, caster, false); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ if(!world.isRemote){ - double x = rayTrace.hitVec.xCoord; - double y = rayTrace.hitVec.yCoord; - double z = rayTrace.hitVec.zCoord; + double x = rayTrace.blockX; + double y = rayTrace.blockY; + double z = rayTrace.blockZ; // Moves the entity back towards the caster a bit, so the area of effect is better centred on the position. // 3.0d is the distance to move the entity back towards the caster. double dx = caster.posX - x; @@ -43,12 +40,12 @@ public class ArrowRain extends Spell { x += dx*distRatio; z += dz*distRatio; - EntityArrowRain arrowrain = new EntityArrowRain(world, x, y + 5, z, caster, (int)(120*modifiers.get(WizardryItems.duration_upgrade)), modifiers.get(SpellModifiers.DAMAGE)); + EntityArrowRain arrowrain = new EntityArrowRain(world, x, y + 5, z, caster, (int)(120*durationMultiplier), damageMultiplier); arrowrain.rotationYaw = caster.rotationYawHead; world.spawnEntityInWorld(arrowrain); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SUMMONING, 1.0F, 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:darkaura", 1.0F, 1.0F); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/Banish.java b/src/main/java/electroblob/wizardry/spell/Banish.java index 8bf92bec..1f298427 100644 --- a/src/main/java/electroblob/wizardry/spell/Banish.java +++ b/src/main/java/electroblob/wizardry/spell/Banish.java @@ -1,56 +1,52 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.entity.construct.EntityBubble; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.MathHelper; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class Banish extends Spell { public Banish() { - super(Tier.APPRENTICE, 15, Element.NECROMANCY, "banish", SpellType.ATTACK, 40, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 15, EnumElement.NECROMANCY, "banish", EnumSpellType.ATTACK, 40, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - Vec3d look = caster.getLookVec(); + Vec3 look = caster.getLookVec(); - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ EntityLivingBase target = (EntityLivingBase) rayTrace.entityHit; - double radius = (8 + world.rand.nextDouble()*8) * modifiers.get(WizardryItems.range_upgrade); + double radius = (8 + world.rand.nextDouble()*8) * rangeMultiplier; double angle = world.rand.nextDouble()*Math.PI*2; int x = MathHelper.floor_double(target.posX + Math.sin(angle)*radius); int z = MathHelper.floor_double(target.posZ - Math.cos(angle)*radius); - int y = WizardryUtilities.getNearestFloorLevel(world, new BlockPos(x, (int)caster.getEntityBoundingBox().minY, z), (int)radius); + int y = WizardryUtilities.getNearestFloorLevel(world, x, (int)caster.boundingBox.minY, z, (int)radius); if(world.isRemote){ for(int i=0;i<10;i++){ double dx1 = target.posX; - double dy1 = target.getEntityBoundingBox().minY + target.height*world.rand.nextFloat(); + double dy1 = target.boundingBox.minY + target.height*world.rand.nextFloat(); double dz1 = target.posZ; - world.spawnParticle(EnumParticleTypes.PORTAL, dx1, dy1, dz1, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5); + world.spawnParticle("portal", dx1, dy1, dz1, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5); } } @@ -58,11 +54,11 @@ public class Banish extends Spell { // This means stuff like snow layers is ignored, meaning when on snow-covered ground the caster does // not teleport 1 block above the ground. - if(!world.getBlockState(new BlockPos(x, y, z)).getMaterial().blocksMovement()){ + if(!world.getBlock(x, y, z).getMaterial().blocksMovement()){ y--; } - if(world.getBlockState(new BlockPos(x, y + 1, z)).getMaterial().blocksMovement() || world.getBlockState(new BlockPos(x, y + 2, z)).getMaterial().blocksMovement()){ + if(world.getBlock(x, y + 1, z).getMaterial().blocksMovement() || world.getBlock(x, y + 2, z).getMaterial().blocksMovement()){ return false; } @@ -70,37 +66,37 @@ public class Banish extends Spell { target.setPositionAndUpdate(x + 0.5, y + 1, z + 0.5); } - target.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f); + world.playSoundAtEntity(target, "mob.endermen.portal", 1.0F, 1.0f); } } if(world.isRemote){ - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ double x1 = caster.posX + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - world.spawnParticle(EnumParticleTypes.PORTAL, x1, y1 - 0.5, z1, 0.0d, 0.0d, 0.0d); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.2f, 0.0f, 0.2f); + world.spawnParticle("portal", x1, y1 - 0.5, z1, 0.0d, 0.0d, 0.0d); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.2f, 0.0f, 0.2f); } } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f); - caster.swingArm(hand); + world.playSoundAtEntity(caster, "mob.endermen.portal", 1.0F, 1.0f); + caster.swingItem(); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ - double radius = (8 + world.rand.nextDouble()*8) * modifiers.get(WizardryItems.range_upgrade); + double radius = (8 + world.rand.nextDouble()*8) * rangeMultiplier; double angle = world.rand.nextDouble()*Math.PI*2; int x = MathHelper.floor_double(target.posX + Math.sin(angle)*radius); int z = MathHelper.floor_double(target.posZ - Math.cos(angle)*radius); - int y = WizardryUtilities.getNearestFloorLevel(world, new BlockPos(x, (int)caster.getEntityBoundingBox().minY, z), (int)radius); + int y = WizardryUtilities.getNearestFloorLevel(world, x, (int)caster.boundingBox.minY, z, (int)radius); if(world.isRemote){ @@ -114,15 +110,15 @@ public class Banish extends Spell { double y1 = caster.posY + caster.getEyeHeight() - 0.4f + dy*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + dz*i/2 + world.rand.nextFloat()/5 - 0.1f; - world.spawnParticle(EnumParticleTypes.PORTAL, x1, y1 - 0.5, z1, 0.0d, 0.0d, 0.0d); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.2f, 0.0f, 0.2f); + world.spawnParticle("portal", x1, y1 - 0.5, z1, 0.0d, 0.0d, 0.0d); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.2f, 0.0f, 0.2f); } for(int i=0;i<10;i++){ double dx1 = target.posX; - double dy1 = target.getEntityBoundingBox().minY + target.height*world.rand.nextFloat(); + double dy1 = target.boundingBox.minY + target.height*world.rand.nextFloat(); double dz1 = target.posZ; - world.spawnParticle(EnumParticleTypes.PORTAL, dx1, dy1, dz1, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5); + world.spawnParticle("portal", dx1, dy1, dz1, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5); } } @@ -130,11 +126,11 @@ public class Banish extends Spell { // This means stuff like snow layers is ignored, meaning when on snow-covered ground the caster does // not teleport 1 block above the ground. - if(!world.getBlockState(new BlockPos(x, y, z)).getMaterial().blocksMovement()){ + if(!world.getBlock(x, y, z).getMaterial().blocksMovement()){ y--; } - if(world.getBlockState(new BlockPos(x, y + 1, z)).getMaterial().blocksMovement() || world.getBlockState(new BlockPos(x, y + 2, z)).getMaterial().blocksMovement()){ + if(world.getBlock(x, y + 1, z).getMaterial().blocksMovement() || world.getBlock(x, y + 2, z).getMaterial().blocksMovement()){ return false; } @@ -142,12 +138,12 @@ public class Banish extends Spell { target.setPositionAndUpdate(x + 0.5, y + 1, z + 0.5); } - target.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f); + world.playSoundAtEntity(target, "mob.endermen.portal", 1.0F, 1.0f); } } - caster.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f); - caster.swingArm(hand); + world.playSoundAtEntity(caster, "mob.endermen.portal", 1.0F, 1.0f); + caster.swingItem(); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/BlackHole.java b/src/main/java/electroblob/wizardry/spell/BlackHole.java index 3cfcd267..29b14cb8 100644 --- a/src/main/java/electroblob/wizardry/spell/BlackHole.java +++ b/src/main/java/electroblob/wizardry/spell/BlackHole.java @@ -1,24 +1,20 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.construct.EntityBlackHole; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class BlackHole extends Spell { public BlackHole() { - super(Tier.MASTER, 150, Element.SORCERY, "black_hole", SpellType.ATTACK, 400, EnumAction.NONE, false); + super(EnumTier.MASTER, 150, EnumElement.SORCERY, "black_hole", EnumSpellType.ATTACK, 400, EnumAction.none, false); } @Override @@ -27,36 +23,81 @@ public class BlackHole extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(10*modifiers.get(WizardryItems.range_upgrade), world, caster, false); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(10*rangeMultiplier, world, caster, false); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ - - // This demonstrates beautifully the elegance of BlockPos. In 1.7.10 this required a 50-line long switch - // statement and a flag variable; now it only needs a few lines. - BlockPos pos = new BlockPos(rayTrace.hitVec).offset(rayTrace.sideHit); - - if(world.isAirBlock(pos)){ - - if(!world.isRemote){ - world.spawnEntityInWorld(new EntityBlackHole(world, pos.getX()+0.5, pos.getY()-1+0.5, pos.getZ()+0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), modifiers.get(SpellModifiers.DAMAGE))); + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ + int blockHitX = rayTrace.blockX; + int blockHitY = rayTrace.blockY; + int blockHitZ = rayTrace.blockZ; + //world.playSound(blockHitX, blockHitY, blockHitZ, "sound/ambient/cave/cave2", 1.0f, 1.5f, false); + int blockHitSide = rayTrace.sideHit; + boolean flag2 = false; + switch(blockHitSide){ + case 0: + if(world.isAirBlock(blockHitX, blockHitY-1, blockHitZ)){ + if(!world.isRemote){ + world.spawnEntityInWorld(new EntityBlackHole(world, (double)blockHitX+0.5, (double)blockHitY-1+0.5, (double)blockHitZ+0.5, caster, (int)(600*durationMultiplier), damageMultiplier)); + } + flag2 = true; } - - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SPAWN, 2.0f, 0.7f); + break; + case 1: + if(world.isAirBlock(blockHitX, blockHitY+1, blockHitZ)){ + if(!world.isRemote){ + world.spawnEntityInWorld(new EntityBlackHole(world, (double)blockHitX+0.5, (double)blockHitY+1+0.5, (double)blockHitZ+0.5, caster, (int)(600*durationMultiplier), damageMultiplier)); + } + flag2 = true; + } + break; + case 2: + if(world.isAirBlock(blockHitX, blockHitY, blockHitZ-1)){ + if(!world.isRemote){ + world.spawnEntityInWorld(new EntityBlackHole(world, (double)blockHitX+0.5, (double)blockHitY+0.5, (double)blockHitZ-1+0.5, caster, (int)(600*durationMultiplier), damageMultiplier)); + } + flag2 = true; + } + break; + case 3: + if(world.isAirBlock(blockHitX, blockHitY, blockHitZ+1)){ + if(!world.isRemote){ + world.spawnEntityInWorld(new EntityBlackHole(world, (double)blockHitX+0.5, (double)blockHitY+0.5, (double)blockHitZ+1+0.5, caster, (int)(600*durationMultiplier), damageMultiplier)); + } + flag2 = true; + } + break; + case 4: + if(world.isAirBlock(blockHitX-1, blockHitY, blockHitZ)){ + if(!world.isRemote){ + world.spawnEntityInWorld(new EntityBlackHole(world, (double)blockHitX-1+0.5, (double)blockHitY+0.5, (double)blockHitZ+0.5, caster, (int)(600*durationMultiplier), damageMultiplier)); + } + flag2 = true; + } + break; + case 5: + if(world.isAirBlock(blockHitX+1, blockHitY, blockHitZ)){ + if(!world.isRemote){ + world.spawnEntityInWorld(new EntityBlackHole(world, (double)blockHitX+1, (double)blockHitY, (double)blockHitZ, caster, (int)(600*durationMultiplier), damageMultiplier)); + } + flag2 = true; + } + break; + } + if(flag2){ + caster.swingItem(); + world.playSoundAtEntity(caster, "mob.wither.spawn", 2.0f, 0.7f); return true; } - }else{ int x = (int) (Math.floor(caster.posX) + caster.getLookVec().xCoord*8); int y = (int) (Math.floor(caster.posY) + caster.eyeHeight + caster.getLookVec().yCoord*8); int z = (int) (Math.floor(caster.posZ) + caster.getLookVec().zCoord*8); if(!world.isRemote){ - world.spawnEntityInWorld(new EntityBlackHole(world, x, y, z, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), modifiers.get(SpellModifiers.DAMAGE))); + world.spawnEntityInWorld(new EntityBlackHole(world, x, y, z, caster, (int)(600*durationMultiplier), damageMultiplier)); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SPAWN, 2.0f, 0.7f); + caster.swingItem(); + world.playSoundAtEntity(caster, "mob.wither.spawn", 2.0f, 0.7f); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/Blink.java b/src/main/java/electroblob/wizardry/spell/Blink.java index 3353d686..68f41a0c 100644 --- a/src/main/java/electroblob/wizardry/spell/Blink.java +++ b/src/main/java/electroblob/wizardry/spell/Blink.java @@ -1,75 +1,115 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.entity.living.EntityWizard; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.ai.EntityAIArrowAttack; +import net.minecraft.entity.ai.EntityAITasks.EntityAITaskEntry; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MathHelper; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class Blink extends Spell { public Blink() { - super(Tier.APPRENTICE, 15, Element.SORCERY, "blink", SpellType.UTILITY, 25, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 15, EnumElement.SORCERY, "blink", EnumSpellType.UTILITY, 25, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(25*modifiers.get(WizardryItems.range_upgrade), world, caster, false); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(25*rangeMultiplier, world, caster, false); // It's worth noting that on the client side, the cast() method only gets called if the server side // cast method succeeded, so you need not check any conditions for spawning particles. if(world.isRemote){ for(int i=0;i<10;i++){ - double dx = caster.posX; - double dy = caster.getEntityBoundingBox().minY + 2*world.rand.nextFloat(); - double dz = caster.posZ; + double dx1 = caster.posX; + double dy1 = WizardryUtilities.getPlayerEyesPos(caster) - 1.5 + 2*world.rand.nextFloat(); + double dz1 = caster.posZ; // For portal particles, velocity is not velocity but the offset where they start, then drift to // the actual position given. - world.spawnParticle(EnumParticleTypes.PORTAL, dx, dy, dz, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5); + world.spawnParticle("portal", dx1, dy1, dz1, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5); } } - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ - BlockPos pos = rayTrace.getBlockPos(); - - // Can't teleport onto the ceiling. - if(rayTrace.sideHit == EnumFacing.DOWN) return false; + int blockHitX = rayTrace.blockX; + int blockHitY = rayTrace.blockY; + int blockHitZ = rayTrace.blockZ; + int blockHitSide = rayTrace.sideHit; // This means stuff like snow layers is ignored, meaning when on snow-covered ground the player does // not teleport 1 block above the ground. - if(rayTrace.sideHit == EnumFacing.UP && !world.getBlockState(pos).getMaterial().blocksMovement()){ - pos = pos.down(); + if(blockHitSide == 1 && !world.getBlock(blockHitX, blockHitY, blockHitZ).getMaterial().blocksMovement()){ + blockHitY--; } - pos = rayTrace.getBlockPos().offset(rayTrace.sideHit); - - // Prevents the player from teleporting into blocks and suffocating. - if(world.getBlockState(pos).getMaterial().blocksMovement() || world.getBlockState(pos.up()).getMaterial().blocksMovement()){ + // The following prevents the player from teleporting into blocks and suffocating + switch(blockHitSide){ + case -1: return false; + case 0: + return false; + case 1: + if(world.getBlock(blockHitX, blockHitY + 1, blockHitZ).getMaterial().blocksMovement() || world.getBlock(blockHitX, blockHitY + 2, blockHitZ).getMaterial().blocksMovement()){ + return false; + } + break; + case 2: + if(world.getBlock(blockHitX, blockHitY, blockHitZ - 1).getMaterial().blocksMovement() || world.getBlock(blockHitX, blockHitY + 1, blockHitZ - 1).getMaterial().blocksMovement()){ + return false; + } + break; + case 3: + if(world.getBlock(blockHitX, blockHitY, blockHitZ + 1).getMaterial().blocksMovement() || world.getBlock(blockHitX, blockHitY + 1, blockHitZ + 1).getMaterial().blocksMovement()){ + return false; + } + break; + case 4: + if(world.getBlock(blockHitX - 1, blockHitY, blockHitZ).getMaterial().blocksMovement() || world.getBlock(blockHitX - 1, blockHitY + 1, blockHitZ).getMaterial().blocksMovement()){ + return false; + } + break; + case 5: + if(world.getBlock(blockHitX + 1, blockHitY, blockHitZ).getMaterial().blocksMovement() || world.getBlock(blockHitX + 1, blockHitY + 1, blockHitZ).getMaterial().blocksMovement()){ + return false; + } + break; } - + // Plays before and after so it is heard from both positions - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f); + world.playSoundAtEntity(caster, "mob.endermen.portal", 1.0F, 1.0f); - if(!world.isRemote) caster.setPositionAndUpdate(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5); - - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f); - caster.swingArm(hand); + if(!world.isRemote){ + switch(blockHitSide){ + case 1: + caster.setPositionAndUpdate(blockHitX + 0.5, blockHitY + 1, blockHitZ + 0.5); + break; + case 2: + caster.setPositionAndUpdate(blockHitX + 0.5, blockHitY, blockHitZ - 0.5); + break; + case 3: + caster.setPositionAndUpdate(blockHitX + 0.5, blockHitY, blockHitZ + 1.5); + break; + case 4: + caster.setPositionAndUpdate(blockHitX - 0.5, blockHitY, blockHitZ + 0.5); + break; + case 5: + caster.setPositionAndUpdate(blockHitX + 1.5, blockHitY, blockHitZ + 0.5); + break; + } + } + world.playSoundAtEntity(caster, "mob.endermen.portal", 1.0F, 1.0f); + caster.swingItem(); return true; } @@ -77,14 +117,14 @@ public class Blink extends Spell { } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ double angle = Math.atan2(target.posZ - caster.posZ, target.posX - caster.posX) + world.rand.nextDouble()*Math.PI; - double radius = caster.getDistance(target.posX, target.getEntityBoundingBox().minY, target.posZ) + world.rand.nextDouble()*3.0d; + double radius = caster.getDistance(target.posX, target.boundingBox.minY, target.posZ) + world.rand.nextDouble()*3.0d; int x = MathHelper.floor_double(target.posX + Math.sin(angle)*radius); int z = MathHelper.floor_double(target.posZ - Math.cos(angle)*radius); - int y = WizardryUtilities.getNearestFloorLevel(world, new BlockPos(caster), (int)radius); + int y = WizardryUtilities.getNearestFloorLevel(world, x, (int)caster.boundingBox.minY, z, (int)radius); // It's worth noting that on the client side, the cast() method only gets called if the server side // cast method succeeded, so you need not check any conditions for spawning particles. @@ -93,9 +133,9 @@ public class Blink extends Spell { if(world.isRemote){ for(int i=0;i<10;i++){ double dx1 = caster.posX; - double dy1 = caster.getEntityBoundingBox().minY + caster.height*world.rand.nextFloat(); + double dy1 = caster.boundingBox.minY + caster.height*world.rand.nextFloat(); double dz1 = caster.posZ; - world.spawnParticle(EnumParticleTypes.PORTAL, dx1, dy1, dz1, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5); + world.spawnParticle("portal", dx1, dy1, dz1, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5); } } @@ -103,23 +143,23 @@ public class Blink extends Spell { // This means stuff like snow layers is ignored, meaning when on snow-covered ground the caster does // not teleport 1 block above the ground. - if(!world.getBlockState(new BlockPos(x, y, z)).getMaterial().blocksMovement()){ + if(!world.getBlock(x, y, z).getMaterial().blocksMovement()){ y--; } - if(world.getBlockState(new BlockPos(x, y + 1, z)).getMaterial().blocksMovement() || world.getBlockState(new BlockPos(x, y + 2, z)).getMaterial().blocksMovement()){ + if(world.getBlock(x, y + 1, z).getMaterial().blocksMovement() || world.getBlock(x, y + 2, z).getMaterial().blocksMovement()){ return false; } // Plays before and after so it is heard from both positions - caster.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f); + world.playSoundAtEntity(caster, "mob.endermen.portal", 1.0F, 1.0f); if(!world.isRemote){ caster.setPositionAndUpdate(x + 0.5, y + 1, z + 0.5); } - caster.playSound(SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f); - caster.swingArm(hand); + world.playSoundAtEntity(caster, "mob.endermen.portal", 1.0F, 1.0f); + caster.swingItem(); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Blizzard.java b/src/main/java/electroblob/wizardry/spell/Blizzard.java index 8f2066db..4fd66b1e 100644 --- a/src/main/java/electroblob/wizardry/spell/Blizzard.java +++ b/src/main/java/electroblob/wizardry/spell/Blizzard.java @@ -1,25 +1,22 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.construct.EntityBlizzard; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class Blizzard extends Spell { public Blizzard() { - super(Tier.ADVANCED, 40, Element.ICE, "blizzard", SpellType.ATTACK, 100, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 40, EnumElement.ICE, "blizzard", EnumSpellType.ATTACK, 100, EnumAction.none, false); } @Override @@ -28,27 +25,27 @@ public class Blizzard extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(20*modifiers.get(WizardryItems.range_upgrade), world, caster, false); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(20*rangeMultiplier, world, caster, false); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ if(!world.isRemote){ - double x = rayTrace.hitVec.xCoord; - double y = rayTrace.hitVec.yCoord; - double z = rayTrace.hitVec.zCoord; - EntityBlizzard blizzard = new EntityBlizzard(world, x, y+0.5, z, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), modifiers.get(SpellModifiers.DAMAGE)); + double x = rayTrace.blockX; + double y = rayTrace.blockY; + double z = rayTrace.blockZ; + EntityBlizzard blizzard = new EntityBlizzard(world, x, y+1.5, z, caster, (int)(600*durationMultiplier), damageMultiplier); world.spawnEntityInWorld(blizzard); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, 1.0F); return true; } return false; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ @@ -56,11 +53,11 @@ public class Blizzard extends Spell { double x = target.posX; double y = target.posY; double z = target.posZ; - EntityBlizzard blizzard = new EntityBlizzard(world, x, y+0.5, z, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), modifiers.get(SpellModifiers.DAMAGE)); + EntityBlizzard blizzard = new EntityBlizzard(world, x, y+0.5, z, caster, (int)(600*durationMultiplier), damageMultiplier); world.spawnEntityInWorld(blizzard); } - caster.swingArm(hand); - caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Bubble.java b/src/main/java/electroblob/wizardry/spell/Bubble.java index c9c425d1..0ea7f8a7 100644 --- a/src/main/java/electroblob/wizardry/spell/Bubble.java +++ b/src/main/java/electroblob/wizardry/spell/Bubble.java @@ -1,80 +1,75 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.entity.construct.EntityBubble; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class Bubble extends Spell { public Bubble() { - super(Tier.APPRENTICE, 15, Element.EARTH, "bubble", SpellType.ATTACK, 20, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 15, EnumElement.EARTH, "bubble", EnumSpellType.ATTACK, 20, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - Vec3d look = caster.getLookVec(); + Vec3 look = caster.getLookVec(); - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ EntityLivingBase entity = (EntityLivingBase) rayTrace.entityHit; if(!world.isRemote){ - entity.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC), 1.0f * modifiers.get(SpellModifiers.DAMAGE)); + entity.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC), 1.0f * damageMultiplier); // Deprecated in favour of entity riding method - //entity.addPotionEffect(new PotionEffect(Wizardry.bubblePotion, 200, 0)); - EntityBubble entitybubble = new EntityBubble(world, entity.posX, entity.posY, entity.posZ, caster, (int)(200*modifiers.get(WizardryItems.duration_upgrade)), false, modifiers.get(SpellModifiers.DAMAGE)); + //entity.addPotionEffect(new PotionEffect(Wizardry.bubblePotion.id, 200, 0)); + EntityBubble entitybubble = new EntityBubble(world, entity.posX, entity.posY, entity.posZ, caster, (int)(200*durationMultiplier), false, damageMultiplier); world.spawnEntityInWorld(entitybubble); - entity.startRiding(entitybubble); + entity.mountEntity(entitybubble); } } if(world.isRemote){ - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ double x1 = caster.posX + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - world.spawnParticle(EnumParticleTypes.WATER_SPLASH, x1, y1, z1, 0.0d, 0.0d, 0.0d); - Wizardry.proxy.spawnParticle(WizardryParticleType.MAGIC_BUBBLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0); + world.spawnParticle("splash", x1, y1, z1, 0.0d, 0.0d, 0.0d); + Wizardry.proxy.spawnParticle(EnumParticleType.MAGIC_BUBBLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0); } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_GENERIC_SWIM, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 0.5F, world.rand.nextFloat() * 0.2F + 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "game.neutral.swim", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:ice", 0.5F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC), 1.0f * modifiers.get(SpellModifiers.DAMAGE)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC), 1.0f * damageMultiplier); // Deprecated in favour of entity riding method - //entity.addPotionEffect(new PotionEffect(Wizardry.bubblePotion, 200, 0)); - EntityBubble entitybubble = new EntityBubble(world, target.posX, target.posY, target.posZ, caster, (int)(200*modifiers.get(WizardryItems.duration_upgrade)), false, modifiers.get(SpellModifiers.DAMAGE)); + //entity.addPotionEffect(new PotionEffect(Wizardry.bubblePotion.id, 200, 0)); + EntityBubble entitybubble = new EntityBubble(world, target.posX, target.posY, target.posZ, caster, (int)(200*durationMultiplier), false, damageMultiplier); world.spawnEntityInWorld(entitybubble); - target.startRiding(entitybubble); + target.mountEntity(entitybubble); } if(world.isRemote){ @@ -83,19 +78,19 @@ public class Bubble extends Spell { double dy = (target.posY - caster.posY)/caster.getDistanceToEntity(target); double dz = (target.posZ - caster.posZ)/caster.getDistanceToEntity(target); - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ double x1 = caster.posX + dx*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = caster.posY + caster.getEyeHeight() - 0.4f + dy*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + dz*i/2 + world.rand.nextFloat()/5 - 0.1f; - world.spawnParticle(EnumParticleTypes.WATER_SPLASH, x1, y1, z1, 0.0d, 0.0d, 0.0d); - Wizardry.proxy.spawnParticle(WizardryParticleType.MAGIC_BUBBLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0); + world.spawnParticle("splash", x1, y1, z1, 0.0d, 0.0d, 0.0d); + Wizardry.proxy.spawnParticle(EnumParticleType.MAGIC_BUBBLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0); } } - caster.swingArm(hand); - caster.playSound(SoundEvents.ENTITY_GENERIC_SWIM, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); - caster.playSound(WizardrySounds.SPELL_ICE, 0.5F, world.rand.nextFloat() * 0.2F + 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "game.neutral.swim", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:ice", 0.5F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/ChainLightning.java b/src/main/java/electroblob/wizardry/spell/ChainLightning.java index 1b678ba5..491e653e 100644 --- a/src/main/java/electroblob/wizardry/spell/ChainLightning.java +++ b/src/main/java/electroblob/wizardry/spell/ChainLightning.java @@ -2,43 +2,41 @@ package electroblob.wizardry.spell; import java.util.List; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.entity.EntityArc; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.entity.living.EntityLightningWraith; +import electroblob.wizardry.entity.living.EntityStormElemental; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityCreeper; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; public class ChainLightning extends Spell { public ChainLightning() { - super(Tier.ADVANCED, 25, Element.LIGHTNING, "chain_lightning", SpellType.ATTACK, 50, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 25, EnumElement.LIGHTNING, "chain_lightning", EnumSpellType.ATTACK, 50, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { // First shot has range 10 (this is the only range affected by upgrades) and does 5 hearts of damage. // Chains to up to 5 secondary targets within a range of 5 of the primary target, and then to up to 2 // tertiary targets per secondary target within a range of 5 of that. Secondary targets are dealt 4 hearts // of damage; tertiary targets are dealt 3 hearts of damage. - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade), 8.0f); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier, 8.0f); // Anything can be attacked with the initial arc, because the player has control over where it goes. If they // hit a minion or an ally, it's their problem! @@ -53,17 +51,17 @@ public class ChainLightning extends Spell { world.spawnEntityInWorld(arc); }else{ for(int i=0;i<8;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, target.posX + world.rand.nextFloat() - 0.5, target.getEntityBoundingBox().minY + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); - world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, target.posX + world.rand.nextFloat() - 0.5, target.getEntityBoundingBox().minY + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, world, target.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(target) + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); + world.spawnParticle("largesmoke", target.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(target) + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); } } - target.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); + world.playSoundAtEntity(target, "wizardry:arc", 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); if(MagicDamage.isEntityImmune(DamageType.SHOCK, target)){ - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", target.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", target.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else{ - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 10.0f * modifiers.get(SpellModifiers.DAMAGE)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 10.0f * damageMultiplier); } // Secondary chaining effect @@ -84,17 +82,17 @@ public class ChainLightning extends Spell { world.spawnEntityInWorld(arc); }else{ for(int j=0;j<8;j++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, secondaryTarget.posX + world.rand.nextFloat() - 0.5, secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height/2 + world.rand.nextFloat()*2 - 1, secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); - world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, secondaryTarget.posX + world.rand.nextFloat() - 0.5, secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height/2 + world.rand.nextFloat()*2 - 1, secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, world, secondaryTarget.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(secondaryTarget) + secondaryTarget.height/2 + world.rand.nextFloat()*2 - 1, secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); + world.spawnParticle("largesmoke", secondaryTarget.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(secondaryTarget) + secondaryTarget.height/2 + world.rand.nextFloat()*2 - 1, secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); } } - secondaryTarget.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); + world.playSoundAtEntity(secondaryTarget, "wizardry:arc", 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); if(MagicDamage.isEntityImmune(DamageType.SHOCK, secondaryTarget)){ - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", secondaryTarget.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", secondaryTarget.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else{ - secondaryTarget.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 8.0f * modifiers.get(SpellModifiers.DAMAGE)); + secondaryTarget.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 8.0f * damageMultiplier); } // Tertiary chaining effect @@ -114,24 +112,24 @@ public class ChainLightning extends Spell { world.spawnEntityInWorld(arc); }else{ for(int k=0;k<8;k++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, tertiaryTarget.posX + world.rand.nextFloat() - 0.5, tertiaryTarget.getEntityBoundingBox().minY + tertiaryTarget.height/2 + world.rand.nextFloat()*2 - 1, tertiaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); - world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, tertiaryTarget.posX + world.rand.nextFloat() - 0.5, tertiaryTarget.getEntityBoundingBox().minY + tertiaryTarget.height/2 + world.rand.nextFloat()*2 - 1, tertiaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, world, tertiaryTarget.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(tertiaryTarget) + tertiaryTarget.height/2 + world.rand.nextFloat()*2 - 1, tertiaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); + world.spawnParticle("largesmoke", tertiaryTarget.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(tertiaryTarget) + tertiaryTarget.height/2 + world.rand.nextFloat()*2 - 1, tertiaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); } } - tertiaryTarget.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); + world.playSoundAtEntity(tertiaryTarget, "wizardry:arc", 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); if(MagicDamage.isEntityImmune(DamageType.SHOCK, tertiaryTarget)){ - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", tertiaryTarget.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", tertiaryTarget.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else{ - tertiaryTarget.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 6.0f * modifiers.get(SpellModifiers.DAMAGE)); + tertiaryTarget.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 6.0f * damageMultiplier); } } } } } - caster.swingArm(hand); + caster.swingItem(); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/Clairvoyance.java b/src/main/java/electroblob/wizardry/spell/Clairvoyance.java index 816a02f0..11a65283 100644 --- a/src/main/java/electroblob/wizardry/spell/Clairvoyance.java +++ b/src/main/java/electroblob/wizardry/spell/Clairvoyance.java @@ -1,163 +1,104 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.WizardData; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.item.ItemWand; import electroblob.wizardry.packet.PacketClairvoyance; import electroblob.wizardry.packet.WizardryPacketHandler; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WandHelper; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryPathFinder; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.entity.SharedMonsterAttributes; -import net.minecraft.entity.monster.EntityZombie; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.EnumAction; -import net.minecraft.item.ItemStack; -import net.minecraft.pathfinding.Path; -import net.minecraft.pathfinding.PathNodeType; +import net.minecraft.pathfinding.PathEntity; import net.minecraft.pathfinding.PathPoint; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; import net.minecraft.world.World; -import net.minecraftforge.event.entity.player.PlayerInteractEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -@Mod.EventBusSubscriber public class Clairvoyance extends Spell { - + /** The number of ticks it takes each path particle to move from one path point to the next. */ public static final int PARTICLE_MOVEMENT_INTERVAL = 45; - public Clairvoyance(){ - super(Tier.APPRENTICE, 20, Element.SORCERY, "clairvoyance", SpellType.UTILITY, 100, EnumAction.BOW, false); + public Clairvoyance() { + super(EnumTier.APPRENTICE, 20, EnumElement.SORCERY, "clairvoyance", EnumSpellType.UTILITY, 100, EnumAction.bow, false); } - + @Override public boolean doesSpellRequirePacket(){ return false; } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - WizardData properties = WizardData.get(caster); + ExtendedPlayer properties = ExtendedPlayer.get(caster); if(properties != null && !caster.isSneaking()){ - if(caster.dimension == properties.getClairvoyanceDimension()){ - if(properties.getClairvoyanceLocation() != null){ - - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.clairvoyance.searching")); - - EntityZombie arbitraryZombie = new EntityZombie(world){ - @Override public float getBlockPathWeight(BlockPos pos){ return 0; } - }; - arbitraryZombie.getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).setBaseValue(256*modifiers.get(WizardryItems.range_upgrade)); - arbitraryZombie.setPosition(caster.posX, caster.posY, caster.posZ); - arbitraryZombie.setPathPriority(PathNodeType.WATER, 0.0F); - arbitraryZombie.onGround = true; - - BlockPos destination = properties.getClairvoyanceLocation(); + if(caster.dimension == properties.clairvoyanceDimension){ + // Has to be y since x and z could reasonably be -1. + if(properties.clairvoyanceY > -1){ - WizardryPathFinder pathfinder = new WizardryPathFinder(arbitraryZombie.getNavigator().getNodeProcessor()); - - Path path = pathfinder.findPath(world, arbitraryZombie, destination, 256*modifiers.get(WizardryItems.range_upgrade)); - - if(path != null && path.getFinalPathPoint() != null){ - - int x = path.getFinalPathPoint().xCoord; - int y = path.getFinalPathPoint().yCoord; - int z = path.getFinalPathPoint().zCoord; - - if(x == destination.getX() && y == destination.getY() && z == destination.getZ()){ + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.clairvoyance.searching")); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f); + // Parameters: entity, x, y, z, range, passOpenDoors, passClosedDoors, avoidWater, canSwim + PathEntity path = world.getEntityPathToXYZ(caster, properties.clairvoyanceX, properties.clairvoyanceY, properties.clairvoyanceZ, 256*rangeMultiplier, true, true, false, true); - if(!world.isRemote && caster instanceof EntityPlayerMP){ - WizardryPacketHandler.net.sendTo(new PacketClairvoyance.Message(path, modifiers.get(WizardryItems.duration_upgrade)), (EntityPlayerMP)caster); - } + // If the coordinates weren't checked, the path might not lead to the correct location. + if(path != null && path.getFinalPathPoint() != null + && path.getFinalPathPoint().xCoord == properties.clairvoyanceX + && path.getFinalPathPoint().yCoord == properties.clairvoyanceY + && path.getFinalPathPoint().zCoord == properties.clairvoyanceZ){ - return true; + world.playSoundAtEntity(caster, "wizardry:aura", 1.0f, 1.0f); + + // TODO: When the chunk the destination is in is not loaded, the particles don't spawn. + // I think I can fix this by sending the path positions in a packet to the caster, with the + // added benefit of only spawning them on that player's client. + if(!world.isRemote && caster instanceof EntityPlayerMP){ + WizardryPacketHandler.net.sendTo(new PacketClairvoyance.Message(path, durationMultiplier), (EntityPlayerMP)caster); } + + return true; + + }else{ + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.clairvoyance.outofrange")); } - - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.clairvoyance.outofrange")); - }else{ - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.clairvoyance.undefined")); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.clairvoyance.undefined")); } }else{ - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.clairvoyance.wrongdimension")); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.clairvoyance.wrongdimension")); } } - // Fixes the problem with the sound not playing for the client of the caster. - if(world.isRemote) WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f); - return false; } - - public static void spawnPathPaticles(World world, Path path, float durationMultiplier){ + + public static void spawnPathPaticles(World world, PathEntity path, float durationMultiplier) { PathPoint point, nextPoint; while(!path.isFinished()){ - + point = path.getPathPointFromIndex(path.getCurrentPathIndex()); if(point == path.getFinalPathPoint()) break; nextPoint = path.getCurrentPathLength() - path.getCurrentPathIndex() <= 2 ? path.getFinalPathPoint() : path.getPathPointFromIndex(path.getCurrentPathIndex() + 2); - - Wizardry.proxy.spawnParticle(WizardryParticleType.PATH, world, point.xCoord + 0.5, point.yCoord + 0.5, point.zCoord + 0.5, + + Wizardry.proxy.spawnParticle(EnumParticleType.PATH, world, point.xCoord + 0.5, point.yCoord + 0.5, point.zCoord + 0.5, (nextPoint.xCoord - point.xCoord)/(float)PARTICLE_MOVEMENT_INTERVAL, (nextPoint.yCoord - point.yCoord)/(float)PARTICLE_MOVEMENT_INTERVAL, (nextPoint.zCoord - point.zCoord)/(float)PARTICLE_MOVEMENT_INTERVAL, (int)(1800*durationMultiplier), 0, 1, 0.3f); - + path.incrementPathIndex(); path.incrementPathIndex(); } point = path.getFinalPathPoint(); - Wizardry.proxy.spawnParticle(WizardryParticleType.PATH, world, point.xCoord + 0.5, point.yCoord + 0.5, point.zCoord + 0.5, 0, 0, 0, (int)(1800*durationMultiplier), 1, 1, 1); - } - - @SubscribeEvent - public static void onRightClickBlockEvent(PlayerInteractEvent.RightClickBlock event){ - - if(event.getEntityPlayer().isSneaking()){ - - // The event now has an ItemStack, which greatly simplifies hand-related stuff. - ItemStack wand = event.getItemStack(); - - if(wand != null && wand.getItem() instanceof ItemWand && WandHelper.getCurrentSpell(wand) instanceof Clairvoyance){ - - WizardData properties = WizardData.get(event.getEntityPlayer()); - - if(properties != null){ - // THIS is why BlockPos is a thing - in 1.7.10 this requires a clumsy switch statement. - BlockPos pos = event.getPos().offset(event.getFace()); - - properties.setClairvoyancePoint(pos, event.getWorld().provider.getDimension()); - - if(!event.getWorld().isRemote){ - event.getEntityPlayer().addChatMessage(new TextComponentTranslation("spell.clairvoyance.confirm", Spells.clairvoyance.getNameForTranslationFormatted())); - } - - event.setCanceled(true); - } - } - } + Wizardry.proxy.spawnParticle(EnumParticleType.PATH, world, point.xCoord + 0.5, point.yCoord + 0.5, point.zCoord + 0.5, 0, 0, 0, (int)(1800*durationMultiplier), 1, 1, 1); } } \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/spell/Cobwebs.java b/src/main/java/electroblob/wizardry/spell/Cobwebs.java index b61e33ff..53b62618 100644 --- a/src/main/java/electroblob/wizardry/spell/Cobwebs.java +++ b/src/main/java/electroblob/wizardry/spell/Cobwebs.java @@ -1,23 +1,18 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryBlocks; -import electroblob.wizardry.registry.WizardryItems; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.tileentity.TileEntityTimer; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MathHelper; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class Cobwebs extends Spell { @@ -25,7 +20,7 @@ public class Cobwebs extends Spell { private static final int baseDuration = 400; public Cobwebs() { - super(Tier.ADVANCED, 30, Element.EARTH, "cobwebs", SpellType.ATTACK, 70, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 30, EnumElement.EARTH, "cobwebs", EnumSpellType.ATTACK, 70, EnumAction.none, false); } @Override @@ -34,44 +29,95 @@ public class Cobwebs extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(12*modifiers.get(WizardryItems.range_upgrade), world, caster, true); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(12*rangeMultiplier, world, caster, true); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ + + int blockHitX = rayTrace.blockX; + int blockHitY = rayTrace.blockY; + int blockHitZ = rayTrace.blockZ; + int blockHitSide = rayTrace.sideHit; boolean flag = false; - BlockPos pos = rayTrace.getBlockPos().offset(rayTrace.sideHit); + switch(blockHitSide){ + case 0: blockHitY--; break; + case 1: blockHitY++; break; + case 2: blockHitZ--; break; + case 3: blockHitZ++; break; + case 4: blockHitX--; break; + case 5: blockHitX++; break; + } - if(world.isAirBlock(pos)){ + if(world.isAirBlock(blockHitX, blockHitY, blockHitZ)){ if(!world.isRemote){ - world.setBlockState(pos, WizardryBlocks.vanishing_cobweb.getDefaultState()); - if(world.getTileEntity(pos) instanceof TileEntityTimer){ - ((TileEntityTimer)world.getTileEntity(pos)).setLifetime((int)(baseDuration*modifiers.get(WizardryItems.duration_upgrade))); + world.setBlock(blockHitX, blockHitY, blockHitZ, Wizardry.vanishingCobweb); + if(world.getTileEntity(blockHitX, blockHitY, blockHitZ) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(blockHitX, blockHitY, blockHitZ)).setLifetime((int)(baseDuration*durationMultiplier)); } } flag = true; } - - for(EnumFacing side : EnumFacing.values()){ - - BlockPos pos1 = pos.offset(side); - - if(world.isAirBlock(pos1)){ - if(!world.isRemote){ - world.setBlockState(pos1, WizardryBlocks.vanishing_cobweb.getDefaultState()); - if(world.getTileEntity(pos1) instanceof TileEntityTimer){ - ((TileEntityTimer)world.getTileEntity(pos1)).setLifetime((int)(baseDuration*modifiers.get(WizardryItems.duration_upgrade))); - } + if(world.isAirBlock(blockHitX+1, blockHitY, blockHitZ)){ + if(!world.isRemote){ + world.setBlock(blockHitX+1, blockHitY, blockHitZ, Wizardry.vanishingCobweb); + if(world.getTileEntity(blockHitX+1, blockHitY, blockHitZ) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(blockHitX+1, blockHitY, blockHitZ)).setLifetime((int)(baseDuration*durationMultiplier)); } - flag = true; } + flag = true; + } + if(world.isAirBlock(blockHitX-1, blockHitY, blockHitZ)){ + if(!world.isRemote){ + world.setBlock(blockHitX-1, blockHitY, blockHitZ, Wizardry.vanishingCobweb); + if(world.getTileEntity(blockHitX-1, blockHitY, blockHitZ) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(blockHitX-1, blockHitY, blockHitZ)).setLifetime((int)(baseDuration*durationMultiplier)); + } + } + flag = true; + } + if(world.isAirBlock(blockHitX, blockHitY+1, blockHitZ)){ + if(!world.isRemote){ + world.setBlock(blockHitX, blockHitY+1, blockHitZ, Wizardry.vanishingCobweb); + if(world.getTileEntity(blockHitX, blockHitY+1, blockHitZ) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(blockHitX, blockHitY+1, blockHitZ)).setLifetime((int)(baseDuration*durationMultiplier)); + } + } + flag = true; + } + if(world.isAirBlock(blockHitX, blockHitY-1, blockHitZ)){ + if(!world.isRemote){ + world.setBlock(blockHitX, blockHitY-1, blockHitZ, Wizardry.vanishingCobweb); + if(world.getTileEntity(blockHitX, blockHitY-1, blockHitZ) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(blockHitX, blockHitY-1, blockHitZ)).setLifetime((int)(baseDuration*durationMultiplier)); + } + } + flag = true; + } + if(world.isAirBlock(blockHitX, blockHitY, blockHitZ+1)){ + if(!world.isRemote){ + world.setBlock(blockHitX, blockHitY, blockHitZ+1, Wizardry.vanishingCobweb); + if(world.getTileEntity(blockHitX, blockHitY, blockHitZ+1) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(blockHitX, blockHitY, blockHitZ+1)).setLifetime((int)(baseDuration*durationMultiplier)); + } + } + flag = true; + } + if(world.isAirBlock(blockHitX, blockHitY, blockHitZ-1)){ + if(!world.isRemote){ + world.setBlock(blockHitX, blockHitY, blockHitZ-1, Wizardry.vanishingCobweb); + if(world.getTileEntity(blockHitX, blockHitY, blockHitZ-1) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(blockHitX, blockHitY, blockHitZ-1)).setLifetime((int)(baseDuration*durationMultiplier)); + } + } + flag = true; } if(flag){ - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.BLOCK_LAVA_EXTINGUISH, 1.0f, 1.0f); + caster.swingItem(); + world.playSoundAtEntity(caster, "random.fizz", 1.0f, 1.0f); return true; } } @@ -79,46 +125,83 @@ public class Cobwebs extends Spell { } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers) { + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(target != null){ int x = MathHelper.floor_double(target.posX); - int y = (int)target.getEntityBoundingBox().minY; + int y = (int)target.boundingBox.minY; int z = MathHelper.floor_double(target.posZ); boolean flag = false; - BlockPos pos = new BlockPos(x, y, z); - - if(world.isAirBlock(pos)){ + if(world.isAirBlock(x, y, z)){ if(!world.isRemote){ - world.setBlockState(pos, WizardryBlocks.vanishing_cobweb.getDefaultState()); - if(world.getTileEntity(pos) instanceof TileEntityTimer){ - ((TileEntityTimer)world.getTileEntity(pos)).setLifetime((int)(baseDuration*modifiers.get(WizardryItems.duration_upgrade))); + world.setBlock(x, y, z, Wizardry.vanishingCobweb); + if(world.getTileEntity(x, y, z) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(x, y, z)).setLifetime((int)(baseDuration*durationMultiplier)); } } flag = true; } - - for(EnumFacing side : EnumFacing.values()){ - - BlockPos pos1 = pos.offset(side); - - if(world.isAirBlock(pos1)){ - if(!world.isRemote){ - world.setBlockState(pos1, WizardryBlocks.vanishing_cobweb.getDefaultState()); - if(world.getTileEntity(pos1) instanceof TileEntityTimer){ - ((TileEntityTimer)world.getTileEntity(pos1)).setLifetime((int)(baseDuration*modifiers.get(WizardryItems.duration_upgrade))); - } + if(world.isAirBlock(x+1, y, z)){ + if(!world.isRemote){ + world.setBlock(x+1, y, z, Wizardry.vanishingCobweb); + if(world.getTileEntity(x+1, y, z) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(x+1, y, z)).setLifetime((int)(baseDuration*durationMultiplier)); } - flag = true; } + flag = true; + } + if(world.isAirBlock(x-1, y, z)){ + if(!world.isRemote){ + world.setBlock(x-1, y, z, Wizardry.vanishingCobweb); + if(world.getTileEntity(x-1, y, z) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(x-1, y, z)).setLifetime((int)(baseDuration*durationMultiplier)); + } + } + flag = true; + } + if(world.isAirBlock(x, y+1, z)){ + if(!world.isRemote){ + world.setBlock(x, y+1, z, Wizardry.vanishingCobweb); + if(world.getTileEntity(x, y+1, z) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(x, y+1, z)).setLifetime((int)(baseDuration*durationMultiplier)); + } + } + flag = true; + } + if(world.isAirBlock(x, y-1, z)){ + if(!world.isRemote){ + world.setBlock(x, y-1, z, Wizardry.vanishingCobweb); + if(world.getTileEntity(x, y-1, z) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(x, y-1, z)).setLifetime((int)(baseDuration*durationMultiplier)); + } + } + flag = true; + } + if(world.isAirBlock(x, y, z+1)){ + if(!world.isRemote){ + world.setBlock(x, y, z+1, Wizardry.vanishingCobweb); + if(world.getTileEntity(x, y, z+1) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(x, y, z+1)).setLifetime((int)(baseDuration*durationMultiplier)); + } + } + flag = true; + } + if(world.isAirBlock(x, y, z-1)){ + if(!world.isRemote){ + world.setBlock(x, y, z-1, Wizardry.vanishingCobweb); + if(world.getTileEntity(x, y, z-1) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(x, y, z-1)).setLifetime((int)(baseDuration*durationMultiplier)); + } + } + flag = true; } if(flag){ - caster.swingArm(hand); - caster.playSound(SoundEvents.BLOCK_LAVA_EXTINGUISH, 1.0f, 1.0f); + caster.swingItem(); + world.playSoundAtEntity(caster, "random.fizz", 1.0f, 1.0f); return true; } } diff --git a/src/main/java/electroblob/wizardry/spell/ConjureArmour.java b/src/main/java/electroblob/wizardry/spell/ConjureArmour.java index 0096ff24..505aaed7 100644 --- a/src/main/java/electroblob/wizardry/spell/ConjureArmour.java +++ b/src/main/java/electroblob/wizardry/spell/ConjureArmour.java @@ -1,30 +1,27 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.item.IConjuredItem; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class ConjureArmour extends Spell { public ConjureArmour() { - super(Tier.ADVANCED, 45, Element.HEALING, "conjure_armour", SpellType.DEFENCE, 50, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 45, EnumElement.HEALING, "conjure_armour", EnumSpellType.DEFENCE, 50, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { ItemStack armour; boolean flag = false; @@ -32,34 +29,38 @@ public class ConjureArmour extends Spell { // Note that armourInventory is the other way round! Also note that a blank "ench" tag is set to trick // the renderer into showing the enchantment effect on the actual armour model. - if(caster.inventory.armorInventory[3] == null && !WizardryUtilities.doesPlayerHaveItem(caster, WizardryItems.spectral_helmet)){ - armour = new ItemStack(WizardryItems.spectral_helmet); - IConjuredItem.setDurationMultiplier(armour, modifiers.get(WizardryItems.duration_upgrade)); - armour.getTagCompound().setTag("ench", new NBTTagList()); + if(caster.inventory.armorInventory[3] == null && !caster.inventory.hasItem(Wizardry.spectralHelmet)){ + armour = new ItemStack(Wizardry.spectralHelmet); + armour.stackTagCompound = new NBTTagCompound(); + armour.stackTagCompound.setFloat("durationMultiplier", durationMultiplier); + armour.stackTagCompound.setTag("ench", new NBTTagList()); caster.inventory.armorInventory[3] = armour; flag = true; } - if(caster.inventory.armorInventory[2] == null && !WizardryUtilities.doesPlayerHaveItem(caster, WizardryItems.spectral_chestplate)){ - armour = new ItemStack(WizardryItems.spectral_chestplate); - IConjuredItem.setDurationMultiplier(armour, modifiers.get(WizardryItems.duration_upgrade)); - armour.getTagCompound().setTag("ench", new NBTTagList()); + if(caster.inventory.armorInventory[2] == null && !caster.inventory.hasItem(Wizardry.spectralChestplate)){ + armour = new ItemStack(Wizardry.spectralChestplate); + armour.stackTagCompound = new NBTTagCompound(); + armour.stackTagCompound.setFloat("durationMultiplier", durationMultiplier); + armour.stackTagCompound.setTag("ench", new NBTTagList()); caster.inventory.armorInventory[2] = armour; flag = true; } - if(caster.inventory.armorInventory[1] == null && !WizardryUtilities.doesPlayerHaveItem(caster, WizardryItems.spectral_leggings)){ - armour = new ItemStack(WizardryItems.spectral_leggings); - IConjuredItem.setDurationMultiplier(armour, modifiers.get(WizardryItems.duration_upgrade)); - armour.getTagCompound().setTag("ench", new NBTTagList()); + if(caster.inventory.armorInventory[1] == null && !caster.inventory.hasItem(Wizardry.spectralLeggings)){ + armour = new ItemStack(Wizardry.spectralLeggings); + armour.stackTagCompound = new NBTTagCompound(); + armour.stackTagCompound.setFloat("durationMultiplier", durationMultiplier); + armour.stackTagCompound.setTag("ench", new NBTTagList()); caster.inventory.armorInventory[1] = armour; flag = true; } - if(caster.inventory.armorInventory[0] == null && !WizardryUtilities.doesPlayerHaveItem(caster, WizardryItems.spectral_boots)){ - armour = new ItemStack(WizardryItems.spectral_boots); - IConjuredItem.setDurationMultiplier(armour, modifiers.get(WizardryItems.duration_upgrade)); - armour.getTagCompound().setTag("ench", new NBTTagList()); + if(caster.inventory.armorInventory[0] == null && !caster.inventory.hasItem(Wizardry.spectralBoots)){ + armour = new ItemStack(Wizardry.spectralBoots); + armour.stackTagCompound = new NBTTagCompound(); + armour.stackTagCompound.setFloat("durationMultiplier", durationMultiplier); + armour.stackTagCompound.setTag("ench", new NBTTagList()); caster.inventory.armorInventory[0] = armour; flag = true; } @@ -71,11 +72,12 @@ public class ConjureArmour extends Spell { double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.7f, 0.9f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.7f, 0.9f, 1.0f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f); + ExtendedPlayer.get(caster).conjuredArmourDuration = 0; + world.playSoundAtEntity(caster, "wizardry:aura", 1.0f, 1.0f); } return flag; diff --git a/src/main/java/electroblob/wizardry/spell/ConjureBow.java b/src/main/java/electroblob/wizardry/spell/ConjureBow.java index 087e41c6..74559a38 100644 --- a/src/main/java/electroblob/wizardry/spell/ConjureBow.java +++ b/src/main/java/electroblob/wizardry/spell/ConjureBow.java @@ -1,58 +1,46 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.item.IConjuredItem; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumHand; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; public class ConjureBow extends Spell { public ConjureBow() { - super(Tier.APPRENTICE, 40, Element.SORCERY, "conjure_bow", SpellType.UTILITY, 50, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 40, EnumElement.SORCERY, "conjure_bow", EnumSpellType.UTILITY, 50, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - ItemStack bow = new ItemStack(WizardryItems.spectral_bow); + ItemStack bow = new ItemStack(Wizardry.spectralBow); + bow.stackTagCompound = new NBTTagCompound(); + bow.stackTagCompound.setFloat("durationMultiplier", durationMultiplier); - IConjuredItem.setDurationMultiplier(bow, modifiers.get(WizardryItems.duration_upgrade)); - - if(!WizardryUtilities.doesPlayerHaveItem(caster, WizardryItems.spectral_bow) && conjureItemInInventory(caster, bow)){ + if(!caster.inventory.hasItem(Wizardry.spectralBow) && caster.inventory.addItemStackToInventory(bow)){ for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); if(world.isRemote){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.7f, 0.9f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.7f, 0.9f, 1.0f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f); + ExtendedPlayer.get(caster).conjuredBowDuration = 0; + world.playSoundAtEntity(caster, "wizardry:aura", 1.0f, 1.0f); return true; } return false; } - // TODO: When spells get superclassed, this method needs to be in the conjuration superclass. - /** Adds the given item to the given player's inventory, placing it in the main hand if the main hand is empty. */ - public static boolean conjureItemInInventory(EntityPlayer caster, ItemStack item){ - if(caster.getHeldItemMainhand() == null){ - caster.setHeldItem(EnumHand.MAIN_HAND, item); - return true; - }else{ - return caster.inventory.addItemStackToInventory(item); - } - } } diff --git a/src/main/java/electroblob/wizardry/spell/ConjurePickaxe.java b/src/main/java/electroblob/wizardry/spell/ConjurePickaxe.java index f1fdb33e..73c5b74a 100644 --- a/src/main/java/electroblob/wizardry/spell/ConjurePickaxe.java +++ b/src/main/java/electroblob/wizardry/spell/ConjurePickaxe.java @@ -1,44 +1,42 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.item.IConjuredItem; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumHand; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; public class ConjurePickaxe extends Spell { public ConjurePickaxe() { - super(Tier.APPRENTICE, 25, Element.SORCERY, "conjure_pickaxe", SpellType.UTILITY, 50, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 25, EnumElement.SORCERY, "conjure_pickaxe", EnumSpellType.UTILITY, 50, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - ItemStack pickaxe = new ItemStack(WizardryItems.spectral_pickaxe); + ItemStack pickaxe = new ItemStack(Wizardry.spectralPickaxe); + pickaxe.stackTagCompound = new NBTTagCompound(); + pickaxe.stackTagCompound.setFloat("durationMultiplier", durationMultiplier); - IConjuredItem.setDurationMultiplier(pickaxe, modifiers.get(WizardryItems.duration_upgrade)); - - if(!WizardryUtilities.doesPlayerHaveItem(caster, WizardryItems.spectral_pickaxe) && ConjureBow.conjureItemInInventory(caster, pickaxe)){ - if(world.isRemote){ - for(int i=0; i<10; i++){ + if(!caster.inventory.hasItem(Wizardry.spectralPickaxe) && caster.inventory.addItemStackToInventory(pickaxe)){ + for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.7f, 0.9f, 1.0f); + if(world.isRemote){ + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.7f, 0.9f, 1.0f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f); + ExtendedPlayer.get(caster).conjuredPickaxeDuration = 0; + world.playSoundAtEntity(caster, "wizardry:aura", 1.0f, 1.0f); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/ConjureSword.java b/src/main/java/electroblob/wizardry/spell/ConjureSword.java index adcce8bf..ecd21b34 100644 --- a/src/main/java/electroblob/wizardry/spell/ConjureSword.java +++ b/src/main/java/electroblob/wizardry/spell/ConjureSword.java @@ -1,44 +1,45 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.item.IConjuredItem; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.client.particle.EntitySparkleFX; +import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumHand; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; public class ConjureSword extends Spell { public ConjureSword() { - super(Tier.APPRENTICE, 25, Element.SORCERY, "conjure_sword", SpellType.UTILITY, 50, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 25, EnumElement.SORCERY, "conjure_sword", EnumSpellType.UTILITY, 50, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - ItemStack sword = new ItemStack(WizardryItems.spectral_sword); + ItemStack sword = new ItemStack(Wizardry.spectralSword); - IConjuredItem.setDurationMultiplier(sword, modifiers.get(WizardryItems.duration_upgrade)); + sword.stackTagCompound = new NBTTagCompound(); + sword.stackTagCompound.setFloat("durationMultiplier", durationMultiplier); - if(!WizardryUtilities.doesPlayerHaveItem(caster, WizardryItems.spectral_sword) && ConjureBow.conjureItemInInventory(caster, sword)){ + if(!caster.inventory.hasItem(Wizardry.spectralSword) && caster.inventory.addItemStackToInventory(sword)){ for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); if(world.isRemote){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.7f, 0.9f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.7f, 0.9f, 1.0f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f); + ExtendedPlayer.get(caster).conjuredSwordDuration = 0; + world.playSoundAtEntity(caster, "wizardry:aura", 1.0f, 1.0f); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/CureEffects.java b/src/main/java/electroblob/wizardry/spell/CureEffects.java index 585a3946..28aacc89 100644 --- a/src/main/java/electroblob/wizardry/spell/CureEffects.java +++ b/src/main/java/electroblob/wizardry/spell/CureEffects.java @@ -1,63 +1,57 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class CureEffects extends Spell { public CureEffects() { - super(Tier.APPRENTICE, 25, Element.HEALING, "cure_effects", SpellType.DEFENCE, 40, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 25, EnumElement.HEALING, "cure_effects", EnumSpellType.DEFENCE, 40, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { - - if(world.isRemote){ + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { + + if(!caster.getActivePotionEffects().isEmpty()){ + caster.clearActivePotions(); for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.6f, 0.6f, 1.0f); + if(world.isRemote){ + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.6f, 0.6f, 1.0f); + } } - } - - if(!caster.getActivePotionEffects().isEmpty()){ - caster.clearActivePotions(); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } - // Fixes the sound not playing in first person. - if(world.isRemote) WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return false; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(!caster.getActivePotionEffects().isEmpty()){ caster.clearActivePotions(); - if(world.isRemote){ - for(int i=0; i<10; i++){ - double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); - double y1 = (double)((float)caster.posY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat()); - double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.6f, 0.6f, 1.0f); + for(int i=0; i<10; i++){ + double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); + double y1 = (double)((float)caster.posY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat()); + double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); + if(world.isRemote){ + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.6f, 0.6f, 1.0f); } } - caster.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/CurseOfSoulbinding.java b/src/main/java/electroblob/wizardry/spell/CurseOfSoulbinding.java index 3a2bc261..c1aec3b8 100644 --- a/src/main/java/electroblob/wizardry/spell/CurseOfSoulbinding.java +++ b/src/main/java/electroblob/wizardry/spell/CurseOfSoulbinding.java @@ -1,74 +1,58 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.WizardData; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.IElementalDamage; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.boss.EntityWither; +import net.minecraft.entity.monster.EntitySkeleton; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; +import net.minecraft.potion.PotionEffect; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; +import net.minecraft.util.Vec3; import net.minecraft.world.World; -import net.minecraftforge.event.entity.living.LivingHurtEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -@Mod.EventBusSubscriber public class CurseOfSoulbinding extends Spell { public CurseOfSoulbinding() { - super(Tier.ADVANCED, 35, Element.NECROMANCY, "curse_of_soulbinding", SpellType.ATTACK, 100, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 35, EnumElement.NECROMANCY, "curse_of_soulbinding", EnumSpellType.ATTACK, 100, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - Vec3d look = caster.getLookVec(); + Vec3 look = caster.getLookVec(); - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase && WizardData.get(caster) != null){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLivingBase && ExtendedPlayer.get(caster) != null){ EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit; - if(!WizardData.get(caster).soulbind(target)) return false; + ExtendedPlayer.get(caster).soulbind(target); } if(world.isRemote){ - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ // I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet! double x1 = caster.posX + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; //world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.4f, 0.0f, 0.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 1.0f, 0.8f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.4f, 0.0f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 1.0f, 0.8f, 1.0f); } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SPAWN, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "mob.wither.spawn", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } - - @SubscribeEvent - public static void onLivingHurtEvent(LivingHurtEvent event){ - - if(!event.getEntity().worldObj.isRemote && event.getEntityLiving() instanceof EntityPlayer && !event.getSource().isUnblockable() - && !(event.getSource() instanceof IElementalDamage && ((IElementalDamage)event.getSource()).isRetaliatory())){ - WizardData data = WizardData.get((EntityPlayer)event.getEntityLiving()); - if(data != null){ - data.damageAllSoulboundCreatures(event.getAmount()); - } - } - } } diff --git a/src/main/java/electroblob/wizardry/spell/DarknessOrb.java b/src/main/java/electroblob/wizardry/spell/DarknessOrb.java index d55ff4b0..19f6e3e3 100644 --- a/src/main/java/electroblob/wizardry/spell/DarknessOrb.java +++ b/src/main/java/electroblob/wizardry/spell/DarknessOrb.java @@ -1,23 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntityDarknessOrb; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class DarknessOrb extends Spell { public DarknessOrb() { - super(Tier.ADVANCED, 20, Element.NECROMANCY, "darkness_orb", SpellType.ATTACK, 20, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 20, EnumElement.NECROMANCY, "darkness_orb", EnumSpellType.ATTACK, 20, EnumAction.none, false); } @Override @@ -26,31 +22,31 @@ public class DarknessOrb extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntityDarknessOrb darknessorb = new EntityDarknessOrb(world, caster, modifiers.get(SpellModifiers.DAMAGE)); + EntityDarknessOrb darknessorb = new EntityDarknessOrb(world, caster, damageMultiplier); world.spawnEntityInWorld(darknessorb); + world.playSoundAtEntity(caster, "mob.wither.shoot", 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SHOOT, 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); - caster.swingArm(hand); + caster.swingItem(); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntityDarknessOrb darknessorb = new EntityDarknessOrb(world, caster, modifiers.get(SpellModifiers.DAMAGE)); + EntityDarknessOrb darknessorb = new EntityDarknessOrb(world, caster, damageMultiplier); darknessorb.directTowards(target, 0.5f); world.spawnEntityInWorld(darknessorb); + world.playSoundAtEntity(caster, "mob.wither.shoot", 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); } - - caster.playSound(SoundEvents.ENTITY_WITHER_SHOOT, 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); - caster.swingArm(hand); + + caster.swingItem(); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Darkvision.java b/src/main/java/electroblob/wizardry/spell/Darkvision.java index e426688f..11a2ee46 100644 --- a/src/main/java/electroblob/wizardry/spell/Darkvision.java +++ b/src/main/java/electroblob/wizardry/spell/Darkvision.java @@ -1,41 +1,39 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class Darkvision extends Spell { public Darkvision() { - super(Tier.APPRENTICE, 20, Element.EARTH, "darkvision", SpellType.UTILITY, 40, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 20, EnumElement.EARTH, "darkvision", EnumSpellType.UTILITY, 40, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - caster.addPotionEffect(new PotionEffect(MobEffects.NIGHT_VISION, (int)(900*modifiers.get(WizardryItems.duration_upgrade)), 0, false, false)); + caster.addPotionEffect(new PotionEffect(Potion.nightVision.id, (int)(900*durationMultiplier), 0, true)); if(world.isRemote){ for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.0f, 0.4f, 0.7f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.0f, 0.4f, 0.7f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Dart.java b/src/main/java/electroblob/wizardry/spell/Dart.java index 3babbaa4..954924bc 100644 --- a/src/main/java/electroblob/wizardry/spell/Dart.java +++ b/src/main/java/electroblob/wizardry/spell/Dart.java @@ -1,24 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntityDart; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class Dart extends Spell { public Dart() { - super(Tier.BASIC, 5, Element.EARTH, "dart", SpellType.ATTACK, 10, EnumAction.NONE, false); + super(EnumTier.BASIC, 5, EnumElement.EARTH, "dart", EnumSpellType.ATTACK, 10, EnumAction.none, false); } @Override @@ -27,28 +22,28 @@ public class Dart extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntityDart dart = new EntityDart(world, caster, 2*modifiers.get(WizardryItems.range_upgrade), modifiers.get(SpellModifiers.DAMAGE)); + EntityDart dart = new EntityDart(world, caster, 2*rangeMultiplier, damageMultiplier); world.spawnEntityInWorld(dart); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ARROW_SHOOT, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + caster.swingItem(); + world.playSoundAtEntity(caster, "random.bow", 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntityDart dart = new EntityDart(world, caster, target, 2*modifiers.get(WizardryItems.range_upgrade), 2, modifiers.get(SpellModifiers.DAMAGE)); + EntityDart dart = new EntityDart(world, caster, target, 2*rangeMultiplier, 2, damageMultiplier); world.spawnEntityInWorld(dart); } - caster.swingArm(hand); - caster.playSound(SoundEvents.ENTITY_ARROW_SHOOT, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + caster.swingItem(); + world.playSoundAtEntity(caster, "random.bow", 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Decay.java b/src/main/java/electroblob/wizardry/spell/Decay.java index aa6b899f..a7ba1c6f 100644 --- a/src/main/java/electroblob/wizardry/spell/Decay.java +++ b/src/main/java/electroblob/wizardry/spell/Decay.java @@ -1,27 +1,28 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.entity.EntityArc; import electroblob.wizardry.entity.construct.EntityDecay; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.entity.living.EntitySkeletonMinion; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityCreeper; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MathHelper; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class Decay extends Spell { public Decay(){ - super(Tier.ADVANCED, 50, Element.NECROMANCY, "decay", SpellType.ATTACK, 200, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 50, EnumElement.NECROMANCY, "decay", EnumSpellType.ATTACK, 200, EnumAction.none, false); } @Override @@ -30,29 +31,35 @@ public class Decay extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(12*modifiers.get(WizardryItems.range_upgrade), world, caster, false); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(12*rangeMultiplier, world, caster, false); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ - BlockPos pos = rayTrace.getBlockPos(); + int x = rayTrace.blockX; + int y = rayTrace.blockY; + int z = rayTrace.blockZ; - if(world.getBlockState(pos.up()).isNormalCube()) return false; + if(world.getBlock(x, y+1, z).isNormalCube()) return false; if(!world.isRemote){ - world.spawnEntityInWorld(new EntityDecay(world, pos.getX()+0.5, pos.getY()+1, pos.getZ()+0.5, caster)); + world.spawnEntityInWorld(new EntityDecay(world, x+0.5, y+1, z+0.5, caster)); for(int i=0;i<5;i++){ - BlockPos pos1 = WizardryUtilities.findNearbyFloorSpace(caster, 2, 6); - if(pos1 == null) break; - world.spawnEntityInWorld(new EntityDecay(world, pos1.getX()+0.5, pos1.getY(), pos1.getZ()+0.5, caster)); + double x1 = x + world.rand.nextDouble()*4 - 2; + double z1 = z + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(world.getTopSolidOrLiquidBlock((int)x1, (int)z1) - y < 6){ + double y1 = Math.max(y, world.getTopSolidOrLiquidBlock((int)x1, (int)z1)); + world.spawnEntityInWorld(new EntityDecay(world, x1+0.5, y1, z1+0.5, caster)); + } } } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SHOOT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); - caster.swingArm(hand); + world.playSoundAtEntity(caster, "mob.wither.shoot", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + caster.swingItem(); return true; } @@ -60,29 +67,33 @@ public class Decay extends Spell { } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ int x = MathHelper.floor_double(target.posX); - int y = (int)(int)target.getEntityBoundingBox().minY; + int y = (int)(int)target.boundingBox.minY; int z = MathHelper.floor_double(target.posZ); - if(world.getBlockState(new BlockPos(x, y, z)).isNormalCube()) return false; + if(world.getBlock(x, y, z).isNormalCube()) return false; if(!world.isRemote){ world.spawnEntityInWorld(new EntityDecay(world, x+0.5, y+1, z+0.5, caster)); for(int i=0;i<5;i++){ - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 6); - if(pos == null) break; - world.spawnEntityInWorld(new EntityDecay(world, pos.getX()+0.5, pos.getY(), pos.getZ()+0.5, caster)); + double x1 = x + world.rand.nextDouble()*4 - 2; + double z1 = z + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(world.getTopSolidOrLiquidBlock((int)x1, (int)z1) - y < 6){ + double y1 = Math.max(y, world.getTopSolidOrLiquidBlock((int)x1, (int)z1)); + world.spawnEntityInWorld(new EntityDecay(world, x1+0.5, y1, z1+0.5, caster)); + } } } - caster.playSound(SoundEvents.ENTITY_WITHER_SHOOT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); - caster.swingArm(hand); + world.playSoundAtEntity(caster, "mob.wither.shoot", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + caster.swingItem(); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Decoy.java b/src/main/java/electroblob/wizardry/spell/Decoy.java index dd4d6cbb..b6c00222 100644 --- a/src/main/java/electroblob/wizardry/spell/Decoy.java +++ b/src/main/java/electroblob/wizardry/spell/Decoy.java @@ -1,27 +1,26 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntityDecoy; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class Decoy extends Spell { public Decoy() { - super(Tier.ADVANCED, 40, Element.SORCERY, "decoy", SpellType.UTILITY, 200, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 40, EnumElement.SORCERY, "decoy", EnumSpellType.UTILITY, 200, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { // Determines whether the caster moves left and the decoy moves right, or vice versa. // Uses the synchronised entity id to ensure it is consistent on client and server, but not always the same. double splitSpeed = caster.getEntityId() % 2 == 0 ? 0.3 : -0.3; @@ -31,26 +30,29 @@ public class Decoy extends Spell { decoy.setLocationAndAngles(caster.posX, caster.posY, caster.posZ, caster.rotationYaw, caster.rotationPitch); decoy.addVelocity(-caster.getLookVec().zCoord*splitSpeed, 0, caster.getLookVec().xCoord*splitSpeed); // Ignores the show names setting, since this would allow a player to easily detect a decoy - decoy.setCustomNameTag(caster.getName()); + decoy.setCustomNameTag(caster.getCommandSenderName()); world.spawnEntityInWorld(decoy); // Tricks any mobs that are targeting the caster into targeting the decoy instead. for(EntityLiving creature : WizardryUtilities.getEntitiesWithinRadius(16, caster.posX, caster.posY, caster.posZ, world, EntityLiving.class)){ // More likely to trick mobs the higher the damage multiplier. Starts off at 50%. - if(world.rand.nextInt((int)(6*modifiers.get(SpellModifiers.DAMAGE))) < 3){ + if(world.rand.nextInt((int)(6*damageMultiplier)) < 3){ + // New AI if(creature.getAttackTarget() == caster) creature.setAttackTarget(decoy); + // Old AI + if(creature instanceof EntityCreature && ((EntityCreature)creature).getEntityToAttack() == caster) ((EntityCreature)creature).setTarget(decoy); } } } caster.addVelocity(caster.getLookVec().zCoord*splitSpeed, 0, -caster.getLookVec().xCoord*splitSpeed); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + world.playSoundAtEntity(caster, "wizardry:aura", 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers) { + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { // Determines whether the caster moves left and the decoy moves right, or vice versa. double splitSpeed = world.rand.nextBoolean() ? 0.3 : -0.3; @@ -64,14 +66,17 @@ public class Decoy extends Spell { // Tricks any mobs that are targeting the caster into targeting the decoy instead. for(EntityLiving creature : WizardryUtilities.getEntitiesWithinRadius(16, caster.posX, caster.posY, caster.posZ, world, EntityLiving.class)){ // More likely to trick mobs the higher the damage multiplier. Starts off at 50%. - if(world.rand.nextInt((int)(6*modifiers.get(SpellModifiers.DAMAGE))) < 3){ + if(world.rand.nextInt((int)(6*damageMultiplier)) < 3){ + // New AI if(creature.getAttackTarget() == caster) creature.setAttackTarget(decoy); + // Old AI + if(creature instanceof EntityCreature && ((EntityCreature)creature).getEntityToAttack() == caster) ((EntityCreature)creature).setTarget(decoy); } } } caster.addVelocity(caster.getLookVec().zCoord*splitSpeed, 0, -caster.getLookVec().xCoord*splitSpeed); - caster.playSound(WizardrySounds.SPELL_CONJURATION, 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + world.playSoundAtEntity(caster, "wizardry:aura", 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Detonate.java b/src/main/java/electroblob/wizardry/spell/Detonate.java index 4a0c02c3..f2c66f9c 100644 --- a/src/main/java/electroblob/wizardry/spell/Detonate.java +++ b/src/main/java/electroblob/wizardry/spell/Detonate.java @@ -2,95 +2,91 @@ package electroblob.wizardry.spell; import java.util.List; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.SoundCategory; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class Detonate extends Spell { public Detonate() { - super(Tier.ADVANCED, 45, Element.FIRE, "detonate", SpellType.ATTACK, 50, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 45, EnumElement.FIRE, "detonate", EnumSpellType.ATTACK, 50, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { - - RayTraceResult rayTrace = WizardryUtilities.rayTrace(16*modifiers.get(WizardryItems.range_upgrade), world, caster, false); - - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { + + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(16*rangeMultiplier, world, caster, false); + + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ if(!world.isRemote){ - List targets = WizardryUtilities.getEntitiesWithinRadius(3.0d*modifiers.get(WizardryItems.blast_upgrade), (rayTrace.hitVec.xCoord+0.5), (rayTrace.hitVec.yCoord+0.5), (rayTrace.hitVec.zCoord+0.5), world); + List targets = WizardryUtilities.getEntitiesWithinRadius(3.0d*blastMultiplier, (rayTrace.blockX+0.5), (rayTrace.blockY+0.5), (rayTrace.blockZ+0.5), world); for(int i=0;i targets = WizardryUtilities.getEntitiesWithinRadius(3.0d, target.posX, target.posY, target.posZ, world); + List targets = WizardryUtilities.getEntitiesWithinRadius(3.0d, target.posX, target.posY, target.posZ, world); for(int i=0;i targets = WizardryUtilities.getEntitiesWithinRadius(5*modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world, EntityPlayer.class); + List targets = WizardryUtilities.getEntitiesWithinRadius(5*blastMultiplier, caster.posX, caster.posY, caster.posZ, world, EntityPlayer.class); for(EntityPlayer target : targets){ if(WizardryUtilities.isPlayerAlly(caster, target) || target == caster){ // Damage multiplier can only ever be 1 or 1.6 for master spells, so there's little point in actually calculating this. - target.addPotionEffect(new PotionEffect(WizardryPotions.font_of_mana, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), modifiers.get(SpellModifiers.DAMAGE) > 1 ? 1 : 0)); + target.addPotionEffect(new PotionEffect(Wizardry.fontOfMana.id, (int)(600*durationMultiplier), damageMultiplier > 1 ? 1 : 0)); } } if(world.isRemote){ - for(int i=0;i<100*modifiers.get(WizardryItems.blast_upgrade);i++){ - double radius = (1 + world.rand.nextDouble()*4)*modifiers.get(WizardryItems.blast_upgrade); + for(int i=0;i<100*blastMultiplier;i++){ + double radius = (1 + world.rand.nextDouble()*4)*blastMultiplier; double angle = world.rand.nextDouble()*Math.PI*2; float hue = world.rand.nextFloat()*0.4f; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, caster.posX + radius*Math.cos(angle), caster.getEntityBoundingBox().minY, caster.posZ + radius*Math.sin(angle), + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, caster.posX + radius*Math.cos(angle), WizardryUtilities.getEntityFeetPos(caster), caster.posZ + radius*Math.sin(angle), 0, 0.03, 0, 50, 1, 1-hue, 0.6f+hue); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/FontOfVitality.java b/src/main/java/electroblob/wizardry/spell/FontOfVitality.java index 1056b526..040eb230 100644 --- a/src/main/java/electroblob/wizardry/spell/FontOfVitality.java +++ b/src/main/java/electroblob/wizardry/spell/FontOfVitality.java @@ -1,32 +1,28 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class FontOfVitality extends Spell { public FontOfVitality() { - super(Tier.MASTER, 75, Element.HEALING, "font_of_vitality", SpellType.DEFENCE, 300, EnumAction.BOW, false); + super(EnumTier.MASTER, 75, EnumElement.HEALING, "font_of_vitality", EnumSpellType.DEFENCE, 300, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - caster.addPotionEffect(new PotionEffect(MobEffects.ABSORPTION, (int)(1200*modifiers.get(WizardryItems.duration_upgrade)), 1, false, false)); - caster.addPotionEffect(new PotionEffect(MobEffects.REGENERATION, (int)(300*modifiers.get(WizardryItems.duration_upgrade)), 1, false, false)); + caster.addPotionEffect(new PotionEffect(Potion.field_76444_x.id, (int)(1200*durationMultiplier), 1, true)); + caster.addPotionEffect(new PotionEffect(Potion.regeneration.id, (int)(300*durationMultiplier), 1, true)); if(world.isRemote){ for(int i=0; i<10; i++){ @@ -34,18 +30,18 @@ public class FontOfVitality extends Spell { double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 0.6f, 0.7f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 0.6f, 0.7f); x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 0.8f, 0.3f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 0.8f, 0.3f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/ForceArrow.java b/src/main/java/electroblob/wizardry/spell/ForceArrow.java index 05cd68eb..c1207c93 100644 --- a/src/main/java/electroblob/wizardry/spell/ForceArrow.java +++ b/src/main/java/electroblob/wizardry/spell/ForceArrow.java @@ -1,24 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntityForceArrow; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class ForceArrow extends Spell { public ForceArrow() { - super(Tier.APPRENTICE, 15, Element.SORCERY, "force_arrow", SpellType.ATTACK, 20, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 15, EnumElement.SORCERY, "force_arrow", EnumSpellType.ATTACK, 20, EnumAction.none, false); } @Override @@ -27,30 +22,32 @@ public class ForceArrow extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntityForceArrow forceArrow = new EntityForceArrow(world, caster, 1*modifiers.get(WizardryItems.range_upgrade), modifiers.get(SpellModifiers.DAMAGE)); + EntityForceArrow forceArrow = new EntityForceArrow(world, caster, 1*rangeMultiplier, damageMultiplier); world.spawnEntityInWorld(forceArrow); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_FORCE, 1.0f, 1.2f + world.rand.nextFloat()*0.2f); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:aura", 1.0F, 1.4f); + world.playSoundAtEntity(caster, "wizardry:magic", 1.0F, 1.2F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntityForceArrow forceArrow = new EntityForceArrow(world, caster, target, 1*modifiers.get(WizardryItems.range_upgrade), 2, modifiers.get(SpellModifiers.DAMAGE)); + EntityForceArrow forceArrow = new EntityForceArrow(world, caster, target, 1*rangeMultiplier, 2, damageMultiplier); world.spawnEntityInWorld(forceArrow); } - caster.swingArm(hand); - caster.playSound(WizardrySounds.SPELL_FORCE, 1.0f, 1.2f + world.rand.nextFloat()*0.2f); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:aura", 1.0F, 1.4f); + world.playSoundAtEntity(caster, "wizardry:magic", 1.0F, 1.2F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/ForceOrb.java b/src/main/java/electroblob/wizardry/spell/ForceOrb.java index 30ee52a4..4e5e8821 100644 --- a/src/main/java/electroblob/wizardry/spell/ForceOrb.java +++ b/src/main/java/electroblob/wizardry/spell/ForceOrb.java @@ -1,24 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntityForceOrb; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class ForceOrb extends Spell { public ForceOrb() { - super(Tier.ADVANCED, 20, Element.SORCERY, "force_orb", SpellType.ATTACK, 20, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 20, EnumElement.SORCERY, "force_orb", EnumSpellType.ATTACK, 20, EnumAction.none, false); } @Override @@ -27,31 +22,31 @@ public class ForceOrb extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntityForceOrb forceOrb = new EntityForceOrb(world, caster, modifiers.get(SpellModifiers.DAMAGE), modifiers.get(WizardryItems.blast_upgrade)); + EntityForceOrb forceOrb = new EntityForceOrb(world, caster, damageMultiplier, blastMultiplier); world.spawnEntityInWorld(forceOrb); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + caster.swingItem(); + world.playSoundAtEntity(caster, "random.bow", 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntityForceOrb forceOrb = new EntityForceOrb(world, caster, modifiers.get(SpellModifiers.DAMAGE), modifiers.get(WizardryItems.blast_upgrade)); + EntityForceOrb forceOrb = new EntityForceOrb(world, caster, damageMultiplier, blastMultiplier); forceOrb.directTowards(target, 1.5f); world.spawnEntityInWorld(forceOrb); } - caster.swingArm(hand); - caster.playSound(SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + caster.swingItem(); + world.playSoundAtEntity(caster, "random.bow", 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Forcefield.java b/src/main/java/electroblob/wizardry/spell/Forcefield.java index 0b366bd1..0778db2f 100644 --- a/src/main/java/electroblob/wizardry/spell/Forcefield.java +++ b/src/main/java/electroblob/wizardry/spell/Forcefield.java @@ -1,24 +1,20 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.construct.EntityForcefield; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.entity.projectile.EntityMagicMissile; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class Forcefield extends Spell { public Forcefield() { - super(Tier.ADVANCED, 45, Element.HEALING, "forcefield", SpellType.DEFENCE, 200, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 45, EnumElement.HEALING, "forcefield", EnumSpellType.DEFENCE, 200, EnumAction.bow, false); } @Override @@ -27,14 +23,14 @@ public class Forcefield extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(caster.onGround){ if(!world.isRemote){ - EntityForcefield forcefield = new EntityForcefield(world, caster.posX, caster.posY, caster.posZ, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); + EntityForcefield forcefield = new EntityForcefield(world, caster.posX, caster.posY, caster.posZ, caster, (int)(600*durationMultiplier)); world.spawnEntityInWorld(forcefield); } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION_LARGE, 1.0f, 1.0f); + world.playSoundAtEntity(caster, "wizardry:largeaura", 1.0f, 1.0f); return true; } @@ -42,16 +38,16 @@ public class Forcefield extends Spell { } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ // Wizards can no longer cast forcefield when they are inside one - if(caster.onGround && world.getEntitiesWithinAABB(EntityForcefield.class, caster.getEntityBoundingBox()).isEmpty()){ + if(caster.onGround && world.getEntitiesWithinAABB(EntityForcefield.class, caster.boundingBox).isEmpty()){ if(!world.isRemote){ - EntityForcefield forcefield = new EntityForcefield(world, caster.posX, caster.posY, caster.posZ, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); + EntityForcefield forcefield = new EntityForcefield(world, caster.posX, caster.posY, caster.posZ, caster, (int)(600*durationMultiplier)); world.spawnEntityInWorld(forcefield); } - caster.playSound(WizardrySounds.SPELL_CONJURATION_LARGE, 1.0f, 1.0f); + world.playSoundAtEntity(caster, "wizardry:largeaura", 1.0f, 1.0f); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/ForestsCurse.java b/src/main/java/electroblob/wizardry/spell/ForestsCurse.java index 68612acd..1165666c 100644 --- a/src/main/java/electroblob/wizardry/spell/ForestsCurse.java +++ b/src/main/java/electroblob/wizardry/spell/ForestsCurse.java @@ -2,61 +2,57 @@ package electroblob.wizardry.spell; import java.util.List; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class ForestsCurse extends Spell { public ForestsCurse() { - super(Tier.MASTER, 75, Element.EARTH, "forests_curse", SpellType.ATTACK, 200, EnumAction.BOW, false); + super(EnumTier.MASTER, 75, EnumElement.EARTH, "forests_curse", EnumSpellType.ATTACK, 200, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - List targets = WizardryUtilities.getEntitiesWithinRadius(5.0d*modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world); + List targets = WizardryUtilities.getEntitiesWithinRadius(5.0d*blastMultiplier, caster.posX, caster.posY, caster.posZ, world); for(EntityLivingBase target : targets){ if(WizardryUtilities.isValidTarget(caster, target) && !MagicDamage.isEntityImmune(DamageType.POISON, target)){ - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.POISON), 4.0f * modifiers.get(SpellModifiers.DAMAGE)); - target.addPotionEffect(new PotionEffect(MobEffects.POISON, (int)(140*modifiers.get(WizardryItems.duration_upgrade)), 2)); - target.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, (int)(140*modifiers.get(WizardryItems.duration_upgrade)), 2)); - target.addPotionEffect(new PotionEffect(MobEffects.WEAKNESS, (int)(140*modifiers.get(WizardryItems.duration_upgrade)), 2)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.POISON), 4.0f * damageMultiplier); + target.addPotionEffect(new PotionEffect(Potion.poison.id, (int)(140*durationMultiplier), 2)); + target.addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, (int)(140*durationMultiplier), 2)); + target.addPotionEffect(new PotionEffect(Potion.weakness.id, (int)(140*durationMultiplier), 2)); } } if(world.isRemote){ - for(int i=0;i<50*modifiers.get(WizardryItems.blast_upgrade);i++){ - double radius = (1 + world.rand.nextDouble()*4)*modifiers.get(WizardryItems.blast_upgrade); + for(int i=0;i<50*blastMultiplier;i++){ + double radius = (1 + world.rand.nextDouble()*4)*blastMultiplier; double angle = world.rand.nextDouble()*Math.PI*2; float brightness = world.rand.nextFloat()/4; - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, caster.posX + radius*Math.cos(angle), WizardryUtilities.getPlayerEyesPos(caster) + 0.5, caster.posZ + radius*Math.sin(angle), + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, caster.posX + radius*Math.cos(angle), WizardryUtilities.getPlayerEyesPos(caster) + 0.5, caster.posZ + radius*Math.sin(angle), 0, -0.2, 0, 0, 0.05f+brightness, 0.2f+brightness, 0.0f); brightness = world.rand.nextFloat()/4; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, caster.posX + radius*Math.cos(angle), WizardryUtilities.getPlayerEyesPos(caster) + 0.5, caster.posZ + radius*Math.sin(angle), + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, caster.posX + radius*Math.cos(angle), WizardryUtilities.getPlayerEyesPos(caster) + 0.5, caster.posZ + radius*Math.sin(angle), 0, -0.05, 0, 50, 0.1f+brightness, 0.2f+brightness, 0.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.LEAF, world, caster.posX + radius*Math.cos(angle), WizardryUtilities.getPlayerEyesPos(caster) + 0.5, caster.posZ + radius*Math.sin(angle), 0, -0.01, 0, 40 + world.rand.nextInt(12)); + Wizardry.proxy.spawnParticle(EnumParticleType.LEAF, world, caster.posX + radius*Math.cos(angle), WizardryUtilities.getPlayerEyesPos(caster) + 0.5, caster.posZ + radius*Math.sin(angle), 0, -0.01, 0, 40 + world.rand.nextInt(12)); } } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SPAWN, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "mob.wither.spawn", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Freeze.java b/src/main/java/electroblob/wizardry/spell/Freeze.java index 01b289cc..bc159e03 100644 --- a/src/main/java/electroblob/wizardry/spell/Freeze.java +++ b/src/main/java/electroblob/wizardry/spell/Freeze.java @@ -1,58 +1,58 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntityBlazeMinion; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.entity.living.EntityIceGiant; +import electroblob.wizardry.entity.living.EntityIceWraith; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.monster.EntityBlaze; import net.minecraft.entity.monster.EntityMagmaCube; +import net.minecraft.entity.monster.EntitySnowman; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.EnumAction; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; public class Freeze extends Spell { public Freeze() { - super(Tier.BASIC, 5, Element.ICE, "freeze", SpellType.ATTACK, 10, EnumAction.NONE, false); + super(EnumTier.BASIC, 5, EnumElement.ICE, "freeze", EnumSpellType.ATTACK, 10, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { + + //caster.addPotionEffect(new PotionEffect(Wizardry.frost.id, 200, 0)); // Entity ray trace is done first because block ray trace passes through entities; if it was the other // way round, entities would only be hit when there were no blocks in range behind them. - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ EntityLivingBase target = (EntityLivingBase) rayTrace.entityHit; if(target instanceof EntityBlaze || target instanceof EntityMagmaCube || target instanceof EntityBlazeMinion){ - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.FROST), 3.0f * modifiers.get(SpellModifiers.DAMAGE)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.FROST), 3.0f * damageMultiplier); } if(MagicDamage.isEntityImmune(DamageType.FROST, target)){ - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", target.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", target.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else{ - target.addPotionEffect(new PotionEffect(WizardryPotions.frost, (int)(200*modifiers.get(WizardryItems.duration_upgrade)), 1)); + target.addPotionEffect(new PotionEffect(Wizardry.frost.id, (int)(200*durationMultiplier), 1, true)); } if(target.isBurning()){ @@ -61,53 +61,52 @@ public class Freeze extends Spell { if(world.isRemote){ double dx = target.posX - caster.posX; - double dy = (target.getEntityBoundingBox().minY + target.height/2) - WizardryUtilities.getPlayerEyesPos(caster); + double dy = (WizardryUtilities.getEntityFeetPos(target) + target.height/2) - WizardryUtilities.getPlayerEyesPos(caster); double dz = target.posZ - caster.posZ; for(int i=1;i<5;i++){ float brightness = 0.5f + (world.rand.nextFloat()/2); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), brightness, brightness + 0.1f, 1.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.SNOW, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, -0.02, 0, 40 + world.rand.nextInt(10)); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), brightness, brightness + 0.1f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SNOW, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, -0.02, 0, 40 + world.rand.nextInt(10)); } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 1.2F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.4F + 1.2F); return true; }else{ - rayTrace = WizardryUtilities.rayTrace(10*modifiers.get(WizardryItems.range_upgrade), world, caster, true); + rayTrace = WizardryUtilities.rayTrace(10*rangeMultiplier, world, caster, true); // Gets block the player is looking at and sets to ice or covers with snow as necessary // Note how the block is set on the server side only (kinda obvious really) but the particles are // spawned on the client side only. - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ - BlockPos pos = rayTrace.getBlockPos(); - - if(world.getBlockState(pos).getBlock() == Blocks.WATER && !world.isRemote){ - world.setBlockState(pos, Blocks.ICE.getDefaultState()); - }else if(world.getBlockState(pos).getBlock() == Blocks.LAVA && !world.isRemote){ - world.setBlockState(pos, Blocks.OBSIDIAN.getDefaultState()); - }else if(world.getBlockState(pos).getBlock() == Blocks.FLOWING_LAVA && !world.isRemote){ - world.setBlockState(pos, Blocks.COBBLESTONE.getDefaultState()); - }else if(rayTrace.sideHit == EnumFacing.UP && !world.isRemote && world.isSideSolid(pos, EnumFacing.UP) && WizardryUtilities.canBlockBeReplaced(world, pos.up())){ - world.setBlockState(pos.up(), Blocks.SNOW_LAYER.getDefaultState()); + int blockHitX = rayTrace.blockX; + int blockHitY = rayTrace.blockY; + int blockHitZ = rayTrace.blockZ; + int blockHitSide = rayTrace.sideHit; + if(world.getBlock(blockHitX, blockHitY, blockHitZ) == Blocks.water && !world.isRemote){ + world.setBlock(blockHitX, blockHitY, blockHitZ, Blocks.ice); + }else if(world.getBlock(blockHitX, blockHitY, blockHitZ) == Blocks.lava && !world.isRemote){ + world.setBlock(blockHitX, blockHitY, blockHitZ, Blocks.obsidian); + }else if(world.getBlock(blockHitX, blockHitY, blockHitZ) == Blocks.flowing_lava && !world.isRemote){ + world.setBlock(blockHitX, blockHitY, blockHitZ, Blocks.cobblestone); + }else if(blockHitSide == 1 && !world.isRemote && world.isSideSolid(blockHitX, blockHitY, blockHitZ, ForgeDirection.UP) && WizardryUtilities.canBlockBeReplaced(world, blockHitX, blockHitY+1, blockHitZ)){ + world.setBlock(blockHitX, blockHitY+1, blockHitZ, Blocks.snow_layer); } if(world.isRemote){ - - double dx = pos.getX() + 0.5 - caster.posX; - double dy = pos.getY() + 0.5 - WizardryUtilities.getPlayerEyesPos(caster); - double dz = pos.getZ() + 0.5 - caster.posZ; - + double dx = blockHitX + 0.5 - caster.posX; + double dy = blockHitY + 1.5 - (caster.posY + caster.height/2); + double dz = blockHitZ + 0.5 - caster.posZ; for(int i=1;i<5;i++){ float brightness = 0.5f + (world.rand.nextFloat()/2); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0.0d, 0.0d, 0.0d, 20 + world.rand.nextInt(8), brightness, brightness + 0.1f, 1.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0, 20 + world.rand.nextInt(8), 1.0f, 1.0f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0.0d, 0.0d, 0.0d, 20 + world.rand.nextInt(8), brightness, brightness + 0.1f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0, 20 + world.rand.nextInt(8), 1.0f, 1.0f, 1.0f); } } - - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 1.2F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.4F + 1.2F); return true; } } @@ -115,16 +114,16 @@ public class Freeze extends Spell { } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(target instanceof EntityBlaze || target instanceof EntityMagmaCube || target instanceof EntityBlazeMinion){ - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.FROST), 3.0f * modifiers.get(SpellModifiers.DAMAGE)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.FROST), 3.0f * damageMultiplier); } if(!world.isRemote && !MagicDamage.isEntityImmune(DamageType.FROST, target)){ - target.addPotionEffect(new PotionEffect(WizardryPotions.frost, (int)(200*modifiers.get(WizardryItems.duration_upgrade)), 1)); + target.addPotionEffect(new PotionEffect(Wizardry.frost.id, (int)(200*durationMultiplier), 1, true)); } if(target.isBurning()){ @@ -133,17 +132,17 @@ public class Freeze extends Spell { if(world.isRemote){ double dx = target.posX - caster.posX; - double dy = (target.getEntityBoundingBox().minY + target.height/2) - (caster.posY + caster.getEyeHeight()); + double dy = (WizardryUtilities.getEntityFeetPos(target) + target.height/2) - (caster.posY + caster.getEyeHeight()); double dz = target.posZ - caster.posZ; for(int i=1;i<5;i++){ float brightness = 0.5f + (world.rand.nextFloat()/2); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + caster.getEyeHeight() + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), brightness, brightness + 0.1f, 1.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.SNOW, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + caster.getEyeHeight() + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, -0.02, 0, 40 + world.rand.nextInt(10)); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + caster.getEyeHeight() + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), brightness, brightness + 0.1f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SNOW, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + caster.getEyeHeight() + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, -0.02, 0, 40 + world.rand.nextInt(10)); } } - caster.swingArm(hand); - caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 1.2F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.4F + 1.2F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/FreezingWeapon.java b/src/main/java/electroblob/wizardry/spell/FreezingWeapon.java index 911be3f4..1a7c5158 100644 --- a/src/main/java/electroblob/wizardry/spell/FreezingWeapon.java +++ b/src/main/java/electroblob/wizardry/spell/FreezingWeapon.java @@ -1,65 +1,71 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.WizardData; +import java.util.List; + +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Constants; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryEnchantments; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.ContainerPlayer; +import net.minecraft.inventory.Slot; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemBow; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class FreezingWeapon extends Spell { - + /** The NBT tag name for storing the level of frost enchantment in the arrow's tag compound. (There's nothing * stopping you from using this elsewhere to shoot freezing arrows if you want to...) */ public static final String FREEZING_ARROW_NBT_KEY = "frostLevel"; public FreezingWeapon() { - super(Tier.ADVANCED, 35, Element.ICE, "freezing_weapon", SpellType.UTILITY, 70, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 35, EnumElement.ICE, "freezing_weapon", EnumSpellType.UTILITY, 70, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { // Won't work if the weapon already has the enchantment - if(WizardData.get(caster) != null && WizardData.get(caster).getImbuementDuration(WizardryEnchantments.freezing_weapon) <= 0){ + if(ExtendedPlayer.get(caster) != null && ExtendedPlayer.get(caster).freezingWeaponDuration <= 0){ - for(ItemStack stack : WizardryUtilities.getPrioritisedHotbarAndOffhand(caster)){ + // Isolates just the hotbar + List hotbar = ((ContainerPlayer)caster.openContainer).inventorySlots.subList(36, 45); - if(stack != null){ + for(Object slot : hotbar){ - if((stack.getItem() instanceof ItemSword || stack.getItem() instanceof ItemBow) && !EnchantmentHelper.getEnchantments(stack).containsKey(WizardryEnchantments.freezing_weapon)){ - // The enchantment level as determined by the damage multiplier. The + 0.5f is so that - // weird float processing doesn't incorrectly round it down. - stack.addEnchantment(WizardryEnchantments.freezing_weapon, modifiers.get(SpellModifiers.DAMAGE) == 1.0f ? 1 : (int)((modifiers.get(SpellModifiers.DAMAGE) - 1.0f)/Constants.DAMAGE_INCREASE_PER_TIER + 0.5f)); + if(slot instanceof Slot){ - WizardData.get(caster).setImbuementDuration(WizardryEnchantments.freezing_weapon, (int)(900*modifiers.get(WizardryItems.duration_upgrade))); + ItemStack stack = ((Slot)slot).getStack(); - if(world.isRemote){ - for(int i=0; i<10; i++){ - double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); - double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); - double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.9f, 0.7f, 1.0f); + if(stack != null){ + + if((stack.getItem() instanceof ItemSword || stack.getItem() instanceof ItemBow) && !EnchantmentHelper.getEnchantments(stack).containsKey(Wizardry.freezingWeapon.effectId)){ + // The enchantment level as determined by the damage multiplier. The + 0.5f is so that + // weird float processing doesn't incorrectly round it down. + stack.addEnchantment(Wizardry.freezingWeapon, damageMultiplier == 1.0f ? 1 : (int)((damageMultiplier - 1.0f)/Wizardry.DAMAGE_INCREASE_PER_TIER + 0.5f)); + + ExtendedPlayer.get(caster).freezingWeaponDuration = (int)(900*durationMultiplier); + + if(world.isRemote){ + for(int i=0; i<10; i++){ + double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); + double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); + double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.9f, 0.7f, 1.0f); + } } + + world.playSoundAtEntity(caster, "wizardry:aura", 1.0f, 1.0f); + return true; + } - - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f); - return true; - } } } diff --git a/src/main/java/electroblob/wizardry/spell/FrostAxe.java b/src/main/java/electroblob/wizardry/spell/FrostAxe.java index 1d48473e..9df23b16 100644 --- a/src/main/java/electroblob/wizardry/spell/FrostAxe.java +++ b/src/main/java/electroblob/wizardry/spell/FrostAxe.java @@ -1,46 +1,44 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.item.IConjuredItem; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumHand; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; public class FrostAxe extends Spell { public FrostAxe() { - super(Tier.ADVANCED, 45, Element.ICE, "frost_axe", SpellType.UTILITY, 50, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 45, EnumElement.ICE, "frost_axe", EnumSpellType.UTILITY, 50, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - ItemStack frostaxe = new ItemStack(WizardryItems.frost_axe); - - IConjuredItem.setDurationMultiplier(frostaxe, modifiers.get(WizardryItems.duration_upgrade)); + ItemStack frostaxe = new ItemStack(Wizardry.frostAxe); + frostaxe.stackTagCompound = new NBTTagCompound(); + frostaxe.stackTagCompound.setFloat("durationMultiplier", durationMultiplier); - if(!WizardryUtilities.doesPlayerHaveItem(caster, WizardryItems.frost_axe) && ConjureBow.conjureItemInInventory(caster, frostaxe)){ + if(!caster.inventory.hasItem(Wizardry.frostAxe) && caster.inventory.addItemStackToInventory(frostaxe)){ if(world.isRemote){ for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SNOW, world, x1, y1, z1, 0, -0.02d, 0, 40 + world.rand.nextInt(10)); + Wizardry.proxy.spawnParticle(EnumParticleType.SNOW, world, x1, y1, z1, 0, -0.02d, 0, 40 + world.rand.nextInt(10)); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0f, 1.0f); + ExtendedPlayer.get(caster).frostAxeDuration = 0; + world.playSoundAtEntity(caster, "wizardry:ice", 1.0f, 1.0f); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/FrostRay.java b/src/main/java/electroblob/wizardry/spell/FrostRay.java index 10897960..98d4bd0f 100644 --- a/src/main/java/electroblob/wizardry/spell/FrostRay.java +++ b/src/main/java/electroblob/wizardry/spell/FrostRay.java @@ -1,132 +1,102 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.entity.EntityLiving; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.entity.living.EntityBlazeMinion; +import electroblob.wizardry.entity.living.EntityIceGiant; +import electroblob.wizardry.entity.living.EntityIceWraith; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.monster.EntityBlaze; import net.minecraft.entity.monster.EntityMagmaCube; +import net.minecraft.entity.monster.EntitySnowman; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class FrostRay extends Spell { public FrostRay() { - super(Tier.APPRENTICE, 5, Element.ICE, "frost_ray", SpellType.ATTACK, 0, EnumAction.NONE, true); + super(EnumTier.APPRENTICE, 5, EnumElement.ICE, "frost_ray", EnumSpellType.ATTACK, 0, EnumAction.none, true); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { - - Vec3d look = caster.getLookVec(); - - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade)); - - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ - + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { + + Vec3 look = caster.getLookVec(); + + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier); + + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ + EntityLivingBase target = (EntityLivingBase) rayTrace.entityHit; - + if(target.isBurning()){ target.extinguish(); } - + if(MagicDamage.isEntityImmune(DamageType.FROST, target)){ - if(!world.isRemote && ticksInUse == 1) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", target.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote && ticksInUse == 1) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", target.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else{ // For frost ray the entity can move slightly, unlike freeze. - target.addPotionEffect(new PotionEffect(WizardryPotions.frost, (int)(200*modifiers.get(WizardryItems.duration_upgrade)), 0)); + target.addPotionEffect(new PotionEffect(Wizardry.frost.id, (int)(200*durationMultiplier), 0, true)); + + if(target instanceof EntityBlaze || target instanceof EntityMagmaCube || target instanceof EntityBlazeMinion){ + // This motion stuff removes knockback, which is desirable for continuous spells. + double motionX = target.motionX; + double motionY = target.motionY; + double motionZ = target.motionZ; + + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.FROST), 6.0f * damageMultiplier); - float baseDamage = target instanceof EntityBlaze || target instanceof EntityMagmaCube ? 6.0f : 3.0f; - WizardryUtilities.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster, DamageType.FROST), baseDamage * modifiers.get(SpellModifiers.DAMAGE)); + target.motionX = motionX; + target.motionY = motionY; + target.motionZ = motionZ; + }else{ + // This motion stuff removes knockback, which is desirable for continuous spells. + double motionX = target.motionX; + double motionY = target.motionY; + double motionZ = target.motionZ; + + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.FROST), 3.0f * damageMultiplier); + target.motionX = motionX; + target.motionY = motionY; + target.motionZ = motionZ; + } } } - + if(world.isRemote){ for(int i=0; i<20; i++){ double x1 = caster.posX + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, look.xCoord*modifiers.get(WizardryItems.range_upgrade), look.yCoord*modifiers.get(WizardryItems.range_upgrade), look.zCoord*modifiers.get(WizardryItems.range_upgrade), 8 + world.rand.nextInt(12), 0.4f, 0.6f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, look.xCoord*rangeMultiplier, look.yCoord*rangeMultiplier, look.zCoord*rangeMultiplier, 8 + world.rand.nextInt(12), 0.4f, 0.6f, 1.0f); x1 = caster.posX + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, look.xCoord*modifiers.get(WizardryItems.range_upgrade), look.yCoord*modifiers.get(WizardryItems.range_upgrade), look.zCoord*modifiers.get(WizardryItems.range_upgrade), 8 + world.rand.nextInt(12), 1.0f, 1.0f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, look.xCoord*rangeMultiplier, look.yCoord*rangeMultiplier, look.zCoord*rangeMultiplier, 8 + world.rand.nextInt(12), 1.0f, 1.0f, 1.0f); } } - - if(ticksInUse % 12 == 0){ - if(ticksInUse == 0) WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 0.5F, 1.0f); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_ICE, 0.5F, 1.0f); - } - return true; - } - - @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers) { - - if(target != null){ - - Vec3d vec = new Vec3d(target.posX - caster.posX, target.posY - caster.posY, target.posZ - caster.posZ).normalize(); - - if(target.isBurning()){ - target.extinguish(); - } - - if(!MagicDamage.isEntityImmune(DamageType.FROST, target)){ - // For frost ray the entity can move slightly, unlike freeze. - target.addPotionEffect(new PotionEffect(WizardryPotions.frost, (int)(200*modifiers.get(WizardryItems.duration_upgrade)), 0)); - - float baseDamage = target instanceof EntityBlaze || target instanceof EntityMagmaCube ? 6.0f : 3.0f; - WizardryUtilities.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster, DamageType.FROST), baseDamage * modifiers.get(SpellModifiers.DAMAGE)); - - } - - if(world.isRemote){ - for(int i=0; i<20; i++){ - double x1 = caster.posX + vec.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - double y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - double z1 = caster.posZ + vec.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, vec.xCoord*modifiers.get(WizardryItems.range_upgrade), vec.yCoord*modifiers.get(WizardryItems.range_upgrade), vec.zCoord*modifiers.get(WizardryItems.range_upgrade), 8 + world.rand.nextInt(12), 0.4f, 0.6f, 1.0f); - - x1 = caster.posX + vec.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - z1 = caster.posZ + vec.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, vec.xCoord*modifiers.get(WizardryItems.range_upgrade), vec.yCoord*modifiers.get(WizardryItems.range_upgrade), vec.zCoord*modifiers.get(WizardryItems.range_upgrade), 8 + world.rand.nextInt(12), 1.0f, 1.0f, 1.0f); - } - } - - if(ticksInUse % 12 == 0){ - if(ticksInUse == 0) caster.playSound(WizardrySounds.SPELL_ICE, 0.5F, 1.0f); - caster.playSound(WizardrySounds.SPELL_LOOP_ICE, 0.5F, 1.0f); - } - - return true; - } - return false; - } - - @Override - public boolean canBeCastByNPCs() { + if(ticksInUse % 12 == 0){ + if(ticksInUse == 0)world.playSoundAtEntity(caster, "wizardry:ice", 0.5F, 1.0f); + world.playSoundAtEntity(caster, "wizardry:frostray", 0.5F, 1.0f); + } return true; } + } diff --git a/src/main/java/electroblob/wizardry/spell/FrostSigil.java b/src/main/java/electroblob/wizardry/spell/FrostSigil.java index 5423e9e8..f375f55e 100644 --- a/src/main/java/electroblob/wizardry/spell/FrostSigil.java +++ b/src/main/java/electroblob/wizardry/spell/FrostSigil.java @@ -1,24 +1,20 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.construct.EntityFrostSigil; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class FrostSigil extends Spell { public FrostSigil() { - super(Tier.APPRENTICE, 10, Element.ICE, "frost_sigil", SpellType.ATTACK, 20, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 10, EnumElement.ICE, "frost_sigil", EnumSpellType.ATTACK, 20, EnumAction.none, false); } @Override @@ -27,20 +23,20 @@ public class FrostSigil extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(10*modifiers.get(WizardryItems.range_upgrade), world, caster, false); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(10*rangeMultiplier, world, caster, false); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK && rayTrace.sideHit == EnumFacing.UP){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK && rayTrace.sideHit == 1){ if(!world.isRemote){ - double x = rayTrace.hitVec.xCoord; - double y = rayTrace.hitVec.yCoord; - double z = rayTrace.hitVec.zCoord; - EntityFrostSigil frostsigil = new EntityFrostSigil(world, x, y, z, caster, modifiers.get(SpellModifiers.DAMAGE)); + double x = rayTrace.blockX; + double y = rayTrace.blockY; + double z = rayTrace.blockZ; + EntityFrostSigil frostsigil = new EntityFrostSigil(world, x + 0.5, y+1, z + 0.5, caster, damageMultiplier); world.spawnEntityInWorld(frostsigil); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, 1.0F); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/Glide.java b/src/main/java/electroblob/wizardry/spell/Glide.java index 45fa88d7..60fd80b9 100644 --- a/src/main/java/electroblob/wizardry/spell/Glide.java +++ b/src/main/java/electroblob/wizardry/spell/Glide.java @@ -1,26 +1,23 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class Glide extends Spell { public Glide() { - super(Tier.ADVANCED, 5, Element.EARTH, "glide", SpellType.UTILITY, 0, EnumAction.NONE, true); + super(EnumTier.ADVANCED, 5, EnumElement.EARTH, "glide", EnumSpellType.UTILITY, 0, EnumAction.none, true); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(caster.motionY < -0.1 && !caster.isInWater()){ caster.motionY = -0.1; @@ -32,12 +29,16 @@ public class Glide extends Spell { } if(world.isRemote){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, caster.posX - 0.25d + world.rand.nextDouble()/2, WizardryUtilities.getPlayerEyesPos(caster) - 1.5f + world.rand.nextDouble(), caster.posZ - 0.25d + world.rand.nextDouble()/2, 0, -0.1F, 0, 15, 1.0f, 1.0f, 1.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.LEAF, world, caster.posX - 0.25d + world.rand.nextDouble()/2, WizardryUtilities.getPlayerEyesPos(caster) - 1.5f + world.rand.nextDouble(), caster.posZ - 0.25d + world.rand.nextDouble()/2, 0, -0.03, 0, 20); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, caster.posX - 0.25d + world.rand.nextDouble()/2, WizardryUtilities.getPlayerEyesPos(caster) - 1.5f + world.rand.nextDouble(), caster.posZ - 0.25d + world.rand.nextDouble()/2, 0, -0.1F, 0, 15, 1.0f, 1.0f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.LEAF, world, caster.posX - 0.25d + world.rand.nextDouble()/2, WizardryUtilities.getPlayerEyesPos(caster) - 1.5f + world.rand.nextDouble(), caster.posZ - 0.25d + world.rand.nextDouble()/2, 0, -0.03, 0, 20); } + //if(caster.getItemInUseDuration() == 0){ + //world.playSoundAtEntity(entityplayer, "wizardry:sparkle", 0.5F, 1.0f); + //} + if(ticksInUse % 24 == 0){ - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ITEM_ELYTRA_FLYING, 0.5F, 1.0f); + world.playSoundAtEntity(caster, "mob.enderdragon.wings", 0.5F, 1.0f); } return true; } diff --git a/src/main/java/electroblob/wizardry/spell/GreaterFireball.java b/src/main/java/electroblob/wizardry/spell/GreaterFireball.java index 93414391..c02157b9 100644 --- a/src/main/java/electroblob/wizardry/spell/GreaterFireball.java +++ b/src/main/java/electroblob/wizardry/spell/GreaterFireball.java @@ -1,24 +1,20 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.projectile.EntityLargeFireball; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class GreaterFireball extends Spell { public GreaterFireball() { - super(Tier.ADVANCED, 20, Element.FIRE, "greater_fireball", SpellType.ATTACK, 30, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 20, EnumElement.FIRE, "greater_fireball", EnumSpellType.ATTACK, 30, EnumAction.none, false); } @Override @@ -27,9 +23,9 @@ public class GreaterFireball extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - Vec3d look = caster.getLookVec(); + Vec3 look = caster.getLookVec(); if(!world.isRemote){ EntityLargeFireball fireball = new EntityLargeFireball(world, caster, 1, 1, 1); @@ -41,15 +37,15 @@ public class GreaterFireball extends Spell { fireball.accelerationY = look.yCoord * 0.1; fireball.accelerationZ = look.zCoord * 0.1; world.spawnEntityInWorld(fireball); + world.playAuxSFX(1009, (int)caster.posX, (int)caster.posY, (int)caster.posZ, 0); } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1); - caster.swingArm(hand); + caster.swingItem(); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ @@ -58,7 +54,7 @@ public class GreaterFireball extends Spell { EntityLargeFireball fireball = new EntityLargeFireball(world, caster, 1, 1, 1); double dx = target.posX - caster.posX; - double dy = target.getEntityBoundingBox().minY + (double)(target.height / 2.0F) - (caster.posY + (double)(caster.height / 2.0F)); + double dy = target.boundingBox.minY + (double)(target.height / 2.0F) - (caster.posY + (double)(caster.height / 2.0F)); double dz = target.posZ - caster.posZ; fireball.accelerationX = dx/caster.getDistanceToEntity(target) * 0.1; @@ -68,10 +64,10 @@ public class GreaterFireball extends Spell { fireball.setPosition(caster.posX, caster.posY + caster.getEyeHeight(), caster.posZ); world.spawnEntityInWorld(fireball); + world.playAuxSFX(1009, (int)caster.posX, (int)caster.posY, (int)caster.posZ, 0); } - caster.playSound(SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1); - caster.swingArm(hand); + caster.swingItem(); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/GreaterHeal.java b/src/main/java/electroblob/wizardry/spell/GreaterHeal.java index df20a7dc..d27e0338 100644 --- a/src/main/java/electroblob/wizardry/spell/GreaterHeal.java +++ b/src/main/java/electroblob/wizardry/spell/GreaterHeal.java @@ -1,59 +1,56 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class GreaterHeal extends Spell { public GreaterHeal() { - super(Tier.ADVANCED, 15, Element.HEALING, "greater_heal", SpellType.DEFENCE, 40, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 15, EnumElement.HEALING, "greater_heal", EnumSpellType.DEFENCE, 40, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(caster.shouldHeal()){ - caster.heal((int)(8*modifiers.get(SpellModifiers.DAMAGE))); + caster.heal((int)(8*damageMultiplier)); if(world.isRemote){ for(int i=0; i<10; i++){ double dx = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double dy = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double dz = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, dx, dy, dz, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, dx, dy, dz, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } return false; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(caster.getHealth() < caster.getMaxHealth()){ - caster.heal((int)(8*modifiers.get(SpellModifiers.DAMAGE))); + caster.heal((int)(8*damageMultiplier)); if(world.isRemote){ for(int i=0; i<10; i++){ double dx = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double dy = (double)((float)caster.posY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat()); double dz = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, dx, dy, dz, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, dx, dy, dz, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f); } } - caster.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/GroupHeal.java b/src/main/java/electroblob/wizardry/spell/GroupHeal.java index 939ef998..b69714a5 100644 --- a/src/main/java/electroblob/wizardry/spell/GroupHeal.java +++ b/src/main/java/electroblob/wizardry/spell/GroupHeal.java @@ -2,34 +2,32 @@ package electroblob.wizardry.spell; import java.util.List; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.entity.living.ISummonedCreature; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.entity.living.EntitySummonedCreature; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionEffect; import net.minecraft.world.World; public class GroupHeal extends Spell { public GroupHeal() { - super(Tier.ADVANCED, 35, Element.HEALING, "group_heal", SpellType.DEFENCE, 150, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 35, EnumElement.HEALING, "group_heal", EnumSpellType.DEFENCE, 150, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { boolean flag = false; - List targets = WizardryUtilities.getEntitiesWithinRadius(5*modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world); + List targets = WizardryUtilities.getEntitiesWithinRadius(5*blastMultiplier, caster.posX, caster.posY, caster.posZ, world); for(EntityLivingBase target : targets){ @@ -39,43 +37,42 @@ public class GroupHeal extends Spell { if(((EntityPlayer)target).shouldHeal()){ - target.heal((int)(6*modifiers.get(SpellModifiers.DAMAGE))); + target.heal((int)(6*damageMultiplier)); if(world.isRemote){ for(int i=0; i<10; i++){ double d0 = (double)((float)target.posX + world.rand.nextFloat()*2 - 1.0F); double d1 = (double)((float)WizardryUtilities.getPlayerEyesPos((EntityPlayer)target) - 0.5F + world.rand.nextFloat()); double d2 = (double)((float)target.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, d0, d1, d2, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, d0, d1, d2, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); flag = true; } } - // Now also works on summoned creatures - }else if(target instanceof ISummonedCreature){ + }else if(target instanceof EntitySummonedCreature){ - EntityLivingBase summoner = ((ISummonedCreature)target).getCaster(); + EntityLivingBase summoner = ((EntitySummonedCreature)target).getCaster(); if(summoner == caster || (summoner instanceof EntityPlayer && WizardryUtilities.isPlayerAlly(caster, (EntityPlayer)summoner))){ if(target.getHealth() < target.getMaxHealth()){ - target.heal((int)(6*modifiers.get(SpellModifiers.DAMAGE))); + target.heal((int)(6*damageMultiplier)); if(world.isRemote){ for(int i=0; i<10; i++){ double d0 = (double)((float)target.posX + world.rand.nextFloat()*2 - 1.0F); double d1 = (double)((float)WizardryUtilities.getPlayerEyesPos((EntityPlayer)target) - 0.5F + world.rand.nextFloat()); double d2 = (double)((float)target.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, d0, d1, d2, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, d0, d1, d2, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); flag = true; } } diff --git a/src/main/java/electroblob/wizardry/spell/GrowthAura.java b/src/main/java/electroblob/wizardry/spell/GrowthAura.java index 7e52855e..c13fe625 100644 --- a/src/main/java/electroblob/wizardry/spell/GrowthAura.java +++ b/src/main/java/electroblob/wizardry/spell/GrowthAura.java @@ -1,24 +1,22 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.WizardryUtilities; +import net.minecraft.block.Block; +import net.minecraft.block.BlockGrass; import net.minecraft.block.IGrowable; -import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemDye; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; public class GrowthAura extends Spell { public GrowthAura() { - super(Tier.APPRENTICE, 20, Element.EARTH, "growth_aura", SpellType.UTILITY, 50, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 20, EnumElement.EARTH, "growth_aura", EnumSpellType.UTILITY, 50, EnumAction.none, false); } @Override @@ -27,7 +25,7 @@ public class GrowthAura extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { boolean flag = false; @@ -35,39 +33,38 @@ public class GrowthAura extends Spell { for(int j=-1; j<2; j++){ - int x = (int)caster.posX + i; - int y = WizardryUtilities.getNearestFloorLevelC(world, new BlockPos(caster.posX + i, caster.posY, caster.posZ + j), 2) - 1; - int z = (int)caster.posZ + j; + if(!world.isRemote){ - BlockPos pos = new BlockPos(x, y, z); + int x = (int)caster.posX + i; + int y = WizardryUtilities.getNearestFloorLevelC(world, (int)caster.posX + i, (int)caster.posY, (int)caster.posZ + j, 2) - 1; + int z = (int)caster.posZ + j; - if(y > -1 && caster.getDistance(x, y, z) <= 2){ + if(y > -1 && caster.getDistance(x, y, z) <= 2){ - IBlockState state = world.getBlockState(pos); + Block block = world.getBlock(x, y, z); - if(state.getBlock() instanceof IGrowable){ + if(block instanceof IGrowable){ - IGrowable igrowable = (IGrowable)state.getBlock(); + IGrowable igrowable = (IGrowable)block; - if(igrowable.canGrow(world, pos, state, world.isRemote)){ - - if(!world.isRemote){ - if(igrowable.canUseBonemeal(world, world.rand, pos, state)){ - igrowable.grow(world, world.rand, pos, state); + if (igrowable.func_149851_a(world, x, y, z, world.isRemote)) + { + if (igrowable.func_149852_a(world, world.rand, x, y, z)) + { + igrowable.func_149853_b(world, world.rand, x, y, z); } - }else{ - // Yes, it's meant to be 0, and it automatically changes it to 15. - ItemDye.spawnBonemealParticles(world, pos, 0); + + world.playAuxSFX(2005, x, y, z, 0); + + flag = true; } - flag = true; } } } } } - if(flag) WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return flag; } diff --git a/src/main/java/electroblob/wizardry/spell/Hailstorm.java b/src/main/java/electroblob/wizardry/spell/Hailstorm.java index 7dc8ee73..b6f02050 100644 --- a/src/main/java/electroblob/wizardry/spell/Hailstorm.java +++ b/src/main/java/electroblob/wizardry/spell/Hailstorm.java @@ -1,23 +1,20 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.construct.EntityHailstorm; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class Hailstorm extends Spell { public Hailstorm() { - super(Tier.MASTER, 75, Element.ICE, "hailstorm", SpellType.ATTACK, 300, EnumAction.NONE, false); + super(EnumTier.MASTER, 75, EnumElement.ICE, "hailstorm", EnumSpellType.ATTACK, 300, EnumAction.none, false); } @Override @@ -26,15 +23,15 @@ public class Hailstorm extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(20*modifiers.get(WizardryItems.range_upgrade), world, caster, false); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(20*rangeMultiplier, world, caster, false); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ if(!world.isRemote){ - double x = rayTrace.hitVec.xCoord; - double y = rayTrace.hitVec.yCoord; - double z = rayTrace.hitVec.zCoord; + double x = rayTrace.blockX; + double y = rayTrace.blockY; + double z = rayTrace.blockZ; // Moves the entity back towards the caster a bit, so the area of effect is better centred on the position. // 3.0d is the distance to move the entity back towards the caster. double dx = caster.posX - x; @@ -43,12 +40,12 @@ public class Hailstorm extends Spell { x += dx*distRatio; z += dz*distRatio; - EntityHailstorm hailstorm = new EntityHailstorm(world, x, y + 5, z, caster, (int)(120*modifiers.get(WizardryItems.duration_upgrade)), modifiers.get(SpellModifiers.DAMAGE)); + EntityHailstorm hailstorm = new EntityHailstorm(world, x, y + 5, z, caster, (int)(120*durationMultiplier), damageMultiplier); hailstorm.rotationYaw = caster.rotationYawHead; world.spawnEntityInWorld(hailstorm); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, 1.0F); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/Heal.java b/src/main/java/electroblob/wizardry/spell/Heal.java index 8a7044e3..a09297c9 100644 --- a/src/main/java/electroblob/wizardry/spell/Heal.java +++ b/src/main/java/electroblob/wizardry/spell/Heal.java @@ -1,32 +1,29 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class Heal extends Spell { public Heal() { - super(Tier.BASIC, 5, Element.HEALING, "heal", SpellType.DEFENCE, 20, EnumAction.BOW, false); + super(EnumTier.BASIC, 5, EnumElement.HEALING, "heal", EnumSpellType.DEFENCE, 20, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(caster.shouldHeal()){ - caster.heal((int)(4*modifiers.get(SpellModifiers.DAMAGE))); + caster.heal((int)(4*damageMultiplier)); if(world.isRemote){ for(int i=0; i<10; i++){ @@ -34,30 +31,30 @@ public class Heal extends Spell { // Apparently the client side spawns the particles 1 block higher than it should... hence the - 0.5F. double d1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double d2 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, d0, d1, d2, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, d0, d1, d2, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } return false; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(caster.getHealth() < caster.getMaxHealth()){ - caster.heal((int)(4*modifiers.get(SpellModifiers.DAMAGE))); + caster.heal((int)(4*damageMultiplier)); if(world.isRemote){ for(int i=0; i<10; i++){ double dx = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double dy = (double)((float)caster.posY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat()); double dz = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, dx, dy, dz, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, dx, dy, dz, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f); } } - caster.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/HealAlly.java b/src/main/java/electroblob/wizardry/spell/HealAlly.java index 3ab49587..e8493459 100644 --- a/src/main/java/electroblob/wizardry/spell/HealAlly.java +++ b/src/main/java/electroblob/wizardry/spell/HealAlly.java @@ -1,49 +1,47 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.client.particle.EntitySparkleFX; +import net.minecraft.client.Minecraft; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; public class HealAlly extends Spell { public HealAlly() { - super(Tier.APPRENTICE, 10, Element.HEALING, "heal_ally", SpellType.DEFENCE, 20, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 10, EnumElement.HEALING, "heal_ally", EnumSpellType.DEFENCE, 20, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade), 8.0f); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier, 8.0f); if(rayTrace != null && rayTrace.entityHit != null && rayTrace.entityHit instanceof EntityLivingBase){ EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit; if(target.getHealth() < target.getMaxHealth()){ - target.heal((int)(5*modifiers.get(SpellModifiers.DAMAGE))); + target.heal((int)(5*damageMultiplier)); if(world.isRemote){ for(int i=0; i<10; i++){ double d0 = (double)((float)target.posX + world.rand.nextFloat()*2 - 1.0F); // Apparently the client side spawns the particles 1 block higher than it should... hence the - 0.5F. - double d1 = (double)((float)target.getEntityBoundingBox().minY + target.height - 0.5f + world.rand.nextFloat()); + double d1 = (double)((float)WizardryUtilities.getEntityFeetPos(target) + target.height - 0.5f + world.rand.nextFloat()); double d2 = (double)((float)target.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, d0, d1, d2, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, d0, d1, d2, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 1.0f, 0.3f); } } - caster.swingArm(hand); - target.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + caster.swingItem(); + world.playSoundAtEntity(target, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } } diff --git a/src/main/java/electroblob/wizardry/spell/HealingAura.java b/src/main/java/electroblob/wizardry/spell/HealingAura.java index bcd6ea61..67359c0e 100644 --- a/src/main/java/electroblob/wizardry/spell/HealingAura.java +++ b/src/main/java/electroblob/wizardry/spell/HealingAura.java @@ -1,22 +1,20 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.entity.construct.EntityForcefield; import electroblob.wizardry.entity.construct.EntityHealAura; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class HealingAura extends Spell { public HealingAura() { - super(Tier.ADVANCED, 35, Element.HEALING, "healing_aura", SpellType.DEFENCE, 150, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 35, EnumElement.HEALING, "healing_aura", EnumSpellType.DEFENCE, 150, EnumAction.bow, false); } @Override @@ -25,11 +23,11 @@ public class HealingAura extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(caster.onGround){ if(!world.isRemote){ - EntityHealAura healaura = new EntityHealAura(world, caster.posX, caster.posY, caster.posZ, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), modifiers.get(SpellModifiers.DAMAGE)); + EntityHealAura healaura = new EntityHealAura(world, caster.posX, caster.posY, caster.posZ, caster, (int)(600*durationMultiplier), damageMultiplier); world.spawnEntityInWorld(healaura); } return true; @@ -38,12 +36,12 @@ public class HealingAura extends Spell { } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers) { + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(target != null){ - if(caster.onGround && world.getEntitiesWithinAABB(EntityHealAura.class, caster.getEntityBoundingBox()).isEmpty()){ + if(caster.onGround && world.getEntitiesWithinAABB(EntityHealAura.class, caster.boundingBox).isEmpty()){ if(!world.isRemote){ - EntityHealAura healaura = new EntityHealAura(world, caster.posX, caster.posY, caster.posZ, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), modifiers.get(SpellModifiers.DAMAGE)); + EntityHealAura healaura = new EntityHealAura(world, caster.posX, caster.posY, caster.posZ, caster, (int)(600*durationMultiplier), damageMultiplier); world.spawnEntityInWorld(healaura); } return true; diff --git a/src/main/java/electroblob/wizardry/spell/HomingSpark.java b/src/main/java/electroblob/wizardry/spell/HomingSpark.java index 65ed1d64..d50f4708 100644 --- a/src/main/java/electroblob/wizardry/spell/HomingSpark.java +++ b/src/main/java/electroblob/wizardry/spell/HomingSpark.java @@ -1,23 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntitySpark; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class HomingSpark extends Spell { public HomingSpark() { - super(Tier.APPRENTICE, 10, Element.LIGHTNING, "homing_spark", SpellType.ATTACK, 20, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 10, EnumElement.LIGHTNING, "homing_spark", EnumSpellType.ATTACK, 20, EnumAction.none, false); } @Override @@ -26,29 +22,29 @@ public class HomingSpark extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntitySpark spark = new EntitySpark(world, caster, modifiers.get(SpellModifiers.DAMAGE)); + EntitySpark spark = new EntitySpark(world, caster, damageMultiplier); world.spawnEntityInWorld(spark); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + world.playSoundAtEntity(caster, "wizardry:aura", 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); } - caster.swingArm(hand); + caster.swingItem(); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntitySpark spark = new EntitySpark(world, caster, modifiers.get(SpellModifiers.DAMAGE)); + EntitySpark spark = new EntitySpark(world, caster, damageMultiplier); spark.directTowards(target, 0.5f); world.spawnEntityInWorld(spark); - caster.playSound(WizardrySounds.SPELL_CONJURATION, 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + world.playSoundAtEntity(caster, "wizardry:aura", 1.0F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); } - caster.swingArm(hand); + caster.swingItem(); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/IceAge.java b/src/main/java/electroblob/wizardry/spell/IceAge.java index 8f57ee59..b9278c7c 100644 --- a/src/main/java/electroblob/wizardry/spell/IceAge.java +++ b/src/main/java/electroblob/wizardry/spell/IceAge.java @@ -2,16 +2,12 @@ package electroblob.wizardry.spell; import java.util.List; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryAchievements; -import electroblob.wizardry.registry.WizardryBlocks; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.tileentity.TileEntityStatue; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.monster.EntityBlaze; @@ -19,8 +15,6 @@ import net.minecraft.entity.monster.EntityMagmaCube; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; public class IceAge extends Spell { @@ -28,7 +22,7 @@ public class IceAge extends Spell { private static final int baseDuration = 1200; public IceAge() { - super(Tier.MASTER, 70, Element.ICE, "ice_age", SpellType.ATTACK, 250, EnumAction.BOW, false); + super(EnumTier.MASTER, 70, EnumElement.ICE, "ice_age", EnumSpellType.ATTACK, 250, EnumAction.bow, false); } @Override @@ -37,76 +31,78 @@ public class IceAge extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - List targets = WizardryUtilities.getEntitiesWithinRadius(7*modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world); + List targets = WizardryUtilities.getEntitiesWithinRadius(7*blastMultiplier, caster.posX, caster.posY, caster.posZ, world); for(EntityLivingBase target : targets){ if(WizardryUtilities.isValidTarget(caster, target)){ if(!world.isRemote){ if(target instanceof EntityBlaze || target instanceof EntityMagmaCube){ // These have been removed for the time being because they cause the entity to sink into the floor when it breaks out. - //target.attackEntityFrom(WizardryUtilities.causePlayerMagicDamage(entityplayer), 8.0f * modifiers.get(SpellModifiers.DAMAGE)); + //target.attackEntityFrom(WizardryUtilities.causePlayerMagicDamage(entityplayer), 8.0f * damageMultiplier); }else{ - //target.attackEntityFrom(WizardryUtilities.causePlayerMagicDamage(entityplayer), 4.0f * modifiers.get(SpellModifiers.DAMAGE)); + //target.attackEntityFrom(WizardryUtilities.causePlayerMagicDamage(entityplayer), 4.0f * damageMultiplier); } if(target.isBurning()){ target.extinguish(); } - if(target instanceof EntityBlaze) caster.addStat(WizardryAchievements.freeze_blaze, 1); + if(target instanceof EntityBlaze) caster.addStat(Wizardry.freezeBlaze, 1); if(target instanceof EntityLiving){ // Stops the entity looking red while frozen and the resulting z-fighting target.hurtTime = 0; - BlockPos pos = new BlockPos(target); + int x = (int)Math.floor(target.posX); + int y = (int)Math.floor(target.posY); + int z = (int)Math.floor(target.posZ); - // Short mobs such as spiders and pigs - if((target.height < 1.2 || target.isChild()) && WizardryUtilities.canBlockBeReplaced(world, pos)){ - world.setBlockState(pos, WizardryBlocks.ice_statue.getDefaultState()); - if(world.getTileEntity(pos) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart((EntityLiving) target, 1, 1); - ((TileEntityStatue)world.getTileEntity(pos)).setLifetime((int)(baseDuration*modifiers.get(WizardryItems.duration_upgrade))); + //Short mobs such as spiders and pigs + if((target.height < 1.2 || target.isChild()) && WizardryUtilities.canBlockBeReplaced(world, x, y, z)){ + world.setBlock(x, y, z, Wizardry.iceStatue); + if(world.getTileEntity(x, y, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y, z)).setCreatureAndPart((EntityLiving) target, 1, 1); + ((TileEntityStatue)world.getTileEntity(x, y, z)).setLifetime((int)(baseDuration*durationMultiplier)); } target.setDead(); - target.playSound(WizardrySounds.SPELL_FREEZE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); + world.playSoundAtEntity(target, "wizardry:freeze", 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); } - // Normal sized mobs like zombies and skeletons - else if(target.height < 2.5 && WizardryUtilities.canBlockBeReplaced(world, pos) && WizardryUtilities.canBlockBeReplaced(world, pos.up())){ - world.setBlockState(pos, WizardryBlocks.ice_statue.getDefaultState()); - if(world.getTileEntity(pos) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart((EntityLiving) target, 1, 2); - ((TileEntityStatue)world.getTileEntity(pos)).setLifetime((int)(baseDuration*modifiers.get(WizardryItems.duration_upgrade))); + //Normal sized mobs like zombies and skeletons + else if(target.height < 2.5 && WizardryUtilities.canBlockBeReplaced(world, x, y, z) && WizardryUtilities.canBlockBeReplaced(world, x, y+1, z)){ + world.setBlock(x, y, z, Wizardry.iceStatue); + if(world.getTileEntity(x, y, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y, z)).setCreatureAndPart((EntityLiving) target, 1, 2); + ((TileEntityStatue)world.getTileEntity(x, y, z)).setLifetime((int)(baseDuration*durationMultiplier)); } - world.setBlockState(pos.up(), WizardryBlocks.ice_statue.getDefaultState()); - if(world.getTileEntity(pos.up()) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos.up())).setCreatureAndPart((EntityLiving) target, 2, 2); + world.setBlock(x, y+1, z, Wizardry.iceStatue); + if(world.getTileEntity(x, y+1, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y+1, z)).setCreatureAndPart((EntityLiving) target, 2, 2); } target.setDead(); - target.playSound(WizardrySounds.SPELL_FREEZE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); + world.playSoundAtEntity(target, "wizardry:freeze", 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); } - // Tall mobs like endermen - else if(WizardryUtilities.canBlockBeReplaced(world, pos) && WizardryUtilities.canBlockBeReplaced(world, pos.up()) && WizardryUtilities.canBlockBeReplaced(world, pos.up(2))){ - world.setBlockState(pos, WizardryBlocks.ice_statue.getDefaultState()); - if(world.getTileEntity(pos) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart((EntityLiving) target, 1, 3); - ((TileEntityStatue)world.getTileEntity(pos)).setLifetime((int)(baseDuration*modifiers.get(WizardryItems.duration_upgrade))); + //Tall mobs like endermen + else if(WizardryUtilities.canBlockBeReplaced(world, x, y, z) && WizardryUtilities.canBlockBeReplaced(world, x, y+1, z) && WizardryUtilities.canBlockBeReplaced(world, x, y+2, z)){ + world.setBlock(x, y, z, Wizardry.iceStatue); + if(world.getTileEntity(x, y, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y, z)).setCreatureAndPart((EntityLiving) target, 1, 3); + ((TileEntityStatue)world.getTileEntity(x, y, z)).setLifetime((int)(baseDuration*durationMultiplier)); } - world.setBlockState(pos.up(), WizardryBlocks.ice_statue.getDefaultState()); - if(world.getTileEntity(pos.up()) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos.up())).setCreatureAndPart((EntityLiving) target, 2, 3); + world.setBlock(x, y+1, z, Wizardry.iceStatue); + if(world.getTileEntity(x, y+1, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y+1, z)).setCreatureAndPart((EntityLiving) target, 2, 3); } - world.setBlockState(pos.up(2), WizardryBlocks.ice_statue.getDefaultState()); - if(world.getTileEntity(pos.up(2)) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos.up(2))).setCreatureAndPart((EntityLiving) target, 3, 3); + world.setBlock(x, y+2, z, Wizardry.iceStatue); + if(world.getTileEntity(x, y+2, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y+2, z)).setCreatureAndPart((EntityLiving) target, 3, 3); } target.setDead(); - target.playSound(WizardrySounds.SPELL_FREEZE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); + world.playSoundAtEntity(target, "wizardry:freeze", 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); } } } @@ -115,33 +111,28 @@ public class IceAge extends Spell { if(!world.isRemote){ for(int i=-7; i<8; i++){ for(int j=-7; j<8; j++){ - - BlockPos pos = new BlockPos(caster).add(i, 0, j); - - int y = WizardryUtilities.getNearestFloorLevelB(world, new BlockPos(pos), 7); - - pos = new BlockPos(pos.getX(), y, pos.getZ()); - + int y = WizardryUtilities.getNearestFloorLevelB(world, (int)caster.posX + i, (int)caster.posY, (int)caster.posZ + j, 7); + //System.out.println(y); double dist = caster.getDistance((int)caster.posX + i, y, (int)caster.posZ + j); - // Randomised with weighting so that the nearer the block the more likely it is to be snowed. if(y != -1 && world.rand.nextInt((int)dist*2 + 1) < 7 && dist < 8){ - if(world.getBlockState(pos.down()) == Blocks.WATER.getDefaultState()){ - world.setBlockState(pos.down(), Blocks.ICE.getDefaultState()); - }else if(world.getBlockState(pos.down()) == Blocks.LAVA.getDefaultState()){ - world.setBlockState(pos.down(), Blocks.OBSIDIAN.getDefaultState()); - }else if(world.getBlockState(pos.down()) == Blocks.FLOWING_LAVA.getDefaultState()){ - world.setBlockState(pos.down(), Blocks.COBBLESTONE.getDefaultState()); + if(world.getBlock((int)caster.posX + i, y-1, (int)caster.posZ + j) == Blocks.water){ + world.setBlock((int)caster.posX + i, y-1, (int)caster.posZ + j, Blocks.ice); + }else if(world.getBlock((int)caster.posX + i, y-1, (int)caster.posZ + j) == Blocks.lava){ + world.setBlock((int)caster.posX + i, y-1, (int)caster.posZ + j, Blocks.obsidian); + }else if(world.getBlock((int)caster.posX + i, y-1, (int)caster.posZ + j) == Blocks.flowing_lava){ + world.setBlock((int)caster.posX + i, y-1, (int)caster.posZ + j, Blocks.cobblestone); }else{ - world.setBlockState(pos, Blocks.SNOW_LAYER.getDefaultState()); + world.setBlock((int)caster.posX + i, y, (int)caster.posZ + j, Blocks.snow_layer); } } } } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 0.7F, 1.0f); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_WIND, 1.0F, 1.0f); + world.playSoundAtEntity(caster, "wizardry:ice", 0.7F, 1.0f); + world.playSoundAtEntity(caster, "wizardry:wind", 1.0F, 1.0f); return true; } + } diff --git a/src/main/java/electroblob/wizardry/spell/IceCharge.java b/src/main/java/electroblob/wizardry/spell/IceCharge.java index c419b374..959a477c 100644 --- a/src/main/java/electroblob/wizardry/spell/IceCharge.java +++ b/src/main/java/electroblob/wizardry/spell/IceCharge.java @@ -1,24 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntityIceCharge; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class IceCharge extends Spell { public IceCharge() { - super(Tier.ADVANCED, 20, Element.ICE, "ice_charge", SpellType.ATTACK, 30, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 20, EnumElement.ICE, "ice_charge", EnumSpellType.ATTACK, 30, EnumAction.none, false); } @Override @@ -27,31 +22,31 @@ public class IceCharge extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntityIceCharge icecharge = new EntityIceCharge(world, caster, modifiers.get(SpellModifiers.DAMAGE), modifiers.get(WizardryItems.blast_upgrade)); + EntityIceCharge icecharge = new EntityIceCharge(world, caster, damageMultiplier, blastMultiplier); world.spawnEntityInWorld(icecharge); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntityIceCharge icecharge = new EntityIceCharge(world, caster, modifiers.get(SpellModifiers.DAMAGE), modifiers.get(WizardryItems.blast_upgrade)); + EntityIceCharge icecharge = new EntityIceCharge(world, caster, damageMultiplier, blastMultiplier); icecharge.directTowards(target, 1.5f); world.spawnEntityInWorld(icecharge); } - caster.swingArm(hand); - caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/IceLance.java b/src/main/java/electroblob/wizardry/spell/IceLance.java index dcef7c07..6d571a35 100644 --- a/src/main/java/electroblob/wizardry/spell/IceLance.java +++ b/src/main/java/electroblob/wizardry/spell/IceLance.java @@ -1,24 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntityIceLance; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class IceLance extends Spell { public IceLance() { - super(Tier.ADVANCED, 20, Element.ICE, "ice_lance", SpellType.ATTACK, 20, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 20, EnumElement.ICE, "ice_lance", EnumSpellType.ATTACK, 20, EnumAction.none, false); } @Override @@ -27,28 +22,28 @@ public class IceLance extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntityIceLance iceLance = new EntityIceLance(world, caster, 2*modifiers.get(WizardryItems.range_upgrade), modifiers.get(SpellModifiers.DAMAGE)); + EntityIceLance iceLance = new EntityIceLance(world, caster, 2*rangeMultiplier, damageMultiplier); world.spawnEntityInWorld(iceLance); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntityIceLance iceLance = new EntityIceLance(world, caster, target, 2*modifiers.get(WizardryItems.range_upgrade), 4, modifiers.get(SpellModifiers.DAMAGE)); + EntityIceLance iceLance = new EntityIceLance(world, caster, target, 2*rangeMultiplier, 4, damageMultiplier); world.spawnEntityInWorld(iceLance); } - caster.swingArm(hand); - caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/IceShard.java b/src/main/java/electroblob/wizardry/spell/IceShard.java index ddda2a1d..a361460c 100644 --- a/src/main/java/electroblob/wizardry/spell/IceShard.java +++ b/src/main/java/electroblob/wizardry/spell/IceShard.java @@ -1,24 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntityIceShard; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class IceShard extends Spell { public IceShard() { - super(Tier.APPRENTICE, 10, Element.ICE, "ice_shard", SpellType.ATTACK, 10, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 10, EnumElement.ICE, "ice_shard", EnumSpellType.ATTACK, 10, EnumAction.none, false); } @Override @@ -27,28 +22,28 @@ public class IceShard extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntityIceShard iceShard = new EntityIceShard(world, caster, 2*modifiers.get(WizardryItems.range_upgrade), modifiers.get(SpellModifiers.DAMAGE)); + EntityIceShard iceShard = new EntityIceShard(world, caster, 2*rangeMultiplier, damageMultiplier); world.spawnEntityInWorld(iceShard); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntityIceShard iceShard = new EntityIceShard(world, caster, target, 2*modifiers.get(WizardryItems.range_upgrade), 4, modifiers.get(SpellModifiers.DAMAGE)); + EntityIceShard iceShard = new EntityIceShard(world, caster, target, 2*rangeMultiplier, 4, damageMultiplier); world.spawnEntityInWorld(iceShard); } - caster.swingArm(hand); - caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/IceShroud.java b/src/main/java/electroblob/wizardry/spell/IceShroud.java index 85843dc1..82b2d9f0 100644 --- a/src/main/java/electroblob/wizardry/spell/IceShroud.java +++ b/src/main/java/electroblob/wizardry/spell/IceShroud.java @@ -1,25 +1,21 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.Wizardry; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class IceShroud extends Spell { public IceShroud() { - super(Tier.ADVANCED, 40, Element.ICE, "ice_shroud", SpellType.DEFENCE, 250, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 40, EnumElement.ICE, "ice_shroud", EnumSpellType.DEFENCE, 250, EnumAction.bow, false); } @Override @@ -28,29 +24,29 @@ public class IceShroud extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { // Cannot be cast when it has already been cast - if(!caster.isPotionActive(WizardryPotions.ice_shroud)){ + if(!caster.isPotionActive(Wizardry.iceShroud)){ if(!world.isRemote){ - caster.addPotionEffect(new PotionEffect(WizardryPotions.ice_shroud, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 0)); + caster.addPotionEffect(new PotionEffect(Wizardry.iceShroud.id, (int)(600*durationMultiplier), 0, true)); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); return true; } return false; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers) { + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(target != null){ // Cannot be cast when it has already been cast - if(!caster.isPotionActive(WizardryPotions.ice_shroud)){ + if(!caster.isPotionActive(Wizardry.iceShroud)){ if(!world.isRemote){ - caster.addPotionEffect(new PotionEffect(WizardryPotions.ice_shroud, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 0)); + caster.addPotionEffect(new PotionEffect(Wizardry.iceShroud.id, (int)(600*durationMultiplier), 0, true)); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); } - caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/IceSpikes.java b/src/main/java/electroblob/wizardry/spell/IceSpikes.java index 95325e0f..917a21ab 100644 --- a/src/main/java/electroblob/wizardry/spell/IceSpikes.java +++ b/src/main/java/electroblob/wizardry/spell/IceSpikes.java @@ -1,28 +1,23 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.construct.EntityIceSpike; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MathHelper; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class IceSpikes extends Spell { public IceSpikes() { - super(Tier.ADVANCED, 30, Element.ICE, "ice_spikes", SpellType.ATTACK, 75, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 30, EnumElement.ICE, "ice_spikes", EnumSpellType.ATTACK, 75, EnumAction.none, false); } @Override @@ -31,43 +26,43 @@ public class IceSpikes extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(20*modifiers.get(WizardryItems.range_upgrade), world, caster, false); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(20*rangeMultiplier, world, caster, false); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK && rayTrace.sideHit == EnumFacing.UP){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK && rayTrace.sideHit == 1){ if(!world.isRemote){ - double x = rayTrace.hitVec.xCoord; - double y = rayTrace.hitVec.yCoord; - double z = rayTrace.hitVec.zCoord; + double x = rayTrace.blockX; + double y = rayTrace.blockY; + double z = rayTrace.blockZ; - for(int i=0; i<(int)(18*modifiers.get(WizardryItems.blast_upgrade)); i++){ + for(int i=0; i<(int)(18*blastMultiplier); i++){ float angle = (float)(world.rand.nextFloat()*Math.PI*2); - double radius = 0.5 + world.rand.nextDouble()*2*modifiers.get(WizardryItems.blast_upgrade); + double radius = 0.5 + world.rand.nextDouble()*2*blastMultiplier; double x1 = x + radius*MathHelper.sin(angle); double z1 = z + radius*MathHelper.cos(angle); - double y1 = WizardryUtilities.getNearestFloorLevel(world, new BlockPos(MathHelper.floor_double(x1), (int)y, MathHelper.floor_double(z1)), 2) - 1; + double y1 = WizardryUtilities.getNearestFloorLevel(world, MathHelper.floor_double(x1), (int)y, MathHelper.floor_double(z1), 2) - 1; if(y1 > -1){ - EntityIceSpike icespike = new EntityIceSpike(world, x1, y1, z1, caster, 30 + world.rand.nextInt(15), modifiers.get(SpellModifiers.DAMAGE)); + EntityIceSpike icespike = new EntityIceSpike(world, x1, y1, z1, caster, 30 + world.rand.nextInt(15), damageMultiplier); world.spawnEntityInWorld(icespike); } } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, 1.0F); return true; } return false; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ @@ -77,23 +72,23 @@ public class IceSpikes extends Spell { double y = target.posY; double z = target.posZ; - for(int i=0; i<(int)(18*modifiers.get(WizardryItems.blast_upgrade)); i++){ + for(int i=0; i<(int)(18*blastMultiplier); i++){ float angle = (float)(world.rand.nextFloat()*Math.PI*2); - double radius = 0.5 + world.rand.nextDouble()*2*modifiers.get(WizardryItems.blast_upgrade); + double radius = 0.5 + world.rand.nextDouble()*2*blastMultiplier; double x1 = x + radius*MathHelper.sin(angle); double z1 = z + radius*MathHelper.cos(angle); - double y1 = WizardryUtilities.getNearestFloorLevel(world, new BlockPos(MathHelper.floor_double(x1), (int)y, MathHelper.floor_double(z1)), 2) - 1; + double y1 = WizardryUtilities.getNearestFloorLevel(world, MathHelper.floor_double(x1), (int)y, MathHelper.floor_double(z1), 2) - 1; if(y1 > -1){ - EntityIceSpike icespike = new EntityIceSpike(world, x1, y1, z1, caster, 30 + world.rand.nextInt(15), modifiers.get(SpellModifiers.DAMAGE)); + EntityIceSpike icespike = new EntityIceSpike(world, x1, y1, z1, caster, 30 + world.rand.nextInt(15), damageMultiplier); world.spawnEntityInWorld(icespike); } } } - caster.swingArm(hand); - caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/IceStatue.java b/src/main/java/electroblob/wizardry/spell/IceStatue.java index 1928421a..9635ce50 100644 --- a/src/main/java/electroblob/wizardry/spell/IceStatue.java +++ b/src/main/java/electroblob/wizardry/spell/IceStatue.java @@ -1,25 +1,19 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryAchievements; -import electroblob.wizardry.registry.WizardryBlocks; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.tileentity.TileEntityStatue; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.monster.EntityBlaze; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class IceStatue extends Spell { @@ -27,21 +21,23 @@ public class IceStatue extends Spell { private static final int baseDuration = 400; public IceStatue() { - super(Tier.APPRENTICE, 15, Element.ICE, "ice_statue", SpellType.ATTACK, 40, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 15, EnumElement.ICE, "ice_statue", EnumSpellType.ATTACK, 40, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - Vec3d look = caster.getLookVec(); + Vec3 look = caster.getLookVec(); - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLiving && !world.isRemote){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLiving && !world.isRemote){ EntityLiving target = (EntityLiving) rayTrace.entityHit; - - BlockPos pos = new BlockPos(target); + + int x = (int)Math.floor(target.posX); + int y = (int)Math.floor(target.posY); + int z = (int)Math.floor(target.posZ); if(target.isBurning()){ target.extinguish(); @@ -50,69 +46,69 @@ public class IceStatue extends Spell { // Stops the entity looking red while frozen and the resulting z-fighting target.hurtTime = 0; - if(target instanceof EntityBlaze) caster.addStat(WizardryAchievements.freeze_blaze, 1); + if(target instanceof EntityBlaze) caster.addStat(Wizardry.freezeBlaze, 1); // Short mobs such as spiders and pigs - if((target.height < 1.2 || target.isChild()) && WizardryUtilities.canBlockBeReplaced(world, pos)){ - world.setBlockState(pos, WizardryBlocks.ice_statue.getDefaultState()); - if(world.getTileEntity(pos) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart(target, 1, 1); - ((TileEntityStatue)world.getTileEntity(pos)).setLifetime((int)(baseDuration*modifiers.get(WizardryItems.duration_upgrade))); + if((target.height < 1.2 || target.isChild()) && WizardryUtilities.canBlockBeReplaced(world, x, y, z)){ + world.setBlock(x, y, z, Wizardry.iceStatue); + if(world.getTileEntity(x, y, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y, z)).setCreatureAndPart(target, 1, 1); + ((TileEntityStatue)world.getTileEntity(x, y, z)).setLifetime((int)(baseDuration*durationMultiplier)); } target.setDead(); - target.playSound(WizardrySounds.SPELL_FREEZE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); + world.playSoundAtEntity(target, "wizardry:freeze", 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); } // Normal sized mobs like zombies and skeletons - else if(target.height < 2.5 && WizardryUtilities.canBlockBeReplaced(world, pos) && WizardryUtilities.canBlockBeReplaced(world, pos.up())){ - world.setBlockState(pos, WizardryBlocks.ice_statue.getDefaultState()); - if(world.getTileEntity(pos) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart(target, 1, 2); - ((TileEntityStatue)world.getTileEntity(pos)).setLifetime((int)(baseDuration*modifiers.get(WizardryItems.duration_upgrade))); + else if(target.height < 2.5 && WizardryUtilities.canBlockBeReplaced(world, x, y, z) && WizardryUtilities.canBlockBeReplaced(world, x, y+1, z)){ + world.setBlock(x, y, z, Wizardry.iceStatue); + if(world.getTileEntity(x, y, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y, z)).setCreatureAndPart(target, 1, 2); + ((TileEntityStatue)world.getTileEntity(x, y, z)).setLifetime((int)(baseDuration*durationMultiplier)); } - world.setBlockState(pos.up(), WizardryBlocks.ice_statue.getDefaultState()); - if(world.getTileEntity(pos.up()) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos.up())).setCreatureAndPart(target, 2, 2); + world.setBlock(x, y+1, z, Wizardry.iceStatue); + if(world.getTileEntity(x, y+1, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y+1, z)).setCreatureAndPart(target, 2, 2); } target.setDead(); - target.playSound(WizardrySounds.SPELL_FREEZE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); + world.playSoundAtEntity(target, "wizardry:freeze", 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); } // Tall mobs like endermen and iron golems - else if(WizardryUtilities.canBlockBeReplaced(world, pos) && WizardryUtilities.canBlockBeReplaced(world, pos.up()) && WizardryUtilities.canBlockBeReplaced(world, pos.up(2))){ - world.setBlockState(pos, WizardryBlocks.ice_statue.getDefaultState()); - if(world.getTileEntity(pos) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart(target, 1, 3); - ((TileEntityStatue)world.getTileEntity(pos)).setLifetime((int)(baseDuration*modifiers.get(WizardryItems.duration_upgrade))); + else if(WizardryUtilities.canBlockBeReplaced(world, x, y, z) && WizardryUtilities.canBlockBeReplaced(world, x, y+1, z) && WizardryUtilities.canBlockBeReplaced(world, x, y+2, z)){ + world.setBlock(x, y, z, Wizardry.iceStatue); + if(world.getTileEntity(x, y, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y, z)).setCreatureAndPart(target, 1, 3); + ((TileEntityStatue)world.getTileEntity(x, y, z)).setLifetime((int)(baseDuration*durationMultiplier)); } - world.setBlockState(pos.up(), WizardryBlocks.ice_statue.getDefaultState()); - if(world.getTileEntity(pos.up()) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos.up())).setCreatureAndPart(target, 2, 3); + world.setBlock(x, y+1, z, Wizardry.iceStatue); + if(world.getTileEntity(x, y+1, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y+1, z)).setCreatureAndPart(target, 2, 3); } - world.setBlockState(pos.up(2), WizardryBlocks.ice_statue.getDefaultState()); - if(world.getTileEntity(pos.up(2)) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos.up(2))).setCreatureAndPart(target, 3, 3); + world.setBlock(x, y+2, z, Wizardry.iceStatue); + if(world.getTileEntity(x, y+2, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y+2, z)).setCreatureAndPart(target, 3, 3); } target.setDead(); - target.playSound(WizardrySounds.SPELL_FREEZE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); + world.playSoundAtEntity(target, "wizardry:freeze", 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); } } if(world.isRemote){ - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ float brightness = 0.5f + (world.rand.nextFloat()/2); double x1 = caster.posX + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), brightness, brightness + 0.1f, 1.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.SNOW, world, x1, y1, z1, 0.0d, -0.02d, 0.0d, 20 + world.rand.nextInt(10)); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), brightness, brightness + 0.1f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SNOW, world, x1, y1, z1, 0.0d, -0.02d, 0.0d, 20 + world.rand.nextInt(10)); } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.4F + 1.2F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.4F + 1.2F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Ignite.java b/src/main/java/electroblob/wizardry/spell/Ignite.java index 2807a570..a6eb665e 100644 --- a/src/main/java/electroblob/wizardry/spell/Ignite.java +++ b/src/main/java/electroblob/wizardry/spell/Ignite.java @@ -1,97 +1,141 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; +import electroblob.wizardry.entity.living.EntityIceGiant; +import electroblob.wizardry.entity.living.EntityIceWraith; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntitySnowman; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class Ignite extends Spell { public Ignite() { - super(Tier.BASIC, 5, Element.FIRE, "ignite", SpellType.ATTACK, 10, EnumAction.NONE, false); + super(EnumTier.BASIC, 5, EnumElement.FIRE, "ignite", EnumSpellType.ATTACK, 10, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { - + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { + // Entity ray trace is done first because block ray trace passes through entities; if it was the other // way round, entities would only be hit when there were no blocks in range behind them. - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade)); - - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ - + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier); + + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ + EntityLivingBase target = (EntityLivingBase) rayTrace.entityHit; - + if(MagicDamage.isEntityImmune(DamageType.FIRE, target)){ - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", target.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", target.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else{ - target.setFire((int)(10*modifiers.get(WizardryItems.duration_upgrade))); + target.setFire((int)(10*durationMultiplier)); } - + if(world.isRemote){ double dx = target.posX - caster.posX; - double dy = (target.getEntityBoundingBox().minY + target.height/2) - WizardryUtilities.getPlayerEyesPos(caster); + double dy = (WizardryUtilities.getEntityFeetPos(target) + target.height/2) - WizardryUtilities.getPlayerEyesPos(caster); double dz = target.posZ - caster.posZ; // i starts at 1 so that particles are not spawned in the player's head. for(int i=1;i<5;i++){ - //WizardryUtilities.spawnParticleAndNotify(world, EnumParticleTypes.FLAME, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0, 0, 0, 0, 0); - //WizardryUtilities.spawnParticleAndNotify(world, EnumParticleTypes.FLAME, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0, 0, 0, 0, 0); - world.spawnParticle(EnumParticleTypes.FLAME, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0); - world.spawnParticle(EnumParticleTypes.FLAME, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0); + //WizardryUtilities.spawnParticleAndNotify(world, "flame", caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0, 0, 0, 0, 0); + //WizardryUtilities.spawnParticleAndNotify(world, "flame", caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0, 0, 0, 0, 0); + world.spawnParticle("flame", caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0); + world.spawnParticle("flame", caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0); } } - - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ITEM_FLINTANDSTEEL_USE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); - + + caster.swingItem(); + world.playSoundEffect((double)caster.posX + 0.5D, (double)caster.posY + 1.5D, (double)caster.posZ + 0.5D, "fire.ignite", 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); + return true; - + }else{ - - rayTrace = WizardryUtilities.rayTrace(10*modifiers.get(WizardryItems.range_upgrade), world, caster, false); - + + rayTrace = WizardryUtilities.rayTrace(10*rangeMultiplier, world, caster, false); + // Gets block the player is looking at and sets the appropriate surrounding air block to fire. // Note how the block is set on the server side only (kinda obvious really) but the particles are // spawned on the client side only. - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ - - BlockPos pos = rayTrace.getBlockPos().offset(rayTrace.sideHit); - - if(world.isAirBlock(pos)){ - if(!world.isRemote){ - world.setBlockState(pos, Blocks.FIRE.getDefaultState()); + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ + + int blockHitX = rayTrace.blockX; + int blockHitY = rayTrace.blockY; + int blockHitZ = rayTrace.blockZ; + int blockHitSide = rayTrace.sideHit; + boolean flag = false; + switch(blockHitSide){ + case 0: + if(world.isAirBlock(blockHitX, blockHitY-1, blockHitZ)){ + if(!world.isRemote){ + world.setBlock(blockHitX, blockHitY-1, blockHitZ, Blocks.fire); + } + flag = true; } - + break; + case 1: + if(world.isAirBlock(blockHitX, blockHitY+1, blockHitZ)){ + if(!world.isRemote){ + world.setBlock(blockHitX, blockHitY+1, blockHitZ, Blocks.fire); + } + flag = true; + } + break; + case 2: + if(world.isAirBlock(blockHitX, blockHitY, blockHitZ-1)){ + if(!world.isRemote){ + world.setBlock(blockHitX, blockHitY, blockHitZ-1, Blocks.fire); + } + flag = true; + } + break; + case 3: + if(world.isAirBlock(blockHitX, blockHitY, blockHitZ+1)){ + if(!world.isRemote){ + world.setBlock(blockHitX, blockHitY, blockHitZ+1, Blocks.fire); + } + flag = true; + } + break; + case 4: + if(world.isAirBlock(blockHitX-1, blockHitY, blockHitZ)){ + if(!world.isRemote){ + world.setBlock(blockHitX-1, blockHitY, blockHitZ, Blocks.fire); + } + flag = true; + } + break; + case 5: + if(world.isAirBlock(blockHitX+1, blockHitY, blockHitZ)){ + if(!world.isRemote){ + world.setBlock(blockHitX+1, blockHitY, blockHitZ, Blocks.fire); + } + flag = true; + } + break; + } + if(flag){ + double dx = blockHitX + 0.5 - caster.posX; + double dy = blockHitY + 1.5 - (WizardryUtilities.getPlayerEyesPos(caster) + 1); + double dz = blockHitZ + 0.5 - caster.posZ; if(world.isRemote){ - - double dx = pos.getX() + 0.5 - caster.posX; - double dy = pos.getY() + 0.5 - WizardryUtilities.getPlayerEyesPos(caster); - double dz = pos.getZ() + 0.5 - caster.posZ; - for(int i=1;i<5;i++){ - world.spawnParticle(EnumParticleTypes.FLAME, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0); - world.spawnParticle(EnumParticleTypes.FLAME, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0); + world.spawnParticle("flame", caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0); + world.spawnParticle("flame", caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0); } } - - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ITEM_FLINTANDSTEEL_USE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); + caster.swingItem(); + world.playSoundEffect((double)caster.posX + 0.5D, (double)caster.posY + 1.5D, (double)caster.posZ + 0.5D, "fire.ignite", 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); return true; } } @@ -100,34 +144,34 @@ public class Ignite extends Spell { } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ - + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ + if(target != null){ - - if(!MagicDamage.isEntityImmune(DamageType.FIRE, target)) target.setFire((int)(10*modifiers.get(WizardryItems.duration_upgrade))); - + + if(!MagicDamage.isEntityImmune(DamageType.FIRE, target)) target.setFire((int)(10*durationMultiplier)); + if(world.isRemote){ double dx = target.posX - caster.posX; - double dy = (target.getEntityBoundingBox().minY + target.height/2) - (caster.posY + caster.getEyeHeight()); + double dy = (WizardryUtilities.getEntityFeetPos(target) + target.height/2) - (caster.posY + caster.getEyeHeight()); double dz = target.posZ - caster.posZ; // i starts at 1 so that particles are not spawned in the player's head. for(int i=1;i<5;i++){ - //WizardryUtilities.spawnParticleAndNotify(world, EnumParticleTypes.FLAME, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0, 0, 0, 0, 0); - //WizardryUtilities.spawnParticleAndNotify(world, EnumParticleTypes.FLAME, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0, 0, 0, 0, 0); - world.spawnParticle(EnumParticleTypes.FLAME, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + caster.getEyeHeight() + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0); - world.spawnParticle(EnumParticleTypes.FLAME, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + caster.getEyeHeight() + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0); + //WizardryUtilities.spawnParticleAndNotify(world, "flame", caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0, 0, 0, 0, 0); + //WizardryUtilities.spawnParticleAndNotify(world, "flame", caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0, 0, 0, 0, 0); + world.spawnParticle("flame", caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + caster.getEyeHeight() + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0); + world.spawnParticle("flame", caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, caster.posY + caster.getEyeHeight() + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, 0, 0); } } - - caster.swingArm(hand); - caster.playSound(SoundEvents.ITEM_FLINTANDSTEEL_USE, 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); - + + caster.swingItem(); + world.playSoundEffect((double)caster.posX + 0.5D, (double)caster.posY + 1.5D, (double)caster.posZ + 0.5D, "fire.ignite", 1.0F, world.rand.nextFloat() * 0.4F + 0.8F); + return true; } - + return false; } - + @Override public boolean canBeCastByNPCs(){ return true; diff --git a/src/main/java/electroblob/wizardry/spell/ImbueWeapon.java b/src/main/java/electroblob/wizardry/spell/ImbueWeapon.java index f2dbbcf6..85f29331 100644 --- a/src/main/java/electroblob/wizardry/spell/ImbueWeapon.java +++ b/src/main/java/electroblob/wizardry/spell/ImbueWeapon.java @@ -1,71 +1,79 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.WizardData; +import java.util.List; + +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Constants; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryEnchantments; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.ContainerPlayer; +import net.minecraft.inventory.Slot; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemBow; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class ImbueWeapon extends Spell { public ImbueWeapon() { - super(Tier.APPRENTICE, 20, Element.SORCERY, "imbue_weapon", SpellType.UTILITY, 50, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 20, EnumElement.SORCERY, "imbue_weapon", EnumSpellType.UTILITY, 50, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { // Won't work if the weapon already has the enchantment - if(WizardData.get(caster) != null){ + if(ExtendedPlayer.get(caster) != null && ExtendedPlayer.get(caster).magicWeaponDuration <= 0){ - for(ItemStack stack : WizardryUtilities.getPrioritisedHotbarAndOffhand(caster)){ + // Isolates just the hotbar + List hotbar = ((ContainerPlayer)caster.openContainer).inventorySlots.subList(36, 45); - if(stack != null){ + for(Object slot : hotbar){ - if(stack.getItem() instanceof ItemSword && !EnchantmentHelper.getEnchantments(stack).containsKey(WizardryEnchantments.magic_sword) - && WizardData.get(caster).getImbuementDuration(WizardryEnchantments.magic_sword) <= 0){ - // The enchantment level as determined by the damage multiplier. The + 0.5f is so that - // weird float processing doesn't incorrectly round it down. - stack.addEnchantment(WizardryEnchantments.magic_sword, modifiers.get(SpellModifiers.DAMAGE) == 1.0f ? 1 : (int)((modifiers.get(SpellModifiers.DAMAGE) - 1.0f)/Constants.DAMAGE_INCREASE_PER_TIER + 0.5f)); - WizardData.get(caster).setImbuementDuration(WizardryEnchantments.magic_sword, (int)(900*modifiers.get(WizardryItems.duration_upgrade))); + if(slot instanceof Slot){ - }else if(stack.getItem() instanceof ItemBow && !EnchantmentHelper.getEnchantments(stack).containsKey(WizardryEnchantments.magic_bow) - && WizardData.get(caster).getImbuementDuration(WizardryEnchantments.magic_bow) <= 0){ - // The enchantment level as determined by the damage multiplier. The + 0.5f is so that - // weird float processing doesn't incorrectly round it down. - stack.addEnchantment(WizardryEnchantments.magic_bow, modifiers.get(SpellModifiers.DAMAGE) == 1.0f ? 1 : (int)((modifiers.get(SpellModifiers.DAMAGE) - 1.0f)/Constants.DAMAGE_INCREASE_PER_TIER + 0.5f)); - WizardData.get(caster).setImbuementDuration(WizardryEnchantments.magic_bow, (int)(900*modifiers.get(WizardryItems.duration_upgrade))); + ItemStack stack = ((Slot)slot).getStack(); - }else{ - continue; - } + if(stack != null){ - if(world.isRemote){ - for(int i=0; i<10; i++){ - double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); - double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); - double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.9f, 0.7f, 1.0f); + boolean flag = false; + + if(stack.getItem() instanceof ItemSword && !EnchantmentHelper.getEnchantments(stack).containsKey(Wizardry.magicSword.effectId)){ + // The enchantment level as determined by the damage multiplier. The + 0.5f is so that + // weird float processing doesn't incorrectly round it down. + stack.addEnchantment(Wizardry.magicSword, damageMultiplier == 1.0f ? 1 : (int)((damageMultiplier - 1.0f)/Wizardry.DAMAGE_INCREASE_PER_TIER + 0.5f)); + flag = true; + + }else if(stack.getItem() instanceof ItemBow && !EnchantmentHelper.getEnchantments(stack).containsKey(Wizardry.magicBow.effectId)){ + // The enchantment level as determined by the damage multiplier. The + 0.5f is so that + // weird float processing doesn't incorrectly round it down. + stack.addEnchantment(Wizardry.magicBow, damageMultiplier == 1.0f ? 1 : (int)((damageMultiplier - 1.0f)/Wizardry.DAMAGE_INCREASE_PER_TIER + 0.5f)); + flag = true; + } + + if(flag){ + + ExtendedPlayer.get(caster).magicWeaponDuration = (int)(900*durationMultiplier); + + if(world.isRemote){ + for(int i=0; i<10; i++){ + double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); + double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); + double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.9f, 0.7f, 1.0f); + } + } + + world.playSoundAtEntity(caster, "wizardry:aura", 1.0f, 1.0f); + return true; } } - - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f); - return true; } } } diff --git a/src/main/java/electroblob/wizardry/spell/Intimidate.java b/src/main/java/electroblob/wizardry/spell/Intimidate.java index 941a9193..3dbdbd1e 100644 --- a/src/main/java/electroblob/wizardry/spell/Intimidate.java +++ b/src/main/java/electroblob/wizardry/spell/Intimidate.java @@ -2,76 +2,70 @@ package electroblob.wizardry.spell; import java.util.List; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.entity.Entity; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.ai.RandomPositionGenerator; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.pathfinding.PathEntity; import net.minecraft.pathfinding.PathPoint; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.Vec3; import net.minecraft.world.World; -import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -@Mod.EventBusSubscriber public class Intimidate extends Spell { - /** The NBT tag name for storing the feared entity's UUID in the target's tag compound. */ + /** The NBT tag name for storing the feared entity's UUID in the target's tag compound. Defined here in case + * it changes. */ public static final String NBT_KEY = "fearedEntity"; public Intimidate() { - super(Tier.APPRENTICE, 20, Element.NECROMANCY, "intimidate", SpellType.ATTACK, 100, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 20, EnumElement.NECROMANCY, "intimidate", EnumSpellType.ATTACK, 100, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - List entities = WizardryUtilities.getEntitiesWithinRadius(8*modifiers.get(WizardryItems.range_upgrade), caster.posX, caster.posY, caster.posZ, world, EntityCreature.class); + List entities = WizardryUtilities.getEntitiesWithinRadius(8*rangeMultiplier, caster.posX, caster.posY, caster.posZ, world, EntityCreature.class); for(EntityCreature target : entities){ runAway(target, caster); NBTTagCompound entityNBT = target.getEntityData(); - if(entityNBT != null) entityNBT.setUniqueId(NBT_KEY, caster.getUniqueID()); + if(entityNBT != null) entityNBT.setString(NBT_KEY, caster.getUniqueID().toString()); - ((EntityLiving)target).addPotionEffect(new PotionEffect(WizardryPotions.fear, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 0)); + ((EntityLiving)target).addPotionEffect(new PotionEffect(Wizardry.fear.id, (int)(600*durationMultiplier), 0)); } }else{ for(int i=0; i<30; i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, caster.posX - 1 + world.rand.nextDouble()*2, - caster.getEntityBoundingBox().minY + 1.5 + world.rand.nextDouble()*0.5, + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, caster.posX - 1 + world.rand.nextDouble()*2, + caster.boundingBox.minY + 1.5 + world.rand.nextDouble()*0.5, caster.posZ - 1 + world.rand.nextDouble()*2, 0, 0, 0, 0, 0.9f, 0.1f, 0.0f); } } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ENDERDRAGON_GROWL, 1.0f, 1.0f); + world.playSoundAtEntity(caster, "mob.enderdragon.growl", 1.0f, 1.0f); return true; } /** - * Finds a random position away from the caster and sets the given target's AI path to that location. Defined here - * so it can be used both in the spell itself and in the potion effect (event handler). + * Finds a random position away from the caster and sets the given target's AI path to that location. Handles both + * new AI and old AI. Defined here so it can be used both in the spell itself and in the potion effect (event handler). * @param target The entity running away * @param caster The entity that is being run away from * @return True if a new path was found and set, false if not. @@ -80,16 +74,21 @@ public class Intimidate extends Spell { if(target.getDistanceToEntity(caster) < 16){ - Vec3d Vec3d = RandomPositionGenerator.findRandomTargetBlockAwayFrom(target, 16, 7, new Vec3d(caster.posX, caster.posY, caster.posZ)); + Vec3 vec3 = RandomPositionGenerator.findRandomTargetBlockAwayFrom(target, 16, 7, Vec3.createVectorHelper(caster.posX, caster.posY, caster.posZ)); - if (Vec3d == null){ + if (vec3 == null){ return false; }else{ // In both cases it is necessary to check if the entity already has a path so it doesn't change direction // every tick, unless that path is towards the caster. - //Path path = target.getNavigator().getPathToXYZ(Vec3d.xCoord, Vec3d.yCoord, Vec3d.zCoord); + PathEntity path = target.getNavigator().getPathToXYZ(vec3.xCoord, vec3.yCoord, vec3.zCoord); + // Old AI + if(!target.hasPath() || target.getEntityToAttack() == caster) target.setPathToEntity(path); + target.setTarget(null); + + // New AI boolean flag = true; if(!target.getNavigator().noPath()){ @@ -99,30 +98,11 @@ public class Intimidate extends Spell { // Has a built in mind trick effect because for whatever reason this makes it work with skeletons. target.setAttackTarget(null); - if(flag) return target.getNavigator().tryMoveToXYZ(Vec3d.xCoord, Vec3d.yCoord, Vec3d.zCoord, 1.25);//target.getEntityAttribute(SharedMonsterAttributes.movementSpeed).getAttributeValue()); + if(flag) return target.getNavigator().tryMoveToXYZ(vec3.xCoord, vec3.yCoord, vec3.zCoord, 1.25);//target.getEntityAttribute(SharedMonsterAttributes.movementSpeed).getAttributeValue()); } } return false; } - - @SubscribeEvent - public static void onLivingUpdateEvent(LivingUpdateEvent event){ - - if(event.getEntityLiving().isPotionActive(WizardryPotions.fear) && event.getEntityLiving() instanceof EntityCreature){ - - NBTTagCompound entityNBT = event.getEntityLiving().getEntityData(); - EntityCreature creature = (EntityCreature)event.getEntityLiving(); - - if(entityNBT != null && entityNBT.hasKey(NBT_KEY)){ - - Entity caster = WizardryUtilities.getEntityByUUID(creature.worldObj, entityNBT.getUniqueId(NBT_KEY)); - - if(caster instanceof EntityLivingBase){ - Intimidate.runAway(creature, (EntityLivingBase)caster); - } - } - } - } } diff --git a/src/main/java/electroblob/wizardry/spell/InvigoratingPresence.java b/src/main/java/electroblob/wizardry/spell/InvigoratingPresence.java index b4cbc77d..920dc41b 100644 --- a/src/main/java/electroblob/wizardry/spell/InvigoratingPresence.java +++ b/src/main/java/electroblob/wizardry/spell/InvigoratingPresence.java @@ -2,51 +2,48 @@ package electroblob.wizardry.spell; import java.util.List; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class InvigoratingPresence extends Spell { public InvigoratingPresence() { - super(Tier.APPRENTICE, 30, Element.HEALING, "invigorating_presence", SpellType.UTILITY, 60, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 30, EnumElement.HEALING, "invigorating_presence", EnumSpellType.UTILITY, 60, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - List targets = WizardryUtilities.getEntitiesWithinRadius(5*modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world, EntityPlayer.class); + List targets = WizardryUtilities.getEntitiesWithinRadius(5*blastMultiplier, caster.posX, caster.posY, caster.posZ, world, EntityPlayer.class); for(EntityPlayer target : targets){ if(WizardryUtilities.isPlayerAlly(caster, target) || target == caster){ // Strength 2 for 45 seconds. - target.addPotionEffect(new PotionEffect(MobEffects.STRENGTH, (int)(900*modifiers.get(WizardryItems.duration_upgrade)), 1, false, false)); + target.addPotionEffect(new PotionEffect(Potion.damageBoost.id, (int)(900*durationMultiplier), 1, true)); } } if(world.isRemote){ - for(int i=0;i<50*modifiers.get(WizardryItems.blast_upgrade);i++){ - double radius = (1 + world.rand.nextDouble()*4)*modifiers.get(WizardryItems.blast_upgrade); + for(int i=0;i<50*blastMultiplier;i++){ + double radius = (1 + world.rand.nextDouble()*4)*blastMultiplier; double angle = world.rand.nextDouble()*Math.PI*2; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, caster.posX + radius*Math.cos(angle), caster.getEntityBoundingBox().minY, caster.posZ + radius*Math.sin(angle), + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, caster.posX + radius*Math.cos(angle), WizardryUtilities.getEntityFeetPos(caster), caster.posZ + radius*Math.sin(angle), 0, 0.03, 0, 50, 1, 0.2f, 0.2f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:aura", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Invisibility.java b/src/main/java/electroblob/wizardry/spell/Invisibility.java index a26836d2..7d9cf512 100644 --- a/src/main/java/electroblob/wizardry/spell/Invisibility.java +++ b/src/main/java/electroblob/wizardry/spell/Invisibility.java @@ -1,62 +1,58 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class Invisibility extends Spell { public Invisibility() { - super(Tier.ADVANCED, 35, Element.SORCERY, "invisibility", SpellType.UTILITY, 200, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 35, EnumElement.SORCERY, "invisibility", EnumSpellType.UTILITY, 200, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - caster.addPotionEffect(new PotionEffect(MobEffects.INVISIBILITY, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 0, false, false)); + caster.addPotionEffect(new PotionEffect(Potion.invisibility.id, (int)(600*durationMultiplier), 0, true)); if(world.isRemote){ for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.7f, 1.0f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.7f, 1.0f, 1.0f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ - if(!caster.isPotionActive(MobEffects.INVISIBILITY)){ + if(!caster.isPotionActive(Potion.invisibility)){ - caster.addPotionEffect(new PotionEffect(MobEffects.INVISIBILITY, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 0, false, false)); + caster.addPotionEffect(new PotionEffect(Potion.invisibility.id, (int)(600*durationMultiplier), 0, true)); if(world.isRemote){ for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)caster.posY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.7f, 1.0f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.7f, 1.0f, 1.0f); } } - caster.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/InvokeWeather.java b/src/main/java/electroblob/wizardry/spell/InvokeWeather.java index 98fd97c6..a03e9016 100644 --- a/src/main/java/electroblob/wizardry/spell/InvokeWeather.java +++ b/src/main/java/electroblob/wizardry/spell/InvokeWeather.java @@ -2,62 +2,47 @@ package electroblob.wizardry.spell; import java.util.Random; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; import net.minecraft.world.World; public class InvokeWeather extends Spell { public InvokeWeather() { - super(Tier.ADVANCED, 30, Element.LIGHTNING, "invoke_weather", SpellType.UTILITY, 100, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 30, EnumElement.LIGHTNING, "invoke_weather", EnumSpellType.UTILITY, 100, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(caster.dimension == 0){ - if(!world.isRemote){ - // TODO: Backport these changes. - int standardWeatherTime = (300 + (new Random()).nextInt(600)) * 20; if(world.isRaining()){ - caster.addChatComponentMessage(new TextComponentTranslation("spell.invoke_weather.sun")); - world.getWorldInfo().setCleanWeatherTime(standardWeatherTime); + caster.addChatComponentMessage(new ChatComponentTranslation("spell.invoke_weather.sun")); world.getWorldInfo().setRainTime(0); - world.getWorldInfo().setThunderTime(0); world.getWorldInfo().setRaining(false); - world.getWorldInfo().setThundering(false); }else{ - caster.addChatComponentMessage(new TextComponentTranslation("spell.invoke_weather.rain")); - world.getWorldInfo().setCleanWeatherTime(0); - world.getWorldInfo().setRainTime(standardWeatherTime); - world.getWorldInfo().setThunderTime(standardWeatherTime); + caster.addChatComponentMessage(new ChatComponentTranslation("spell.invoke_weather.rain")); + world.getWorldInfo().setRainTime((300 + (new Random()).nextInt(600)) * 20); world.getWorldInfo().setRaining(true); - // 1/3 chance for a thunderstorm - world.getWorldInfo().setThundering(world.rand.nextInt(3) == 0); } } - if(world.isRemote){ for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.5f, 0.7f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.5f, 0.7f, 1.0f); } } - - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_LIGHTNING_THUNDER, 0.5F, 1.0f); + world.playSoundAtEntity(caster, "ambient.weather.thunder", 0.5F, 1.0f); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/Ironflesh.java b/src/main/java/electroblob/wizardry/spell/Ironflesh.java index 0997439b..e1e316c3 100644 --- a/src/main/java/electroblob/wizardry/spell/Ironflesh.java +++ b/src/main/java/electroblob/wizardry/spell/Ironflesh.java @@ -1,64 +1,60 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class Ironflesh extends Spell { public Ironflesh() { - super(Tier.ADVANCED, 30, Element.HEALING, "ironflesh", SpellType.DEFENCE, 100, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 30, EnumElement.HEALING, "ironflesh", EnumSpellType.DEFENCE, 100, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - caster.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 2, false, false)); + caster.addPotionEffect(new PotionEffect(Potion.resistance.id, (int)(600*durationMultiplier), 2, true)); if(world.isRemote){ for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.4f, 0.5f, 0.6f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.4f, 0.5f, 0.6f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ - if(!caster.isPotionActive(MobEffects.RESISTANCE)){ + if(!caster.isPotionActive(Potion.resistance)){ - caster.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 2, false, false)); + caster.addPotionEffect(new PotionEffect(Potion.resistance.id, (int)(600*durationMultiplier), 2, true)); if(world.isRemote){ for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)caster.posY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.4f, 0.5f, 0.6f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.4f, 0.5f, 0.6f); } } - caster.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Leap.java b/src/main/java/electroblob/wizardry/spell/Leap.java index 49c2265c..130a6278 100644 --- a/src/main/java/electroblob/wizardry/spell/Leap.java +++ b/src/main/java/electroblob/wizardry/spell/Leap.java @@ -1,42 +1,40 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; import net.minecraft.world.World; public class Leap extends Spell { public Leap() { - super(Tier.BASIC, 10, Element.EARTH, "leap", SpellType.UTILITY, 20, EnumAction.NONE, false); + super(EnumTier.BASIC, 10, EnumElement.EARTH, "leap", EnumSpellType.UTILITY, 20, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(caster.onGround){ - caster.motionY = 0.65 * modifiers.get(SpellModifiers.DAMAGE); + caster.motionY = 0.65 * damageMultiplier; caster.addVelocity(caster.getLookVec().xCoord*0.3, 0, caster.getLookVec().zCoord*0.3); if(world.isRemote){ for(int i=0; i<10; i++){ double x = (double)(caster.posX + world.rand.nextFloat() - 0.5F); - double y = (double)(caster.getEntityBoundingBox().minY); + double y = (double)(caster.boundingBox.minY); double z = (double)(caster.posZ + world.rand.nextFloat() - 0.5F); - world.spawnParticle(EnumParticleTypes.CLOUD, x, y, z, 0, 0, 0); + world.spawnParticle("cloud", x, y, z, 0, 0, 0); } } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ENDERDRAGON_FLAP, 0.5F, 1.0f); - caster.swingArm(hand); + world.playSoundAtEntity(caster, "mob.enderdragon.wings", 0.5F, 1.0f); + caster.swingItem(); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Levitation.java b/src/main/java/electroblob/wizardry/spell/Levitation.java index cc67b263..2e9d3b26 100644 --- a/src/main/java/electroblob/wizardry/spell/Levitation.java +++ b/src/main/java/electroblob/wizardry/spell/Levitation.java @@ -1,36 +1,33 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class Levitation extends Spell { - public Levitation(){ - super(Tier.ADVANCED, 10, Element.SORCERY, "levitation", SpellType.UTILITY, 0, EnumAction.BOW, true); + public Levitation() { + super(EnumTier.ADVANCED, 10, EnumElement.SORCERY, "levitation", EnumSpellType.UTILITY, 0, EnumAction.bow, true); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { caster.fallDistance = 0; caster.motionY = caster.motionY < 0.5d ? caster.motionY + 0.1d : caster.motionY; if(world.isRemote){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, caster.posX - 0.25d + world.rand.nextDouble()/2, WizardryUtilities.getPlayerEyesPos(caster) - 1.5f, caster.posZ - 0.25d + world.rand.nextDouble()/2, 0, -0.1F, 0, 15, 0.5f, 1.0f, 0.7f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, caster.posX - 0.25d + world.rand.nextDouble()/2, WizardryUtilities.getPlayerEyesPos(caster) - 1.5f, caster.posZ - 0.25d + world.rand.nextDouble()/2, 0, -0.1F, 0, 15, 0.5f, 1.0f, 0.7f); } if(ticksInUse % 24 == 0 && world.isRemote){ - Wizardry.proxy.playMovingSound(caster, WizardrySounds.SPELL_LOOP_SPARKLE, 0.5F, 1.0f, false); + Wizardry.proxy.playMovingSound(caster, "wizardry:sparkle", 0.5F, 1.0f, false); } return true; } diff --git a/src/main/java/electroblob/wizardry/spell/LifeDrain.java b/src/main/java/electroblob/wizardry/spell/LifeDrain.java index cd2368b6..9327923a 100644 --- a/src/main/java/electroblob/wizardry/spell/LifeDrain.java +++ b/src/main/java/electroblob/wizardry/spell/LifeDrain.java @@ -1,102 +1,72 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.entity.EntityLiving; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class LifeDrain extends Spell { public LifeDrain() { - super(Tier.APPRENTICE, 10, Element.NECROMANCY, "life_drain", SpellType.ATTACK, 0, EnumAction.NONE, true); + super(EnumTier.APPRENTICE, 10, EnumElement.NECROMANCY, "life_drain", EnumSpellType.ATTACK, 0, EnumAction.none, true); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - Vec3d look = caster.getLookVec(); + Vec3 look = caster.getLookVec(); - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ EntityLivingBase target = (EntityLivingBase) rayTrace.entityHit; if(ticksInUse % 12 == 0){ - WizardryUtilities.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC), 2.0f * modifiers.get(SpellModifiers.DAMAGE)); + // This motion stuff removes knockback, which is desirable for continuous spells. + double motionX = target.motionX; + double motionY = target.motionY; + double motionZ = target.motionZ; + + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC), 2.0f * damageMultiplier); + + target.motionX = motionX; + target.motionY = motionY; + target.motionZ = motionZ; + caster.heal(1); } } if(world.isRemote){ - for(int i=5; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=5; i<(int)(25*rangeMultiplier); i+=2){ // I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet! double x1 = caster.posX + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; //world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord); if(i % 5 == 0){ - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); } - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, -0.05*look.xCoord*i, -0.05*look.yCoord*i, -0.05*look.zCoord*i, 8 + world.rand.nextInt(6), 0.5f, 0.0f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, -0.05*look.xCoord*i, -0.05*look.yCoord*i, -0.05*look.zCoord*i, 8 + world.rand.nextInt(6), 0.5f, 0.0f, 0.0f); } } if(ticksInUse % 18 == 0){ - if(ticksInUse == 0) WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SUMMONING, 1.0F, 0.6f); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_CRACKLE, 2.0F, 1.0f); + if(ticksInUse == 0) world.playSoundAtEntity(caster, "wizardry:darkaura", 1.0F, 0.6f); + world.playSoundAtEntity(caster, "wizardry:crackle", 2.0F, 1.0f); } return true; } - @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers) { - - Vec3d vec = new Vec3d(target.posX - caster.posX, target.posY - caster.posY, target.posZ - caster.posZ).normalize(); - - if(target != null){ - if(ticksInUse % 12 == 0){ - WizardryUtilities.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC), 2.0f * modifiers.get(SpellModifiers.DAMAGE)); - caster.heal(1); - } - } - if(world.isRemote){ - for(int i=5; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ - // I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet! - double x1 = caster.posX + vec.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - double y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - double z1 = caster.posZ + vec.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - //world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord); - if(i % 5 == 0){ - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); - } - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, -0.05*vec.xCoord*i, -0.05*vec.yCoord*i, -0.05*vec.zCoord*i, 8 + world.rand.nextInt(6), 0.5f, 0.0f, 0.0f); - } - } - if(ticksInUse % 18 == 0){ - if(ticksInUse == 0) caster.playSound(WizardrySounds.SPELL_SUMMONING, 1.0F, 0.6f); - caster.playSound(WizardrySounds.SPELL_LOOP_CRACKLE, 2.0F, 1.0f); - } - - return true; - } - - @Override - public boolean canBeCastByNPCs() { - return true; - } } diff --git a/src/main/java/electroblob/wizardry/spell/Light.java b/src/main/java/electroblob/wizardry/spell/Light.java index 96d056c8..5f0be405 100644 --- a/src/main/java/electroblob/wizardry/spell/Light.java +++ b/src/main/java/electroblob/wizardry/spell/Light.java @@ -1,25 +1,21 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryBlocks; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.tileentity.TileEntityTimer; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class Light extends Spell { public Light() { - super(Tier.BASIC, 5, Element.SORCERY, "light", SpellType.UTILITY, 15, EnumAction.NONE, false); + super(EnumTier.BASIC, 5, EnumElement.SORCERY, "light", EnumSpellType.UTILITY, 15, EnumAction.none, false); } @Override @@ -28,45 +24,54 @@ public class Light extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(4, world, caster, false); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(4, world, caster, false); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ - BlockPos pos = rayTrace.getBlockPos().offset(rayTrace.sideHit); + int blockHitX = rayTrace.blockX; + int blockHitY = rayTrace.blockY; + int blockHitZ = rayTrace.blockZ; + int blockHitSide = rayTrace.sideHit; - if(world.isAirBlock(pos)){ + switch(blockHitSide){ + case 0: blockHitY--; break; + case 1: blockHitY++; break; + case 2: blockHitZ--; break; + case 3: blockHitZ++; break; + case 4: blockHitX--; break; + case 5: blockHitX++; break; + } + + if(world.isAirBlock(blockHitX, blockHitY, blockHitZ)){ if(!world.isRemote){ - world.setBlockState(pos, WizardryBlocks.magic_light.getDefaultState()); - if(world.getTileEntity(pos) instanceof TileEntityTimer){ - ((TileEntityTimer)world.getTileEntity(pos)).setLifetime((int)(600*modifiers.get(WizardryItems.duration_upgrade))); + world.setBlock(blockHitX, blockHitY, blockHitZ, Wizardry.magicLight); + if(world.getTileEntity(blockHitX, blockHitY, blockHitZ) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(blockHitX, blockHitY, blockHitZ)).setLifetime((int)(600*durationMultiplier)); } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:aura", 1.0f, 1.0f); return true; } }else{ - int x = (int) (Math.floor(caster.posX) + caster.getLookVec().xCoord*4); int y = (int) (Math.floor(caster.posY) + caster.eyeHeight + caster.getLookVec().yCoord*4); int z = (int) (Math.floor(caster.posZ) + caster.getLookVec().zCoord*4); - BlockPos pos = new BlockPos(x, y, z); - - if(world.isAirBlock(pos)){ + if(world.isAirBlock(x, y, z)){ //world.playSound(x, y, z, "sound.ambient.cave.cave", 1.0f, 1.5f, false); if(!world.isRemote){ - world.setBlockState(pos, WizardryBlocks.magic_light.getDefaultState()); - if(world.getTileEntity(pos) instanceof TileEntityTimer){ - ((TileEntityTimer)world.getTileEntity(pos)).setLifetime((int)(600*modifiers.get(WizardryItems.duration_upgrade))); + world.setBlock(x, y, z, Wizardry.magicLight); + if(world.getTileEntity(x, y, z) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity(x, y, z)).setLifetime((int)(600*durationMultiplier)); } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:aura", 1.0f, 1.0f); return true; } } diff --git a/src/main/java/electroblob/wizardry/spell/LightningArrow.java b/src/main/java/electroblob/wizardry/spell/LightningArrow.java index 423fb35e..64086ff9 100644 --- a/src/main/java/electroblob/wizardry/spell/LightningArrow.java +++ b/src/main/java/electroblob/wizardry/spell/LightningArrow.java @@ -1,24 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntityLightningArrow; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class LightningArrow extends Spell { public LightningArrow() { - super(Tier.APPRENTICE, 15, Element.LIGHTNING, "lightning_arrow", SpellType.ATTACK, 20, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 15, EnumElement.LIGHTNING, "lightning_arrow", EnumSpellType.ATTACK, 20, EnumAction.none, false); } @Override @@ -27,30 +22,30 @@ public class LightningArrow extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntityLightningArrow lightningArrow = new EntityLightningArrow(world, caster, 2*modifiers.get(WizardryItems.range_upgrade), modifiers.get(SpellModifiers.DAMAGE)); + EntityLightningArrow lightningArrow = new EntityLightningArrow(world, caster, 2*rangeMultiplier, damageMultiplier); world.spawnEntityInWorld(lightningArrow); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1.0F, world.rand.nextFloat() * 0.3F + 1.3F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:electricitya", 1.0F, world.rand.nextFloat() * 0.3F + 1.3F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntityLightningArrow lightningArrow = new EntityLightningArrow(world, caster, target, 2*modifiers.get(WizardryItems.range_upgrade), 4, modifiers.get(SpellModifiers.DAMAGE)); + EntityLightningArrow lightningArrow = new EntityLightningArrow(world, caster, target, 2*rangeMultiplier, 4, damageMultiplier); world.spawnEntityInWorld(lightningArrow); } - caster.swingArm(hand); - caster.playSound(WizardrySounds.SPELL_LIGHTNING, 1.0F, world.rand.nextFloat() * 0.3F + 1.3F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:electricitya", 1.0F, world.rand.nextFloat() * 0.3F + 1.3F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/LightningBolt.java b/src/main/java/electroblob/wizardry/spell/LightningBolt.java index ae7e1d28..16ec26d2 100644 --- a/src/main/java/electroblob/wizardry/spell/LightningBolt.java +++ b/src/main/java/electroblob/wizardry/spell/LightningBolt.java @@ -1,35 +1,24 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryAchievements; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.WizardryUtilities; +import net.minecraft.block.Block; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.effect.EntityLightningBolt; -import net.minecraft.entity.monster.EntityCreeper; -import net.minecraft.entity.passive.EntityPig; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; -import net.minecraftforge.event.entity.EntityStruckByLightningEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -@Mod.EventBusSubscriber public class LightningBolt extends Spell { - - /** The NBT key used to store the UUID of the player that summoned the lightning bolt. Used for achievements. */ - public static final String NBT_KEY = "summoningPlayer"; public LightningBolt() { - super(Tier.ADVANCED, 40, Element.LIGHTNING, "lightning_bolt", SpellType.ATTACK, 80, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 40, EnumElement.LIGHTNING, "lightning_bolt", EnumSpellType.ATTACK, 80, EnumAction.none, false); } @Override @@ -38,28 +27,29 @@ public class LightningBolt extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(200, world, caster, false); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(200, world, caster, false); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ - BlockPos pos = rayTrace.getBlockPos(); + int i = rayTrace.blockX; + int j = rayTrace.blockY; + int k = rayTrace.blockZ; - // Not sure why it is up 1 but it has to be for canBlockSeeSky to work properly. - // TODO: Remove this requirement? - if(world.canBlockSeeSky(pos.up())){ + // Not sure why it is +1 but it has to be to work properly. + if(world.canBlockSeeTheSky(i, j+1, k)){ if(!world.isRemote){ - EntityLightningBolt entitylightning = new EntityLightningBolt(world, pos.getX(), pos.getY(), pos.getZ(), false); + EntityLightningBolt entitylightning = new EntityLightningBolt(world, i, j, k); world.addWeatherEffect(entitylightning); // Code for eventhandler recognition; for achievements and such like. Left in for future use. NBTTagCompound entityNBT = entitylightning.getEntityData(); - entityNBT.setUniqueId(NBT_KEY, caster.getUniqueID()); + entityNBT.setString("summoningPlayer", caster.getUniqueID().toString()); } - caster.swingArm(hand); + caster.swingItem(); return true; } } @@ -68,24 +58,23 @@ public class LightningBolt extends Spell { } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ - int x = (int)target.posX; - int y = (int)target.posY; - int z = (int)target.posZ; - - // Not sure why it is up 1 but it has to be for canBlockSeeSky to work properly. - // TODO: Remove this requirement? - if(world.canBlockSeeSky(new BlockPos(x, y, z))){ + int i = (int)target.posX; + int j = (int)target.posY; + int k = (int)target.posZ; + + // Not sure why it is +1 but it has to be to work properly. + if(world.canBlockSeeTheSky(i, j+1, k)){ if(!world.isRemote){ - EntityLightningBolt entitylightning = new EntityLightningBolt(world, x, y, z, false); + EntityLightningBolt entitylightning = new EntityLightningBolt(world, i, j, k); world.addWeatherEffect(entitylightning); } - caster.swingArm(hand); + caster.swingItem(); return true; } } @@ -97,22 +86,4 @@ public class LightningBolt extends Spell { public boolean canBeCastByNPCs(){ return true; } - - @SubscribeEvent - public static void onEntityStruckByLightningEvent(EntityStruckByLightningEvent event){ - - if(event.getLightning().getEntityData() != null && event.getLightning().getEntityData().hasKey(NBT_KEY)){ - - EntityPlayer player = (EntityPlayer)WizardryUtilities.getEntityByUUID(event.getLightning().worldObj, event.getLightning().getEntityData().getUniqueId("summoningPlayer")); - - if(event.getEntity() instanceof EntityCreeper){ - player.addStat(WizardryAchievements.charge_creeper); - } - - if(event.getEntity() instanceof EntityPig){ - player.addStat(WizardryAchievements.frankenstein); - } - } - - } } diff --git a/src/main/java/electroblob/wizardry/spell/LightningDisc.java b/src/main/java/electroblob/wizardry/spell/LightningDisc.java index fe0d5f18..99a9ed1e 100644 --- a/src/main/java/electroblob/wizardry/spell/LightningDisc.java +++ b/src/main/java/electroblob/wizardry/spell/LightningDisc.java @@ -1,23 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntityLightningDisc; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class LightningDisc extends Spell { public LightningDisc() { - super(Tier.ADVANCED, 25, Element.LIGHTNING, "lightning_disc", SpellType.ATTACK, 60, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 25, EnumElement.LIGHTNING, "lightning_disc", EnumSpellType.ATTACK, 60, EnumAction.none, false); } @Override @@ -26,31 +22,31 @@ public class LightningDisc extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntityLightningDisc lightningdisc = new EntityLightningDisc(world, caster, modifiers.get(SpellModifiers.DAMAGE)); + EntityLightningDisc lightningdisc = new EntityLightningDisc(world, caster, damageMultiplier); world.spawnEntityInWorld(lightningdisc); + world.playSoundAtEntity(caster, "wizardry:electricitya", 1.0F, world.rand.nextFloat() * 0.3F + 0.8F); } - - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1.0F, world.rand.nextFloat() * 0.3F + 0.8F); - caster.swingArm(hand); + + caster.swingItem(); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntityLightningDisc lightningdisc = new EntityLightningDisc(world, caster, modifiers.get(SpellModifiers.DAMAGE)); + EntityLightningDisc lightningdisc = new EntityLightningDisc(world, caster, damageMultiplier); lightningdisc.directTowards(target, 1.2f); world.spawnEntityInWorld(lightningdisc); + world.playSoundAtEntity(caster, "wizardry:electricitya", 1.0F, world.rand.nextFloat() * 0.3F + 0.8F); } - - caster.playSound(WizardrySounds.SPELL_LIGHTNING, 1.0F, world.rand.nextFloat() * 0.3F + 0.8F); - caster.swingArm(hand); + + caster.swingItem(); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/LightningHammer.java b/src/main/java/electroblob/wizardry/spell/LightningHammer.java index a7408c2e..dd165e75 100644 --- a/src/main/java/electroblob/wizardry/spell/LightningHammer.java +++ b/src/main/java/electroblob/wizardry/spell/LightningHammer.java @@ -1,24 +1,20 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.construct.EntityHammer; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class LightningHammer extends Spell { public LightningHammer() { - super(Tier.MASTER, 100, Element.LIGHTNING, "lightning_hammer", SpellType.ATTACK, 300, EnumAction.BOW, false); + super(EnumTier.MASTER, 100, EnumElement.LIGHTNING, "lightning_hammer", EnumSpellType.ATTACK, 300, EnumAction.bow, false); } @Override @@ -27,20 +23,22 @@ public class LightningHammer extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(40*modifiers.get(WizardryItems.range_upgrade), world, caster, false); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(40*rangeMultiplier, world, caster, false); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ - BlockPos pos = rayTrace.getBlockPos(); + int x = rayTrace.blockX; + int y = rayTrace.blockY; + int z = rayTrace.blockZ; // Not sure why it is +1 but it has to be to work properly. - if(world.canBlockSeeSky(pos.up())){ + if(world.canBlockSeeTheSky(x, y+1, z)){ if(!world.isRemote){ - EntityHammer hammer = new EntityHammer(world, pos.getX()+0.5, pos.getY()+50, pos.getZ()+0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), modifiers.get(SpellModifiers.DAMAGE)); + EntityHammer hammer = new EntityHammer(world, x+0.5, y + 50, z+0.5, caster, (int)(600*durationMultiplier), damageMultiplier); hammer.motionX = 0; hammer.motionY = -2; @@ -49,8 +47,8 @@ public class LightningHammer extends Spell { world.spawnEntityInWorld(hammer); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SUMMONING, 3.0f, 1.0f); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:darkaura", 3.0f, 1.0f); return true; } } diff --git a/src/main/java/electroblob/wizardry/spell/LightningPulse.java b/src/main/java/electroblob/wizardry/spell/LightningPulse.java index f180b10d..4226d008 100644 --- a/src/main/java/electroblob/wizardry/spell/LightningPulse.java +++ b/src/main/java/electroblob/wizardry/spell/LightningPulse.java @@ -2,29 +2,25 @@ package electroblob.wizardry.spell; import java.util.List; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.entity.construct.EntityLightningPulse; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.EnumAction; -import net.minecraft.network.play.server.SPacketEntityVelocity; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.MathHelper; +import net.minecraft.network.play.server.S12PacketEntityVelocity; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; public class LightningPulse extends Spell { public LightningPulse() { - super(Tier.ADVANCED, 25, Element.LIGHTNING, "lightning_pulse", SpellType.ATTACK, 75, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 25, EnumElement.LIGHTNING, "lightning_pulse", EnumSpellType.ATTACK, 75, EnumAction.none, false); } @Override @@ -33,16 +29,16 @@ public class LightningPulse extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(caster.onGround){ - List targets = WizardryUtilities.getEntitiesWithinRadius(3.0d*modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world); + List targets = WizardryUtilities.getEntitiesWithinRadius(3.0d*blastMultiplier, caster.posX, caster.posY, caster.posZ, world); for(EntityLivingBase target : targets){ if(WizardryUtilities.isValidTarget(caster, target)){ // Damage is 4 hearts no matter where the target is. - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 8 * modifiers.get(SpellModifiers.DAMAGE)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 8 * damageMultiplier); if(!world.isRemote){ @@ -59,18 +55,18 @@ public class LightningPulse extends Spell { // Player motion is handled on that player's client so needs packets if(target instanceof EntityPlayerMP){ - ((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target)); + ((EntityPlayerMP)target).playerNetServerHandler.sendPacket(new S12PacketEntityVelocity(target)); } } } } if(!world.isRemote){ - EntityLightningPulse lightningpulse = new EntityLightningPulse(world, caster.posX, caster.getEntityBoundingBox().minY, caster.posZ, caster, 7, modifiers.get(SpellModifiers.DAMAGE)); + EntityLightningPulse lightningpulse = new EntityLightningPulse(world, caster.posX, caster.boundingBox.minY, caster.posZ, caster, 7, damageMultiplier); world.spawnEntityInWorld(lightningpulse); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1.0f, 1.0f); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SHOCKWAVE, 2.0f, 1.0f); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:electricitya", 1.0f, 1.0f); + world.playSoundAtEntity(caster, "wizardry:boom", 2.0f, 1.0f); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/LightningRay.java b/src/main/java/electroblob/wizardry/spell/LightningRay.java index b956bd49..e93e766c 100644 --- a/src/main/java/electroblob/wizardry/spell/LightningRay.java +++ b/src/main/java/electroblob/wizardry/spell/LightningRay.java @@ -1,39 +1,38 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.entity.EntityArc; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.entity.living.EntityLightningWraith; +import electroblob.wizardry.entity.living.EntityStormElemental; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityCreeper; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class LightningRay extends Spell { public LightningRay() { - super(Tier.APPRENTICE, 5, Element.LIGHTNING, "lightning_ray", SpellType.ATTACK, 0, EnumAction.NONE, true); + super(EnumTier.APPRENTICE, 5, EnumElement.LIGHTNING, "lightning_ray", EnumSpellType.ATTACK, 0, EnumAction.none, true); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade), 2.0f); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier, 2.0f); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ Entity target = rayTrace.entityHit; if(!world.isRemote){ // This statement means the arc only spawns every other tick. @@ -51,25 +50,32 @@ public class LightningRay extends Spell { } if(MagicDamage.isEntityImmune(DamageType.SHOCK, target)){ - if(!world.isRemote && ticksInUse == 1) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", target.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote && ticksInUse == 1) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", target.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else{ - WizardryUtilities.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 3.0f * modifiers.get(SpellModifiers.DAMAGE)); + // This motion stuff removes knockback, which is desirable for continuous spells. + double motionX = target.motionX; + double motionY = target.motionY; + double motionZ = target.motionZ; + + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 3.0f * damageMultiplier); + + target.motionX = motionX; + target.motionY = motionY; + target.motionZ = motionZ; + } + + if(ticksInUse == 1){ + world.playSoundAtEntity(caster, "wizardry:electricitya", 1.0F, 1.0f); + }else if(ticksInUse > 0 && ticksInUse % 20 == 0){ + world.playSoundAtEntity(caster, "wizardry:electricityb", 1.0F, 1.0f); } }else{ for(int i=0;i<5;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, target.posX + world.rand.nextFloat() - 0.5, target.getEntityBoundingBox().minY + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, world, target.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(target) + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); } } - - if(ticksInUse == 1){ - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1.0F, 1.0f); - }else if(ticksInUse > 0 && ticksInUse % 20 == 0){ - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_LIGHTNING, 1.0F, 1.0f); - } - return true; - }else{ if(!world.isRemote){ // This statement means the arc only spawns every other tick. @@ -87,57 +93,14 @@ public class LightningRay extends Spell { } if(ticksInUse == 1){ - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1.0F, 1.0f); + world.playSoundAtEntity(caster, "wizardry:electricitya", 1.0F, 1.0f); }else if(ticksInUse > 0 && ticksInUse % 20 == 0){ - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_LIGHTNING, 1.0F, 1.0f); + world.playSoundAtEntity(caster, "wizardry:electricityb", 1.0F, 1.0f); } return true; } } - - @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ - - if(target != null){ - if(!world.isRemote){ - // This statement means the arc only spawns every other tick. - if(ticksInUse % 2 == 0){ - - EntityArc arc = new EntityArc(world); - // The look vec stuff performs a translation on the start point to line it up with the wand. - // EDIT: removed due to 1st/3rd person render differences. - arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ, - target.posX, target.posY + target.height/2, target.posZ); - - arc.lifetime = 1; - - world.spawnEntityInWorld(arc); - } - - WizardryUtilities.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 3.0f * modifiers.get(SpellModifiers.DAMAGE)); - - }else{ - for(int i=0;i<5;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, target.posX + world.rand.nextFloat() - 0.5, target.getEntityBoundingBox().minY + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); - } - } - - if(ticksInUse == 1){ - caster.playSound(WizardrySounds.SPELL_LIGHTNING, 1.0F, 1.0f); - }else if(ticksInUse > 0 && ticksInUse % 20 == 0){ - caster.playSound(WizardrySounds.SPELL_LOOP_LIGHTNING, 1.0F, 1.0f); - } - - return true; - } - - return false; - } - @Override - public boolean canBeCastByNPCs(){ - return true; - } } diff --git a/src/main/java/electroblob/wizardry/spell/LightningSigil.java b/src/main/java/electroblob/wizardry/spell/LightningSigil.java index 831a1189..a580342c 100644 --- a/src/main/java/electroblob/wizardry/spell/LightningSigil.java +++ b/src/main/java/electroblob/wizardry/spell/LightningSigil.java @@ -1,24 +1,20 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.construct.EntityLightningSigil; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class LightningSigil extends Spell { public LightningSigil() { - super(Tier.APPRENTICE, 10, Element.LIGHTNING, "lightning_sigil", SpellType.ATTACK, 20, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 10, EnumElement.LIGHTNING, "lightning_sigil", EnumSpellType.ATTACK, 20, EnumAction.none, false); } @Override @@ -27,22 +23,20 @@ public class LightningSigil extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(10*modifiers.get(WizardryItems.range_upgrade), world, caster, false); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(10*rangeMultiplier, world, caster, false); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK && rayTrace.sideHit == EnumFacing.UP){ - + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK && rayTrace.sideHit == 1){ if(!world.isRemote){ - double x = rayTrace.hitVec.xCoord; - double y = rayTrace.hitVec.yCoord; - double z = rayTrace.hitVec.zCoord; - EntityLightningSigil lightningsigil = new EntityLightningSigil(world, x, y, z, caster, modifiers.get(SpellModifiers.DAMAGE)); + double x = rayTrace.blockX; + double y = rayTrace.blockY; + double z = rayTrace.blockZ; + EntityLightningSigil lightningsigil = new EntityLightningSigil(world, x + 0.5, y+1, z + 0.5, caster, damageMultiplier); world.spawnEntityInWorld(lightningsigil); } - - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0F, 0.3F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:aura", 1.0F, 0.3F); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/LightningWeb.java b/src/main/java/electroblob/wizardry/spell/LightningWeb.java index 3b654be1..2df7764c 100644 --- a/src/main/java/electroblob/wizardry/spell/LightningWeb.java +++ b/src/main/java/electroblob/wizardry/spell/LightningWeb.java @@ -2,39 +2,39 @@ package electroblob.wizardry.spell; import java.util.List; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.entity.EntityArc; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.entity.living.EntityLightningWraith; +import electroblob.wizardry.entity.living.EntityStormElemental; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityCreeper; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class LightningWeb extends Spell { public LightningWeb() { - super(Tier.MASTER, 15, Element.LIGHTNING, "lightning_web", SpellType.ATTACK, 0, EnumAction.NONE, true); + super(EnumTier.MASTER, 15, EnumElement.LIGHTNING, "lightning_web", EnumSpellType.ATTACK, 0, EnumAction.none, true); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade), 2.0f); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier, 2.0f); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ Entity target = rayTrace.entityHit; @@ -48,26 +48,34 @@ public class LightningWeb extends Spell { arc.setEndpointCoords(caster.posX, caster.posY + 1.2, caster.posZ, target.posX, target.posY + target.height/2, target.posZ); arc.lifetime = 1; + arc.setOffset(caster.getLookVec().zCoord * 0.5, caster.getLookVec().xCoord * 0.5); world.spawnEntityInWorld(arc); } if(MagicDamage.isEntityImmune(DamageType.SHOCK, target)){ - if(!world.isRemote && ticksInUse == 1) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", target.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote && ticksInUse == 1) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", target.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else{ // This motion stuff removes knockback, which is desirable for continuous spells. double motionX = target.motionX; double motionY = target.motionY; double motionZ = target.motionZ; - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 5.0f * modifiers.get(SpellModifiers.DAMAGE)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 5.0f * damageMultiplier); target.motionX = motionX; target.motionY = motionY; target.motionZ = motionZ; } + + if(ticksInUse == 1){ + world.playSoundAtEntity(caster, "wizardry:electricitya", 1.0F, 1.0f); + }else if(ticksInUse > 0 && ticksInUse % 20 == 0){ + world.playSoundAtEntity(caster, "wizardry:electricityb", 1.0F, 1.0f); + } + }else{ for(int i=0;i<5;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, target.posX + world.rand.nextFloat() - 0.5, target.getEntityBoundingBox().minY + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, world, target.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(target) + target.height/2 + world.rand.nextFloat()*2 - 1, target.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); } } @@ -94,22 +102,29 @@ public class LightningWeb extends Spell { } if(MagicDamage.isEntityImmune(DamageType.SHOCK, secondaryTarget)){ - if(!world.isRemote && ticksInUse == 1) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", secondaryTarget.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote && ticksInUse == 1) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", secondaryTarget.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else{ // This motion stuff removes knockback, which is desirable for continuous spells. double motionX = secondaryTarget.motionX; double motionY = secondaryTarget.motionY; double motionZ = secondaryTarget.motionZ; - secondaryTarget.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 4.0f * modifiers.get(SpellModifiers.DAMAGE)); + secondaryTarget.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 4.0f * damageMultiplier); secondaryTarget.motionX = motionX; secondaryTarget.motionY = motionY; secondaryTarget.motionZ = motionZ; } + + if(ticksInUse == 1){ + world.playSoundAtEntity(caster, "wizardry:electricitya", 1.0F, 1.0f); + }else if(ticksInUse > 0 && ticksInUse % 20 == 0){ + world.playSoundAtEntity(caster, "wizardry:electricityb", 1.0F, 1.0f); + } + }else{ for(int i=0;i<5;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, secondaryTarget.posX + world.rand.nextFloat() - 0.5, secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height/2 + world.rand.nextFloat()*2 - 1, secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, world, secondaryTarget.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(secondaryTarget) + secondaryTarget.height/2 + world.rand.nextFloat()*2 - 1, secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); } } @@ -135,22 +150,29 @@ public class LightningWeb extends Spell { } if(MagicDamage.isEntityImmune(DamageType.SHOCK, tertiaryTarget)){ - if(!world.isRemote && ticksInUse == 1) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", tertiaryTarget.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote && ticksInUse == 1) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", tertiaryTarget.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else{ // This motion stuff removes knockback, which is desirable for continuous spells. double motionX = tertiaryTarget.motionX; double motionY = tertiaryTarget.motionY; double motionZ = tertiaryTarget.motionZ; - tertiaryTarget.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 3.0f * modifiers.get(SpellModifiers.DAMAGE)); + tertiaryTarget.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 3.0f * damageMultiplier); tertiaryTarget.motionX = motionX; tertiaryTarget.motionY = motionY; tertiaryTarget.motionZ = motionZ; } + + if(ticksInUse == 1){ + world.playSoundAtEntity(caster, "wizardry:electricitya", 1.0F, 1.0f); + }else if(ticksInUse > 0 && ticksInUse % 20 == 0){ + world.playSoundAtEntity(caster, "wizardry:electricityb", 1.0F, 1.0f); + } + }else{ for(int i=0;i<5;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, tertiaryTarget.posX + world.rand.nextFloat() - 0.5, tertiaryTarget.getEntityBoundingBox().minY + tertiaryTarget.height/2 + world.rand.nextFloat()*2 - 1, tertiaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, world, tertiaryTarget.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(tertiaryTarget) + tertiaryTarget.height/2 + world.rand.nextFloat()*2 - 1, tertiaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); } } } @@ -158,12 +180,6 @@ public class LightningWeb extends Spell { } } - if(ticksInUse == 1){ - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1.0F, 1.0f); - }else if(ticksInUse > 0 && ticksInUse % 20 == 0){ - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_LIGHTNING, 1.0F, 1.0f); - } - return true; }else{ @@ -180,9 +196,9 @@ public class LightningWeb extends Spell { } if(ticksInUse == 1){ - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LIGHTNING, 1.0F, 1.0f); + world.playSoundAtEntity(caster, "wizardry:electricitya", 1.0F, 1.0f); }else if(ticksInUse > 0 && ticksInUse % 20 == 0){ - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_LIGHTNING, 1.0F, 1.0f); + world.playSoundAtEntity(caster, "wizardry:electricityb", 1.0F, 1.0f); } return true; diff --git a/src/main/java/electroblob/wizardry/spell/MagicMissile.java b/src/main/java/electroblob/wizardry/spell/MagicMissile.java index 9cb083e3..d029276b 100644 --- a/src/main/java/electroblob/wizardry/spell/MagicMissile.java +++ b/src/main/java/electroblob/wizardry/spell/MagicMissile.java @@ -1,24 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntityMagicMissile; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class MagicMissile extends Spell { public MagicMissile() { - super(Tier.BASIC, 5, Element.MAGIC, "magic_missile", SpellType.ATTACK, 10, EnumAction.NONE, false); + super(EnumTier.BASIC, 5, EnumElement.MAGIC, "magic_missile", EnumSpellType.ATTACK, 10, EnumAction.none, false); } @Override @@ -27,31 +22,31 @@ public class MagicMissile extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntityMagicMissile magicMissile = new EntityMagicMissile(world, caster, 2*modifiers.get(WizardryItems.range_upgrade), modifiers.get(SpellModifiers.DAMAGE)); + EntityMagicMissile magicMissile = new EntityMagicMissile(world, caster, 2*rangeMultiplier, damageMultiplier); world.spawnEntityInWorld(magicMissile); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_MAGIC, 1.0F, world.rand.nextFloat() * 0.4F + 1.2F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:magic", 1.0F, world.rand.nextFloat() * 0.4F + 1.2F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntityMagicMissile magicMissile = new EntityMagicMissile(world, caster, target, 2*modifiers.get(WizardryItems.range_upgrade), 4, modifiers.get(SpellModifiers.DAMAGE)); + EntityMagicMissile magicMissile = new EntityMagicMissile(world, caster, target, 2*rangeMultiplier, 4, damageMultiplier); world.spawnEntityInWorld(magicMissile); } - caster.swingArm(hand); - caster.playSound(WizardrySounds.SPELL_MAGIC, 1.0F, world.rand.nextFloat() * 0.4F + 1.2F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:magic", 1.0F, world.rand.nextFloat() * 0.4F + 1.2F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Metamorphosis.java b/src/main/java/electroblob/wizardry/spell/Metamorphosis.java index abfceedc..69cf50ff 100644 --- a/src/main/java/electroblob/wizardry/spell/Metamorphosis.java +++ b/src/main/java/electroblob/wizardry/spell/Metamorphosis.java @@ -1,14 +1,11 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; @@ -18,31 +15,31 @@ import net.minecraft.entity.monster.EntityPigZombie; import net.minecraft.entity.monster.EntitySkeleton; import net.minecraft.entity.monster.EntitySlime; import net.minecraft.entity.monster.EntitySpider; -import net.minecraft.entity.monster.SkeletonType; +import net.minecraft.entity.monster.EntityWitch; import net.minecraft.entity.passive.EntityBat; import net.minecraft.entity.passive.EntityChicken; import net.minecraft.entity.passive.EntityCow; import net.minecraft.entity.passive.EntityMooshroom; import net.minecraft.entity.passive.EntityPig; +import net.minecraft.entity.passive.EntityVillager; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class Metamorphosis extends Spell { public Metamorphosis() { - super(Tier.APPRENTICE, 15, Element.NECROMANCY, "metamorphosis", SpellType.UTILITY, 30, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 15, EnumElement.NECROMANCY, "metamorphosis", EnumSpellType.UTILITY, 30, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - Vec3d look = caster.getLookVec(); + Vec3 look = caster.getLookVec(); - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier); if(rayTrace != null && rayTrace.entityHit != null && rayTrace.entityHit instanceof EntityLivingBase){ @@ -61,11 +58,10 @@ public class Metamorphosis extends Spell { newEntity = new EntityPig(world); } else if(entityHit instanceof EntitySkeleton){ - // IDEA: Interaction with husks/strays? - if(((EntitySkeleton)entityHit).getSkeletonType() == SkeletonType.NORMAL){ - ((EntitySkeleton)entityHit).setSkeletonType(SkeletonType.WITHER); + if(((EntitySkeleton)entityHit).getSkeletonType() == 0){ + ((EntitySkeleton)entityHit).setSkeletonType(1); }else{ - ((EntitySkeleton)entityHit).setSkeletonType(SkeletonType.NORMAL); + ((EntitySkeleton)entityHit).setSkeletonType(0); } flag = true; } @@ -107,21 +103,21 @@ public class Metamorphosis extends Spell { } if(world.isRemote){ - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ // I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet! double x1 = caster.posX + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; //world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.2f, 0.0f, 0.1f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.2f, 0.0f, 0.1f); } for(int i=0;i<5;i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, xPos, yPos, zPos, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, xPos, yPos, zPos, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_DEFLECTION, 0.5F, 0.8f); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:effect", 0.5F, 0.8f); return true; } } diff --git a/src/main/java/electroblob/wizardry/spell/Meteor.java b/src/main/java/electroblob/wizardry/spell/Meteor.java index af6c4aa3..2cf1cf8d 100644 --- a/src/main/java/electroblob/wizardry/spell/Meteor.java +++ b/src/main/java/electroblob/wizardry/spell/Meteor.java @@ -1,24 +1,21 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.EntityMeteor; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class Meteor extends Spell { public Meteor() { - super(Tier.MASTER, 100, Element.FIRE, "meteor", SpellType.ATTACK, 200, EnumAction.NONE, false); + super(EnumTier.MASTER, 100, EnumElement.FIRE, "meteor", EnumSpellType.ATTACK, 200, EnumAction.none, false); } @Override @@ -27,24 +24,26 @@ public class Meteor extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(40*modifiers.get(WizardryItems.range_upgrade), world, caster, false); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(40*rangeMultiplier, world, caster, false); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ - BlockPos pos = rayTrace.getBlockPos(); + int x = rayTrace.blockX; + int y = rayTrace.blockY; + int z = rayTrace.blockZ; // Not sure why it is +1 but it has to be to work properly. - if(world.canBlockSeeSky(pos.up())){ + if(world.canBlockSeeTheSky(x, y+1, z)){ if(!world.isRemote){ - EntityMeteor meteor = new EntityMeteor(world, pos.getX(), pos.getY() + 50, pos.getZ(), modifiers.get(WizardryItems.blast_upgrade)); + EntityMeteor meteor = new EntityMeteor(world, x, y + 50, z, Blocks.stone, blastMultiplier); world.spawnEntityInWorld(meteor); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SUMMONING, 3.0f, 1.0f); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:darkaura", 3.0f, 1.0f); return true; } } diff --git a/src/main/java/electroblob/wizardry/spell/MindControl.java b/src/main/java/electroblob/wizardry/spell/MindControl.java index 82e99605..dccb84a7 100644 --- a/src/main/java/electroblob/wizardry/spell/MindControl.java +++ b/src/main/java/electroblob/wizardry/spell/MindControl.java @@ -2,36 +2,28 @@ package electroblob.wizardry.spell; import java.util.List; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.entity.living.EntityEvilWizard; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.entity.living.EntityWizard; import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.INpc; import net.minecraft.entity.SharedMonsterAttributes; +import net.minecraft.entity.boss.IBossDisplayData; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; -import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent; -import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -@Mod.EventBusSubscriber public class MindControl extends Spell { /** The NBT tag name for storing the controlling entity's UUID in the target's tag compound. Defined here in case @@ -39,101 +31,102 @@ public class MindControl extends Spell { public static final String NBT_KEY = "controllingEntity"; public MindControl() { - super(Tier.ADVANCED, 40, Element.NECROMANCY, "mind_control", SpellType.ATTACK, 150, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 40, EnumElement.NECROMANCY, "mind_control", EnumSpellType.ATTACK, 150, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 8*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 8*rangeMultiplier); if(rayTrace != null && rayTrace.entityHit != null && rayTrace.entityHit instanceof EntityLivingBase){ - EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit; + Entity target = rayTrace.entityHit; if(!world.isRemote){ - if(!canControl(target)){ + if(target instanceof EntityPlayer || target instanceof IBossDisplayData || target instanceof INpc){ // Adds a message saying that the player/boss entity/wizard resisted mind control - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", target.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", target.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else if(target instanceof EntityLiving){ if(!MindControl.findMindControlTarget((EntityLiving)target, caster, world)){ // If no valid target was found, this just acts like mind trick. + // New AI ((EntityLiving)target).setAttackTarget(null); + // Old AI + if(target instanceof EntityCreature) ((EntityCreature)target).setTarget(null); } NBTTagCompound entityNBT = target.getEntityData(); - if(entityNBT != null) entityNBT.setUniqueId(NBT_KEY, caster.getUniqueID()); + if(entityNBT != null) entityNBT.setString(NBT_KEY, caster.getUniqueID().toString()); - ((EntityLiving)target).addPotionEffect(new PotionEffect(WizardryPotions.mind_control, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 0)); + ((EntityLiving)target).addPotionEffect(new PotionEffect(Wizardry.mindControl.id, (int)(600*durationMultiplier), 0)); } }else{ for(int i=0; i<10; i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, target.posX - 0.25 + world.rand.nextDouble()*0.5, - target.getEntityBoundingBox().minY + target.getEyeHeight() - 0.25 + world.rand.nextDouble()*0.5, + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, target.posX - 0.25 + world.rand.nextDouble()*0.5, + WizardryUtilities.getEntityFeetPos(target) + target.getEyeHeight() - 0.25 + world.rand.nextDouble()*0.5, target.posZ - 0.25 + world.rand.nextDouble()*0.5, 0, 0, 0, 0, 0.8f, 0.2f, 1.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, target.posX - 0.25 + world.rand.nextDouble()*0.5, - target.getEntityBoundingBox().minY + target.getEyeHeight() - 0.25 + world.rand.nextDouble()*0.5, + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, target.posX - 0.25 + world.rand.nextDouble()*0.5, + WizardryUtilities.getEntityFeetPos(target) + target.getEyeHeight() - 0.25 + world.rand.nextDouble()*0.5, target.posZ - 0.25 + world.rand.nextDouble()*0.5, 0, 0, 0, 0, 0.2f, 0.04f, 0.25f); } } - target.playSound(WizardrySounds.SPELL_SUMMONING, 1.0f, 1.0f); - caster.swingArm(hand); + world.playSoundAtEntity(target, "wizardry:darkaura", 1.0f, 1.0f); + caster.swingItem(); return true; } return false; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers) { + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(target != null){ if(!world.isRemote){ - if(canControl(target)){ + if(target instanceof EntityLiving && !(target instanceof IBossDisplayData) + && !(target instanceof EntityWizard)){ if(!MindControl.findMindControlTarget((EntityLiving)target, caster, world)){ // If no valid target was found, this just acts like mind trick. + // New AI ((EntityLiving)target).setAttackTarget(null); + // Old AI + if(target instanceof EntityCreature) ((EntityCreature)target).setTarget(null); } NBTTagCompound entityNBT = target.getEntityData(); - if(entityNBT != null) entityNBT.setUniqueId(NBT_KEY, caster.getUniqueID()); + if(entityNBT != null) entityNBT.setString(NBT_KEY, caster.getUniqueID().toString()); - ((EntityLiving)target).addPotionEffect(new PotionEffect(WizardryPotions.mind_control, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 0)); + ((EntityLiving)target).addPotionEffect(new PotionEffect(Wizardry.mindControl.id, (int)(600*durationMultiplier), 0)); } }else{ for(int i=0; i<10; i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, target.posX - 0.25 + world.rand.nextDouble()*0.5, - target.getEntityBoundingBox().minY + target.getEyeHeight() - 0.25 + world.rand.nextDouble()*0.5, + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, target.posX - 0.25 + world.rand.nextDouble()*0.5, + WizardryUtilities.getEntityFeetPos(target) + target.getEyeHeight() - 0.25 + world.rand.nextDouble()*0.5, target.posZ - 0.25 + world.rand.nextDouble()*0.5, 0, 0, 0, 0, 0.8f, 0.2f, 1.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, target.posX - 0.25 + world.rand.nextDouble()*0.5, - target.getEntityBoundingBox().minY + target.getEyeHeight() - 0.25 + world.rand.nextDouble()*0.5, + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, target.posX - 0.25 + world.rand.nextDouble()*0.5, + WizardryUtilities.getEntityFeetPos(target) + target.getEyeHeight() - 0.25 + world.rand.nextDouble()*0.5, target.posZ - 0.25 + world.rand.nextDouble()*0.5, 0, 0, 0, 0, 0.2f, 0.04f, 0.25f); } } - target.playSound(WizardrySounds.SPELL_SUMMONING, 1.0f, 1.0f); - caster.swingArm(hand); + world.playSoundAtEntity(target, "wizardry:darkaura", 1.0f, 1.0f); + caster.swingItem(); return true; } return false; } - + @Override public boolean canBeCastByNPCs(){ return true; } - /** Returns true if the given entity can be mind controlled (i.e. is not a player, npc, evil wizard or boss). */ - public static boolean canControl(EntityLivingBase target){ - return target instanceof EntityLiving && target.isNonBoss() && !(target instanceof INpc) - && !(target instanceof EntityEvilWizard); - } - /** * Finds the nearest creature to the given target which it is allowed to attack according to the given caster * and sets it as the target's attack target. Handles both new and old AI and takes follow range into account. @@ -149,7 +142,7 @@ public class MindControl extends Spell { // no longer lasts until the creature dies; instead it is a potion effect which continues to // set the target until it wears off. List possibleTargets = WizardryUtilities.getEntitiesWithinRadius( - ((EntityLiving)target).getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE).getAttributeValue(), + ((EntityLiving)target).getEntityAttribute(SharedMonsterAttributes.followRange).getAttributeValue(), target.posX, target.posY, target.posZ, world); possibleTargets.remove(target); @@ -164,7 +157,9 @@ public class MindControl extends Spell { } if(newAITarget != null){ - // From 1.7.10 - this seems not to work quite right; the entity appears to continue attacking this target + // Old AI + if(target instanceof EntityCreature) ((EntityCreature)target).setTarget(newAITarget); + // New AI - this seems not to work quite right; the entity appears to continue attacking this target // after it gets killed (not noticeable in survival since it will target the player again immediately.) ((EntityLiving)target).setAttackTarget(newAITarget); @@ -175,43 +170,5 @@ public class MindControl extends Spell { } - @SubscribeEvent - public static void onLivingUpdateEvent(LivingUpdateEvent event){ - // This was added because something got changed in the AI classes which means LivingSetAttackTargetEvent doesn't - // get fired when I want it to... so I'm firing it myself. - if(event.getEntityLiving().isPotionActive(WizardryPotions.mind_control) && event.getEntityLiving() instanceof EntityLiving - && ((EntityLiving)event.getEntityLiving()).getAttackTarget() != null - && !((EntityLiving)event.getEntityLiving()).getAttackTarget().isEntityAlive()) - ((EntityLiving)event.getEntityLiving()).setAttackTarget(null); // Causes the event to be fired - } - @SubscribeEvent - public static void onLivingSetAttackTargetEvent(LivingSetAttackTargetEvent event){ - - if(event.getTarget() == null) return; // Prevents infinite loops with mind trick - - if(event.getEntityLiving().isPotionActive(WizardryPotions.mind_control) && MindControl.canControl(event.getEntityLiving())){ - - NBTTagCompound entityNBT = event.getEntityLiving().getEntityData(); - - if(entityNBT != null && entityNBT.hasKey(MindControl.NBT_KEY + "Most")){ - - Entity caster = WizardryUtilities.getEntityByUUID(event.getEntity().worldObj, entityNBT.getUniqueId(MindControl.NBT_KEY)); - - // If the target that the event tried to set is already a valid mind control target, nothing happens. - if(WizardryUtilities.isValidTarget(caster, event.getTarget())) return; - - if(caster instanceof EntityLivingBase){ - - if(MindControl.findMindControlTarget((EntityLiving)event.getEntityLiving(), (EntityLivingBase)caster, event.getEntity().worldObj)){ - // If it worked, skip setting the target to null. - return; - } - } - } - // If the caster couldn't be found or no valid target was found, this just acts like mind trick. - ((EntityLiving)event.getEntityLiving()).setAttackTarget(null); - } - } - -} \ No newline at end of file +} diff --git a/src/main/java/electroblob/wizardry/spell/MindTrick.java b/src/main/java/electroblob/wizardry/spell/MindTrick.java index d9cab649..2edd394d 100644 --- a/src/main/java/electroblob/wizardry/spell/MindTrick.java +++ b/src/main/java/electroblob/wizardry/spell/MindTrick.java @@ -1,127 +1,94 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import net.minecraft.entity.EntityCreature; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; -import net.minecraftforge.event.entity.living.LivingAttackEvent; -import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -@Mod.EventBusSubscriber public class MindTrick extends Spell { public MindTrick() { - super(Tier.BASIC, 10, Element.NECROMANCY, "mind_trick", SpellType.ATTACK, 40, EnumAction.NONE, false); + super(EnumTier.BASIC, 10, EnumElement.NECROMANCY, "mind_trick", EnumSpellType.ATTACK, 40, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 8*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 8*rangeMultiplier); if(rayTrace != null && rayTrace.entityHit != null && rayTrace.entityHit instanceof EntityLivingBase){ EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit; if(!world.isRemote){ - if(target instanceof EntityPlayer){ - - target.addPotionEffect(new PotionEffect(MobEffects.NAUSEA, (int)(300*modifiers.get(WizardryItems.duration_upgrade)), 0)); - + target.addPotionEffect(new PotionEffect(Potion.confusion.id, (int)(300*durationMultiplier), 0)); }else if(target instanceof EntityLiving){ - + // New AI ((EntityLiving)target).setAttackTarget(null); - target.addPotionEffect(new PotionEffect(WizardryPotions.mind_trick, (int)(300*modifiers.get(WizardryItems.duration_upgrade)), 0)); + // Old AI + if(target instanceof EntityCreature) ((EntityCreature)target).setTarget(null); + + target.addPotionEffect(new PotionEffect(Wizardry.mindTrick.id, (int)(300*durationMultiplier), 0)); } }else{ for(int i=0; i<10; i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, target.posX - 0.25 + world.rand.nextDouble()*0.5, - target.getEntityBoundingBox().minY + target.getEyeHeight() - 0.25 + world.rand.nextDouble()*0.5, + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, target.posX - 0.25 + world.rand.nextDouble()*0.5, + WizardryUtilities.getEntityFeetPos(target) + target.getEyeHeight() - 0.25 + world.rand.nextDouble()*0.5, target.posZ - 0.25 + world.rand.nextDouble()*0.5, 0, 0, 0, 0, 0.8f, 0.2f, 1.0f); } } - - target.playSound(WizardrySounds.SPELL_DEFLECTION, 0.7F, world.rand.nextFloat() * 0.4F + 0.8F); - caster.swingArm(hand); + world.playSoundAtEntity(target, "wizardry:effect", 0.7F, world.rand.nextFloat() * 0.4F + 0.8F); + caster.swingItem(); return true; } return false; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers) { + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(target != null){ if(!world.isRemote){ if(target instanceof EntityPlayer){ - - target.addPotionEffect(new PotionEffect(MobEffects.NAUSEA, (int)(300*modifiers.get(WizardryItems.duration_upgrade)), 0)); - + target.addPotionEffect(new PotionEffect(Potion.confusion.id, (int)(300*durationMultiplier), 0)); }else if(target instanceof EntityLiving){ - + // New AI ((EntityLiving)target).setAttackTarget(null); - target.addPotionEffect(new PotionEffect(WizardryPotions.mind_trick, (int)(300*modifiers.get(WizardryItems.duration_upgrade)), 0)); + // Old AI + if(target instanceof EntityCreature) ((EntityCreature)target).setTarget(null); + target.addPotionEffect(new PotionEffect(Wizardry.mindTrick.id, (int)(300*durationMultiplier), 0)); } }else{ for(int i=0; i<10; i++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, target.posX - 0.25 + world.rand.nextDouble()*0.5, - target.getEntityBoundingBox().minY + target.getEyeHeight() - 0.25 + world.rand.nextDouble()*0.5, + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, target.posX - 0.25 + world.rand.nextDouble()*0.5, + WizardryUtilities.getEntityFeetPos(target) + target.getEyeHeight() - 0.25 + world.rand.nextDouble()*0.5, target.posZ - 0.25 + world.rand.nextDouble()*0.5, 0, 0, 0, 0, 0.8f, 0.2f, 1.0f); } } - - target.playSound(WizardrySounds.SPELL_DEFLECTION, 0.7F, world.rand.nextFloat() * 0.4F + 0.8F); - caster.swingArm(hand); + world.playSoundAtEntity(target, "wizardry:effect", 0.7F, world.rand.nextFloat() * 0.4F + 0.8F); + caster.swingItem(); return true; } return false; } - + @Override public boolean canBeCastByNPCs() { return true; } - - @SubscribeEvent - public static void onLivingAttackEvent(LivingAttackEvent event){ - if(event.getSource() != null && event.getSource().getEntity() instanceof EntityLivingBase){ - // Cancels the mind trick effect if the creature takes damage - // This has been moved to within an (event.getSource().getEntity() instanceof EntityLivingBase) check so it doesn't - // crash the game with a ConcurrentModificationException. If you think about it, mind trick only ought to be - // cancelled if something attacks the entity since potions, drowning, cacti etc. don't affect the targeting. - if(event.getEntityLiving().isPotionActive(WizardryPotions.mind_trick)){ - event.getEntityLiving().removePotionEffect(WizardryPotions.mind_trick); - } - } - } - - @SubscribeEvent - public static void onLivingSetAttackTargetEvent(LivingSetAttackTargetEvent event){ - // Mind trick - // If the target is null already, no need to set it to null, or infinite loops will occur. - if((event.getEntityLiving().isPotionActive(WizardryPotions.mind_trick) || event.getEntityLiving().isPotionActive(WizardryPotions.fear)) && event.getEntityLiving() instanceof EntityLiving && event.getTarget() != null){ - ((EntityLiving)event.getEntityLiving()).setAttackTarget(null); - } - } } diff --git a/src/main/java/electroblob/wizardry/spell/None.java b/src/main/java/electroblob/wizardry/spell/None.java index 12566e04..e0978188 100644 --- a/src/main/java/electroblob/wizardry/spell/None.java +++ b/src/main/java/electroblob/wizardry/spell/None.java @@ -1,21 +1,18 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.util.SpellModifiers; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; /** This class represents a blank spell used to fill empty slots on wands. It is unobtainable in-game, except via - * commands, and does nothing when the player attempts to cast it. Its instance can be referenced directly using - * {@link electroblob.wizardry.registry.Spells#none WizardryRegistry.none}*/ + * commands, and does nothing when the player attempts to cast it. */ public class None extends Spell { public None() { - super(Tier.BASIC, 0, Element.MAGIC, "none", SpellType.UTILITY, 0, EnumAction.NONE, false); + super(EnumTier.BASIC, 0, EnumElement.MAGIC, "none", EnumSpellType.UTILITY, 0, EnumAction.none, false); } @Override @@ -24,7 +21,7 @@ public class None extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { return false; } diff --git a/src/main/java/electroblob/wizardry/spell/Oakflesh.java b/src/main/java/electroblob/wizardry/spell/Oakflesh.java index cb2f5fd6..53eec40b 100644 --- a/src/main/java/electroblob/wizardry/spell/Oakflesh.java +++ b/src/main/java/electroblob/wizardry/spell/Oakflesh.java @@ -1,64 +1,60 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class Oakflesh extends Spell { public Oakflesh() { - super(Tier.APPRENTICE, 20, Element.HEALING, "oakflesh", SpellType.DEFENCE, 50, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 20, EnumElement.HEALING, "oakflesh", EnumSpellType.DEFENCE, 50, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - caster.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 1, false, false)); + caster.addPotionEffect(new PotionEffect(Potion.resistance.id, (int)(600*durationMultiplier), 1, true)); if(world.isRemote){ for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.6f, 0.5f, 0.4f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.6f, 0.5f, 0.4f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ - if(!caster.isPotionActive(MobEffects.RESISTANCE)){ + if(!caster.isPotionActive(Potion.resistance)){ - caster.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 1, false, false)); + caster.addPotionEffect(new PotionEffect(Potion.resistance.id, (int)(600*durationMultiplier), 1, true)); if(world.isRemote){ for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)caster.posY + caster.getEyeHeight() - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.6f, 0.5f, 0.4f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.6f, 0.5f, 0.4f); } } - caster.playSound(WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Petrify.java b/src/main/java/electroblob/wizardry/spell/Petrify.java index 4dd4cf24..694896f1 100644 --- a/src/main/java/electroblob/wizardry/spell/Petrify.java +++ b/src/main/java/electroblob/wizardry/spell/Petrify.java @@ -1,112 +1,101 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryBlocks; -import electroblob.wizardry.registry.WizardryItems; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.tileentity.TileEntityStatue; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class Petrify extends Spell { private static final int baseDuration = 900; - - /** The NBT tag name for storing the petrified flag in the target's tag compound. Defined here in case it changes. */ - public static final String NBT_KEY = "petrified"; public Petrify() { - super(Tier.ADVANCED, 40, Element.SORCERY, "petrify", SpellType.ATTACK, 100, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 40, EnumElement.SORCERY, "petrify", EnumSpellType.ATTACK, 100, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - Vec3d look = caster.getLookVec(); + Vec3 look = caster.getLookVec(); - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLiving && !world.isRemote){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLiving && !world.isRemote){ - EntityLiving target = (EntityLiving) rayTrace.entityHit; - - if(target.deathTime > 0) return false; + EntityLiving entity = (EntityLiving) rayTrace.entityHit; - BlockPos pos = new BlockPos(target); + int x = (int)Math.floor(entity.posX); + int y = (int)Math.floor(entity.posY); + int z = (int)Math.floor(entity.posZ); - target.extinguish(); + entity.extinguish(); //Short mobs such as spiders and pigs - if((target.height < 1.2 || target.isChild()) && WizardryUtilities.canBlockBeReplaced(world, pos)){ - world.setBlockState(pos, WizardryBlocks.petrified_stone.getDefaultState()); - if(world.getTileEntity(pos) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart(target, 1, 1); - ((TileEntityStatue)world.getTileEntity(pos)).setLifetime((int)(baseDuration*modifiers.get(WizardryItems.duration_upgrade))); + if((entity.height < 1.2 || entity.isChild()) && WizardryUtilities.canBlockBeReplaced(world, x, y, z)){ + world.setBlock(x, y, z, Wizardry.petrifiedStone); + if(world.getTileEntity(x, y, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y, z)).setCreatureAndPart(entity, 1, 1); + ((TileEntityStatue)world.getTileEntity(x, y, z)).setLifetime((int)(baseDuration*durationMultiplier)); } - target.getEntityData().setBoolean(NBT_KEY, true); - target.setDead(); + entity.setDead(); } //Normal sized mobs like zombies and skeletons - else if(target.height < 2.5 && WizardryUtilities.canBlockBeReplaced(world, pos) && WizardryUtilities.canBlockBeReplaced(world, pos.up())){ - world.setBlockState(pos, WizardryBlocks.petrified_stone.getDefaultState()); - if(world.getTileEntity(pos) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart(target, 1, 2); - ((TileEntityStatue)world.getTileEntity(pos)).setLifetime((int)(baseDuration*modifiers.get(WizardryItems.duration_upgrade))); + else if(entity.height < 2.5 && WizardryUtilities.canBlockBeReplaced(world, x, y, z) && WizardryUtilities.canBlockBeReplaced(world, x, y+1, z)){ + world.setBlock(x, y, z, Wizardry.petrifiedStone); + if(world.getTileEntity(x, y, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y, z)).setCreatureAndPart(entity, 1, 2); + ((TileEntityStatue)world.getTileEntity(x, y, z)).setLifetime((int)(baseDuration*durationMultiplier)); } - world.setBlockState(pos.up(), WizardryBlocks.petrified_stone.getDefaultState()); - if(world.getTileEntity(pos.up()) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos.up())).setCreatureAndPart(target, 2, 2); + world.setBlock(x, y+1, z, Wizardry.petrifiedStone); + if(world.getTileEntity(x, y+1, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y+1, z)).setCreatureAndPart(entity, 2, 2); } - target.getEntityData().setBoolean(NBT_KEY, true); - target.setDead(); + entity.setDead(); } //Tall mobs like endermen - else if(WizardryUtilities.canBlockBeReplaced(world, pos) && WizardryUtilities.canBlockBeReplaced(world, pos.up()) && WizardryUtilities.canBlockBeReplaced(world, pos.up(2))){ - world.setBlockState(pos, WizardryBlocks.petrified_stone.getDefaultState()); - if(world.getTileEntity(pos) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos)).setCreatureAndPart(target, 1, 3); - ((TileEntityStatue)world.getTileEntity(pos)).setLifetime((int)(baseDuration*modifiers.get(WizardryItems.duration_upgrade))); + else if(WizardryUtilities.canBlockBeReplaced(world, x, y, z) && WizardryUtilities.canBlockBeReplaced(world, x, y+1, z) && WizardryUtilities.canBlockBeReplaced(world, x, y+2, z)){ + world.setBlock(x, y, z, Wizardry.petrifiedStone); + if(world.getTileEntity(x, y, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y, z)).setCreatureAndPart(entity, 1, 3); + ((TileEntityStatue)world.getTileEntity(x, y, z)).setLifetime((int)(baseDuration*durationMultiplier)); } - world.setBlockState(pos.up(), WizardryBlocks.petrified_stone.getDefaultState()); - if(world.getTileEntity(pos.up()) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos.up())).setCreatureAndPart(target, 2, 3); + world.setBlock(x, y+1, z, Wizardry.petrifiedStone); + if(world.getTileEntity(x, y+1, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y+1, z)).setCreatureAndPart(entity, 2, 3); } - world.setBlockState(pos.up(2), WizardryBlocks.petrified_stone.getDefaultState()); - if(world.getTileEntity(pos.up(2)) instanceof TileEntityStatue){ - ((TileEntityStatue)world.getTileEntity(pos.up(2))).setCreatureAndPart(target, 3, 3); + world.setBlock(x, y+2, z, Wizardry.petrifiedStone); + if(world.getTileEntity(x, y+2, z) instanceof TileEntityStatue){ + ((TileEntityStatue)world.getTileEntity(x, y+2, z)).setCreatureAndPart(entity, 3, 3); } - target.getEntityData().setBoolean(NBT_KEY, true); - target.setDead(); + entity.setDead(); } } if(world.isRemote){ - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ // I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet! double x1 = caster.posX + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; //world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.1f, 0.1f); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.2f, 0.2f, 0.2f); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.1f, 0.1f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.2f, 0.2f, 0.2f); } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SPAWN, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "mob.wither.spawn", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/PhaseStep.java b/src/main/java/electroblob/wizardry/spell/PhaseStep.java index a99034ce..1c1e3c83 100644 --- a/src/main/java/electroblob/wizardry/spell/PhaseStep.java +++ b/src/main/java/electroblob/wizardry/spell/PhaseStep.java @@ -1,64 +1,119 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Constants; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class PhaseStep extends Spell { public PhaseStep() { - super(Tier.ADVANCED, 35, Element.SORCERY, "phase_step", SpellType.UTILITY, 40, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 35, EnumElement.SORCERY, "phase_step", EnumSpellType.UTILITY, 40, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { // Phase step does not gain range from range multiplier, instead it increases the thickness // of the wall you can teleport through. - RayTraceResult rayTrace = WizardryUtilities.rayTrace(5, world, caster, false); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(5, world, caster, false); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ - BlockPos pos = new BlockPos(rayTrace.getBlockPos().getX(), (int)caster.posY, rayTrace.getBlockPos().getZ()); + int blockHitX = rayTrace.blockX; + int blockHitY = rayTrace.blockY; + int blockHitZ = rayTrace.blockZ; + int blockHitSide = rayTrace.sideHit; + + int playerY = (int)caster.posY; // The maximum wall thickness as determined by the range multiplier. The + 0.5f is so that // weird float processing doesn't incorrectly round it down. - int maxThickness = 1 + (int)((modifiers.get(WizardryItems.range_upgrade) - 1)/Constants.RANGE_INCREASE_PER_LEVEL + 0.5f); - - if(rayTrace.sideHit.getAxis().isHorizontal()){ + int maxThickness = 1 + (int)((rangeMultiplier - 1)/Wizardry.RANGE_INCREASE_PER_LEVEL + 0.5f); - // i represents how far the player needs to teleport to get through the wall - for(int i = 0; i <= maxThickness; i++){ - - BlockPos pos1 = pos.offset(rayTrace.sideHit.getOpposite(), i); - - // Prevents the player from teleporting through unbreakable blocks, so they cannot cheat in other mods' mazes and dungeons. - if((WizardryUtilities.isBlockUnbreakable(world, pos1) || WizardryUtilities.isBlockUnbreakable(world, pos1.up())) && !Wizardry.settings.teleportThroughUnbreakableBlocks) return false; + // How far the player needs to teleport to get through the wall + int teleportDistance = 0; - if(!world.getBlockState(pos1).getMaterial().blocksMovement() && !world.getBlockState(pos1.up()).getMaterial().blocksMovement()){ - - if(!world.isRemote){ - caster.setPositionAndUpdate(pos1.getX() + 0.5, caster.posY, pos1.getZ() + 0.5); + // The following prevents the player from teleporting into blocks and suffocating + checkforspace: + switch(blockHitSide){ + case -1: + return false; + case 0: + return false; + case 1: + return false; + case 2: + for(int i = 0; i <= maxThickness; i++){ + // Prevents the player from teleporting through unbreakable blocks, so they cannot cheat in other mods' mazes and dungeons. + if((WizardryUtilities.isBlockUnbreakable(world, blockHitX, playerY, blockHitZ + i) || WizardryUtilities.isBlockUnbreakable(world, blockHitX, playerY + 1, blockHitZ + i)) && !Wizardry.teleportThroughUnbreakableBlocks) return false; + + if(!world.getBlock(blockHitX, playerY, blockHitZ + i).getMaterial().blocksMovement() && !world.getBlock(blockHitX, playerY + 1, blockHitZ + i).getMaterial().blocksMovement()){ + teleportDistance = i; + break checkforspace; } - - caster.swingArm(hand); - return true; } + return false; + case 3: + for(int i = 0; i <= maxThickness; i++){ + // Prevents the player from teleporting through unbreakable blocks, so they cannot cheat in other mods' mazes and dungeons. + if((WizardryUtilities.isBlockUnbreakable(world, blockHitX, playerY, blockHitZ - i) || WizardryUtilities.isBlockUnbreakable(world, blockHitX, playerY + 1, blockHitZ - i)) && !Wizardry.teleportThroughUnbreakableBlocks) return false; + + if(!world.getBlock(blockHitX, playerY, blockHitZ - i).getMaterial().blocksMovement() && !world.getBlock(blockHitX, playerY + 1, blockHitZ - i).getMaterial().blocksMovement()){ + teleportDistance = i; + break checkforspace; + } + } + return false; + case 4: + for(int i = 0; i <= maxThickness; i++){ + // Prevents the player from teleporting through unbreakable blocks, so they cannot cheat in other mods' mazes and dungeons. + if((WizardryUtilities.isBlockUnbreakable(world, blockHitX + i, playerY, blockHitZ) || WizardryUtilities.isBlockUnbreakable(world, blockHitX + i, playerY + 1, blockHitZ)) && !Wizardry.teleportThroughUnbreakableBlocks) return false; + + if(!world.getBlock(blockHitX + i, playerY, blockHitZ).getMaterial().blocksMovement() && !world.getBlock(blockHitX + i, playerY + 1, blockHitZ).getMaterial().blocksMovement()){ + teleportDistance = i; + break checkforspace; + } + } + return false; + case 5: + for(int i = 0; i <= maxThickness; i++){ + // Prevents the player from teleporting through unbreakable blocks, so they cannot cheat in other mods' mazes and dungeons. + if((WizardryUtilities.isBlockUnbreakable(world, blockHitX - i, playerY, blockHitZ) || WizardryUtilities.isBlockUnbreakable(world, blockHitX - i, playerY + 1, blockHitZ)) && !Wizardry.teleportThroughUnbreakableBlocks) return false; + + if(!world.getBlock(blockHitX - i, playerY, blockHitZ).getMaterial().blocksMovement() && !world.getBlock(blockHitX - i, playerY + 1, blockHitZ).getMaterial().blocksMovement()){ + teleportDistance = i; + break checkforspace; + } + } + return false; + } + + if(!world.isRemote){ + switch(blockHitSide){ + case 2: + caster.setPositionAndUpdate(blockHitX + 0.5, caster.posY, blockHitZ + 0.5 + teleportDistance); + break; + case 3: + caster.setPositionAndUpdate(blockHitX + 0.5, caster.posY, blockHitZ + 0.5 - teleportDistance); + break; + case 4: + caster.setPositionAndUpdate(blockHitX + 0.5 + teleportDistance, caster.posY, blockHitZ + 0.5); + break; + case 5: + caster.setPositionAndUpdate(blockHitX + 0.5 - teleportDistance, caster.posY, blockHitZ + 0.5); + break; } } + world.playSoundAtEntity(caster, "mob.endermen.portal", 1.0F, 1.0f); + caster.swingItem(); + return true; } // This is here because the conditions are false on the client for whatever reason. (see the Javadoc for cast() @@ -68,9 +123,8 @@ public class PhaseStep extends Spell { double dx1 = caster.posX; double dy1 = WizardryUtilities.getPlayerEyesPos(caster) - 1.5 + 2*world.rand.nextFloat(); double dz1 = caster.posZ; - world.spawnParticle(EnumParticleTypes.PORTAL, dx1, dy1, dz1, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5); + world.spawnParticle("portal", dx1, dy1, dz1, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5); } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_ENDERMEN_TELEPORT, 1.0F, 1.0f); } return false; diff --git a/src/main/java/electroblob/wizardry/spell/PlagueOfDarkness.java b/src/main/java/electroblob/wizardry/spell/PlagueOfDarkness.java index 252868a7..695e86f6 100644 --- a/src/main/java/electroblob/wizardry/spell/PlagueOfDarkness.java +++ b/src/main/java/electroblob/wizardry/spell/PlagueOfDarkness.java @@ -2,69 +2,63 @@ package electroblob.wizardry.spell; import java.util.List; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.block.Block; -import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; import net.minecraft.world.World; public class PlagueOfDarkness extends Spell { public PlagueOfDarkness() { - super(Tier.MASTER, 75, Element.NECROMANCY, "plague_of_darkness", SpellType.ATTACK, 200, EnumAction.BOW, false); + super(EnumTier.MASTER, 75, EnumElement.NECROMANCY, "plague_of_darkness", EnumSpellType.ATTACK, 200, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - List targets = WizardryUtilities.getEntitiesWithinRadius(5.0d*modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world); + List targets = WizardryUtilities.getEntitiesWithinRadius(5.0d*blastMultiplier, caster.posX, caster.posY, caster.posZ, world); for(EntityLivingBase target : targets){ if(WizardryUtilities.isValidTarget(caster, target) && !MagicDamage.isEntityImmune(DamageType.WITHER, target)){ - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.WITHER), 8.0f * modifiers.get(SpellModifiers.DAMAGE)); - target.addPotionEffect(new PotionEffect(MobEffects.WITHER, (int)(140*modifiers.get(WizardryItems.duration_upgrade)), 2)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.WITHER), 8.0f * damageMultiplier); + target.addPotionEffect(new PotionEffect(Potion.wither.id, (int)(140*durationMultiplier), 2)); } } if(world.isRemote){ double particleX, particleZ; - for(int i=0;i<40*modifiers.get(WizardryItems.blast_upgrade);i++){ + for(int i=0;i<40*blastMultiplier;i++){ particleX = caster.posX - 1.0d + 2*world.rand.nextDouble(); particleZ = caster.posZ - 1.0d + 2*world.rand.nextDouble(); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, particleX, WizardryUtilities.getPlayerEyesPos(caster) - 1.5, particleZ, + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, particleX, WizardryUtilities.getPlayerEyesPos(caster) - 1.5, particleZ, particleX - caster.posX, 0, particleZ - caster.posZ, 0, 0.1f, 0.0f, 0.0f); particleX = caster.posX - 1.0d + 2*world.rand.nextDouble(); particleZ = caster.posZ - 1.0d + 2*world.rand.nextDouble(); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, particleX, WizardryUtilities.getPlayerEyesPos(caster) - 1.5, particleZ, + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, particleX, WizardryUtilities.getPlayerEyesPos(caster) - 1.5, particleZ, particleX - caster.posX, 0, particleZ - caster.posZ, 30, 0.1f, 0.0f, 0.05f); particleX = caster.posX - 1.0d + 2*world.rand.nextDouble(); particleZ = caster.posZ - 1.0d + 2*world.rand.nextDouble(); - IBlockState block = WizardryUtilities.getBlockEntityIsStandingOn(caster); - + Block block = WizardryUtilities.getBlockEntityIsStandingOn(caster); + // Player actual eye height is 1.62, client is 1.5 too high, hence the -1.5. if(block != null){ - world.spawnParticle(EnumParticleTypes.BLOCK_DUST, particleX, caster.getEntityBoundingBox().minY, particleZ, - particleX - caster.posX, 0, particleZ - caster.posZ, Block.getStateId(block)); + Wizardry.proxy.spawnDigParticle(world, particleX, caster.posY - 1.5, particleZ, particleX - caster.posX, 0, particleZ - caster.posZ, + block); } } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_DEATH, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "mob.wither.death", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/PocketFurnace.java b/src/main/java/electroblob/wizardry/spell/PocketFurnace.java index 76f70f58..01bb1cd2 100644 --- a/src/main/java/electroblob/wizardry/spell/PocketFurnace.java +++ b/src/main/java/electroblob/wizardry/spell/PocketFurnace.java @@ -1,27 +1,25 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.FurnaceRecipes; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; import net.minecraft.world.World; public class PocketFurnace extends Spell { public PocketFurnace() { - super(Tier.APPRENTICE, 30, Element.FIRE, "pocket_furnace", SpellType.UTILITY, 40, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 30, EnumElement.FIRE, "pocket_furnace", EnumSpellType.UTILITY, 40, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { int usesLeft = 5; @@ -33,12 +31,12 @@ public class PocketFurnace extends Spell { if(stack != null){ - result = FurnaceRecipes.instance().getSmeltingResult(stack); + result = FurnaceRecipes.smelting().getSmeltingResult(stack); if(result != null){ if(stack.stackSize <= usesLeft){ ItemStack stack2 = new ItemStack(result.getItem(), stack.stackSize, result.getItemDamage()); - if(WizardryUtilities.doesPlayerHaveItem(caster, result.getItem())){ + if(caster.inventory.hasItem(result.getItem())){ caster.inventory.addItemStackToInventory(stack2); caster.inventory.setInventorySlotContents(i, null); }else{ @@ -54,14 +52,14 @@ public class PocketFurnace extends Spell { } } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.BLOCK_FURNACE_FIRE_CRACKLE, 1, 0.75f); + caster.playSound("fire.fire", 1, 0.75f); if(world.isRemote){ for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - world.spawnParticle(EnumParticleTypes.FLAME, x1, y1, z1, 0, 0.01F, 0); + world.spawnParticle("flame", x1, y1, z1, 0, 0.01F, 0); } } diff --git a/src/main/java/electroblob/wizardry/spell/PocketWorkbench.java b/src/main/java/electroblob/wizardry/spell/PocketWorkbench.java index bcb5ce53..7e14d965 100644 --- a/src/main/java/electroblob/wizardry/spell/PocketWorkbench.java +++ b/src/main/java/electroblob/wizardry/spell/PocketWorkbench.java @@ -1,22 +1,20 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; import electroblob.wizardry.WizardryGuiHandler; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.client.GuiPortableCrafting; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.InventoryEnderChest; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class PocketWorkbench extends Spell { public PocketWorkbench() { - super(Tier.APPRENTICE, 30, Element.SORCERY, "pocket_workbench", SpellType.UTILITY, 40, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 30, EnumElement.SORCERY, "pocket_workbench", EnumSpellType.UTILITY, 40, EnumAction.bow, false); } @Override @@ -25,14 +23,14 @@ public class PocketWorkbench extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { // TODO: Investigate possible item duplication bug with this spell. So far I have been unable to recreate it. if(!world.isRemote){ caster.openGui(Wizardry.instance, WizardryGuiHandler.PORTABLE_CRAFTING, world, (int)caster.posX, (int)caster.posY, (int)caster.posZ); } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1, 1); + world.playSoundAtEntity(caster, "wizardry:aura", 1, 1); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Poison.java b/src/main/java/electroblob/wizardry/spell/Poison.java index 9a69bc38..e98bb9d3 100644 --- a/src/main/java/electroblob/wizardry/spell/Poison.java +++ b/src/main/java/electroblob/wizardry/spell/Poison.java @@ -1,78 +1,76 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntitySpider; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class Poison extends Spell { public Poison() { - super(Tier.APPRENTICE, 10, Element.EARTH, "poison", SpellType.ATTACK, 20, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 10, EnumElement.EARTH, "poison", EnumSpellType.ATTACK, 20, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - Vec3d look = caster.getLookVec(); + Vec3 look = caster.getLookVec(); - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ EntityLivingBase target = (EntityLivingBase) rayTrace.entityHit; // Has no effect on undead or spiders. if(MagicDamage.isEntityImmune(DamageType.POISON, target)){ - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", target.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", target.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else{ - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.POISON), 1.0f * modifiers.get(SpellModifiers.DAMAGE)); - target.addPotionEffect(new PotionEffect(MobEffects.POISON, (int)(200*modifiers.get(WizardryItems.duration_upgrade)), 1)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.POISON), 1.0f * damageMultiplier); + target.addPotionEffect(new PotionEffect(Potion.poison.id, (int)(200*durationMultiplier), 1)); } } if(world.isRemote){ - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ // I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet! double x1 = caster.posX + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; //world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.3f, 0.7f, 0.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.1f, 0.4f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.3f, 0.7f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.1f, 0.4f, 0.0f); } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ // Has no effect on undead or spiders. if(!MagicDamage.isEntityImmune(DamageType.POISON, target) && !world.isRemote){ - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.POISON), 1.0f * modifiers.get(SpellModifiers.DAMAGE)); - target.addPotionEffect(new PotionEffect(MobEffects.POISON, (int)(200*modifiers.get(WizardryItems.duration_upgrade)), 1)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.POISON), 1.0f * damageMultiplier); + target.addPotionEffect(new PotionEffect(Potion.poison.id, (int)(200*durationMultiplier), 1)); } if(world.isRemote){ @@ -81,19 +79,19 @@ public class Poison extends Spell { double dy = (target.posY - caster.posY)/caster.getDistanceToEntity(target); double dz = (target.posZ - caster.posZ)/caster.getDistanceToEntity(target); - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ double x1 = caster.posX + dx*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = caster.posY + caster.getEyeHeight() - 0.4f + dy*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + dz*i/2 + world.rand.nextFloat()/5 - 0.1f; - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.3f, 0.7f, 0.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.1f, 0.4f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.3f, 0.7f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.1f, 0.4f, 0.0f); } } - caster.swingArm(hand); - caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/PoisonBomb.java b/src/main/java/electroblob/wizardry/spell/PoisonBomb.java index 3ee00729..6340dbb6 100644 --- a/src/main/java/electroblob/wizardry/spell/PoisonBomb.java +++ b/src/main/java/electroblob/wizardry/spell/PoisonBomb.java @@ -1,24 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntityPoisonBomb; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class PoisonBomb extends Spell { public PoisonBomb() { - super(Tier.APPRENTICE, 15, Element.EARTH, "poison_bomb", SpellType.ATTACK, 25, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 15, EnumElement.EARTH, "poison_bomb", EnumSpellType.ATTACK, 25, EnumAction.none, false); } @Override @@ -27,31 +22,31 @@ public class PoisonBomb extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntityPoisonBomb poisonbomb = new EntityPoisonBomb(world, caster, modifiers.get(SpellModifiers.DAMAGE), modifiers.get(WizardryItems.blast_upgrade)); + EntityPoisonBomb poisonbomb = new EntityPoisonBomb(world, caster, damageMultiplier, blastMultiplier); world.spawnEntityInWorld(poisonbomb); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + caster.swingItem(); + world.playSoundAtEntity(caster, "random.bow", 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntityPoisonBomb poisonbomb = new EntityPoisonBomb(world, caster, modifiers.get(SpellModifiers.DAMAGE), modifiers.get(WizardryItems.blast_upgrade)); + EntityPoisonBomb poisonbomb = new EntityPoisonBomb(world, caster, damageMultiplier, blastMultiplier); poisonbomb.directTowards(target, 1.5f); world.spawnEntityInWorld(poisonbomb); } - caster.swingArm(hand); - caster.playSound(SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + caster.swingItem(); + world.playSoundAtEntity(caster, "random.bow", 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/ReplenishHunger.java b/src/main/java/electroblob/wizardry/spell/ReplenishHunger.java index bf9983a6..9569f0d7 100644 --- a/src/main/java/electroblob/wizardry/spell/ReplenishHunger.java +++ b/src/main/java/electroblob/wizardry/spell/ReplenishHunger.java @@ -1,29 +1,26 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class ReplenishHunger extends Spell { public ReplenishHunger() { - super(Tier.APPRENTICE, 10, Element.HEALING, "replenish_hunger", SpellType.UTILITY, 30, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 10, EnumElement.HEALING, "replenish_hunger", EnumSpellType.UTILITY, 30, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(caster.getFoodStats().needFood()){ - int foodAmount = (int)(6*modifiers.get(SpellModifiers.DAMAGE)); + int foodAmount = (int)(6*damageMultiplier); // Fixed issue #6: Changed to addStats, since setFoodLevel is client-side only caster.getFoodStats().addStats(foodAmount, foodAmount*0.1f); if(world.isRemote){ @@ -31,10 +28,10 @@ public class ReplenishHunger extends Spell { double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 0.7f, 0.3f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 1.0f, 0.7f, 0.3f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/RingOfFire.java b/src/main/java/electroblob/wizardry/spell/RingOfFire.java index e4f1bd84..cf865bde 100644 --- a/src/main/java/electroblob/wizardry/spell/RingOfFire.java +++ b/src/main/java/electroblob/wizardry/spell/RingOfFire.java @@ -1,24 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.construct.EntityFireRing; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class RingOfFire extends Spell { public RingOfFire() { - super(Tier.ADVANCED, 30, Element.FIRE, "ring_of_fire", SpellType.ATTACK, 100, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 30, EnumElement.FIRE, "ring_of_fire", EnumSpellType.ATTACK, 100, EnumAction.bow, false); } @Override @@ -27,31 +22,29 @@ public class RingOfFire extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(caster.onGround){ if(!world.isRemote){ - EntityFireRing firering = new EntityFireRing(world, caster.posX, caster.posY, caster.posZ, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), modifiers.get(SpellModifiers.DAMAGE)); + EntityFireRing firering = new EntityFireRing(world, caster.posX, caster.posY, caster.posZ, caster, (int)(600*durationMultiplier), damageMultiplier); world.spawnEntityInWorld(firering); + world.playAuxSFX(1009, (int)caster.posX, (int)caster.posY, (int)caster.posZ, 0); } - - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1); return true; } return false; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ - if(caster.onGround && world.getEntitiesWithinAABB(EntityFireRing.class, caster.getEntityBoundingBox()).isEmpty()){ + if(caster.onGround && world.getEntitiesWithinAABB(EntityFireRing.class, caster.boundingBox).isEmpty()){ if(!world.isRemote){ - EntityFireRing firering = new EntityFireRing(world, caster.posX, caster.posY, caster.posZ, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), modifiers.get(SpellModifiers.DAMAGE)); + EntityFireRing firering = new EntityFireRing(world, caster.posX, caster.posY, caster.posZ, caster, (int)(600*durationMultiplier), damageMultiplier); world.spawnEntityInWorld(firering); + world.playAuxSFX(1009, (int)caster.posX, (int)caster.posY, (int)caster.posZ, 0); } - - caster.playSound(SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/ShadowWard.java b/src/main/java/electroblob/wizardry/spell/ShadowWard.java index 01132024..7a5a4d57 100644 --- a/src/main/java/electroblob/wizardry/spell/ShadowWard.java +++ b/src/main/java/electroblob/wizardry/spell/ShadowWard.java @@ -1,67 +1,35 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.item.ItemWand; -import electroblob.wizardry.util.IElementalDamage; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WandHelper; -import electroblob.wizardry.util.WizardryUtilities; -import electroblob.wizardry.util.MagicDamage.DamageType; -import net.minecraft.entity.EntityLivingBase; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; import net.minecraft.world.World; -import net.minecraftforge.event.entity.living.LivingAttackEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -@Mod.EventBusSubscriber public class ShadowWard extends Spell { public ShadowWard() { - super(Tier.ADVANCED, 10, Element.NECROMANCY, "shadow_ward", SpellType.DEFENCE, 0, EnumAction.BLOCK, true); + super(EnumTier.ADVANCED, 10, EnumElement.NECROMANCY, "shadow_ward", EnumSpellType.DEFENCE, 0, EnumAction.block, true); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { - + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { + if(world.isRemote){ double dx = -1 + 2*world.rand.nextFloat(); double dy = -1 + world.rand.nextFloat(); double dz = -1 + 2*world.rand.nextFloat(); - world.spawnParticle(EnumParticleTypes.PORTAL, caster.posX, WizardryUtilities.getPlayerEyesPos(caster), caster.posZ, dx, dy, dz); + world.spawnParticle("portal", caster.posX, WizardryUtilities.getPlayerEyesPos(caster), caster.posZ, dx, dy, dz); } - + if(ticksInUse % 50 == 0){ - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.BLOCK_PORTAL_AMBIENT, 0.6f, 1.5f); + world.playSoundAtEntity(caster, "portal.portal", 0.6f, 1.5f); } - + return true; } - @SubscribeEvent - public static void onLivingAttackEvent(LivingAttackEvent event){ - if(event.getSource() != null && event.getSource().getEntity() instanceof EntityLivingBase){ - // There used to be a check that the target was a player here, but I don't see any reason for it. - ItemStack wand = event.getEntityLiving().getActiveItemStack(); - - if(wand != null && wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand - && WandHelper.getCurrentSpell(wand) instanceof ShadowWard && !event.getSource().isUnblockable() - && !(event.getSource() instanceof IElementalDamage && ((IElementalDamage)event.getSource()).isRetaliatory())){ - - event.setCanceled(true); - // Now we can preserve the original daage source (sort of) as long as we make it retaliatory. - event.getEntityLiving().attackEntityFrom(MagicDamage.causeDirectMagicDamage(event.getSource().getEntity(), DamageType.MAGIC, true), event.getAmount()/2); - ((EntityLivingBase)event.getSource().getEntity()).attackEntityFrom(MagicDamage.causeDirectMagicDamage(event.getEntityLiving(), DamageType.MAGIC, true), event.getAmount()/2); - } - } - } } diff --git a/src/main/java/electroblob/wizardry/spell/Shield.java b/src/main/java/electroblob/wizardry/spell/Shield.java index 518cbe22..1d7d80f1 100644 --- a/src/main/java/electroblob/wizardry/spell/Shield.java +++ b/src/main/java/electroblob/wizardry/spell/Shield.java @@ -1,39 +1,35 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.WizardData; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.entity.EntityShield; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class Shield extends Spell { public Shield() { - super(Tier.APPRENTICE, 5, Element.HEALING, "shield", SpellType.DEFENCE, 0, EnumAction.BLOCK, true); + super(EnumTier.APPRENTICE, 5, EnumElement.HEALING, "shield", EnumSpellType.DEFENCE, 0, EnumAction.block, true); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - caster.addPotionEffect(new PotionEffect(MobEffects.RESISTANCE, 10, 0, false, false)); + caster.addPotionEffect(new PotionEffect(Potion.resistance.id, 10, 0, true)); - if(WizardData.get(caster).shield == null){ - WizardData.get(caster).shield = new EntityShield(world, caster); + if(ExtendedPlayer.get(caster).shield == null){ + ExtendedPlayer.get(caster).shield = new EntityShield(world, caster); if(!world.isRemote){ - world.spawnEntityInWorld(WizardData.get(caster).shield); + world.spawnEntityInWorld(ExtendedPlayer.get(caster).shield); } } if(ticksInUse == 0){ - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f); + world.playSoundAtEntity(caster, "wizardry:aura", 1.0f, 1.0f); } return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Shockwave.java b/src/main/java/electroblob/wizardry/spell/Shockwave.java index 1f48a728..35897664 100644 --- a/src/main/java/electroblob/wizardry/spell/Shockwave.java +++ b/src/main/java/electroblob/wizardry/spell/Shockwave.java @@ -2,44 +2,38 @@ package electroblob.wizardry.spell; import java.util.List; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.block.Block; -import net.minecraft.block.state.IBlockState; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.EnumAction; -import net.minecraft.network.play.server.SPacketEntityVelocity; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; +import net.minecraft.network.play.server.S12PacketEntityVelocity; import net.minecraft.world.World; public class Shockwave extends Spell { public Shockwave() { - super(Tier.MASTER, 65, Element.SORCERY, "shockwave", SpellType.ATTACK, 150, EnumAction.BOW, false); + super(EnumTier.MASTER, 65, EnumElement.SORCERY, "shockwave", EnumSpellType.ATTACK, 150, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - List targets = WizardryUtilities.getEntitiesWithinRadius(5.0d*modifiers.get(WizardryItems.blast_upgrade), caster.posX, caster.posY, caster.posZ, world); + List targets = WizardryUtilities.getEntitiesWithinRadius(5.0d*blastMultiplier, caster.posX, caster.posY, caster.posZ, world); for(EntityLivingBase target : targets){ if(WizardryUtilities.isValidTarget(caster, target)){ // Damage increases closer to player up to a maximum of 4 hearts (at 1 block distance). float damage = Math.min(8.0f/target.getDistanceToEntity(caster), 8.0f); - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.BLAST), damage * modifiers.get(SpellModifiers.DAMAGE)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.BLAST), damage * damageMultiplier); if(!world.isRemote){ @@ -58,40 +52,39 @@ public class Shockwave extends Spell { // Player motion is handled on that player's client so needs packets if(target instanceof EntityPlayerMP){ - ((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target)); + ((EntityPlayerMP)target).playerNetServerHandler.sendPacket(new S12PacketEntityVelocity(target)); } } } } if(world.isRemote){ - + + world.spawnParticle("largeexplode", caster.posX, caster.boundingBox.minY + 0.1, caster.posZ, 0, 0, 0); + double particleX, particleZ; for(int i=0;i<40;i++){ particleX = caster.posX - 1.0d + 2*world.rand.nextDouble(); particleZ = caster.posZ - 1.0d + 2*world.rand.nextDouble(); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, particleX, WizardryUtilities.getPlayerEyesPos(caster) - 1.5, particleZ, + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, particleX, WizardryUtilities.getPlayerEyesPos(caster) - 1.5, particleZ, particleX - caster.posX, 0, particleZ - caster.posZ, 30, 0.8f, 0.8f, 1.0f); particleX = caster.posX - 1.0d + 2*world.rand.nextDouble(); particleZ = caster.posZ - 1.0d + 2*world.rand.nextDouble(); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, particleX, WizardryUtilities.getPlayerEyesPos(caster) - 1.5, particleZ, + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, particleX, WizardryUtilities.getPlayerEyesPos(caster) - 1.5, particleZ, particleX - caster.posX, 0, particleZ - caster.posZ, 30, 0.9f, 0.9f, 0.9f); particleX = caster.posX - 1.0d + 2*world.rand.nextDouble(); particleZ = caster.posZ - 1.0d + 2*world.rand.nextDouble(); - IBlockState block = WizardryUtilities.getBlockEntityIsStandingOn(caster); - + Block block = WizardryUtilities.getBlockEntityIsStandingOn(caster); + // Player actual eye height is 1.62, client is 1.5 too high, hence the -1.5. if(block != null){ - world.spawnParticle(EnumParticleTypes.BLOCK_DUST, particleX, caster.getEntityBoundingBox().minY, particleZ, - particleX - caster.posX, 0, particleZ - caster.posZ, Block.getStateId(block)); + Wizardry.proxy.spawnDigParticle(world, particleX, WizardryUtilities.getPlayerEyesPos(caster) - 1.5, particleZ, particleX - caster.posX, 0, particleZ - caster.posZ, + block); } } - - world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, caster.posX, caster.getEntityBoundingBox().minY + 0.1, caster.posZ, 0, 0, 0); - } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SHOCKWAVE, 1.0f, 0.7f); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SHOCKWAVE, 2.0f, 0.3f); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:boom", 1.0f, 0.7f); + world.playSoundAtEntity(caster, "wizardry:boom", 2.0f, 0.3f); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/SilverfishSwarm.java b/src/main/java/electroblob/wizardry/spell/SilverfishSwarm.java index bd7ae7bc..424ac923 100644 --- a/src/main/java/electroblob/wizardry/spell/SilverfishSwarm.java +++ b/src/main/java/electroblob/wizardry/spell/SilverfishSwarm.java @@ -1,23 +1,17 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.living.EntitySilverfishMinion; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; public class SilverfishSwarm extends Spell { public SilverfishSwarm() { - super(Tier.MASTER, 80, Element.EARTH, "silverfish_swarm", SpellType.MINION, 300, EnumAction.BOW, false); + super(EnumTier.MASTER, 80, EnumElement.EARTH, "silverfish_swarm", EnumSpellType.MINION, 300, EnumAction.bow, false); } @Override @@ -26,22 +20,30 @@ public class SilverfishSwarm extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { - + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { + + boolean flag = false; + if(!world.isRemote){ for(int i=0;i<20;i++){ - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 3, 6); - // The spell instantly fails if no space was found (see javadoc for the above method). - if(pos == null) return false; - - EntitySilverfishMinion silverfish = new EntitySilverfishMinion(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); - world.spawnEntityInWorld(silverfish); + double x = caster.posX + world.rand.nextDouble()*6 - 3; + double z = caster.posZ + world.rand.nextDouble()*6 - 3; + // Allows for height variation. + if(world.getTopSolidOrLiquidBlock((int)x, (int)z) - caster.posY < 6){ + flag = true; + double y = Math.max(caster.posY, world.getTopSolidOrLiquidBlock((int)x, (int)z)); + EntitySilverfishMinion silverfish = new EntitySilverfishMinion(world, x, y, z, caster, (int)(600*durationMultiplier)); + world.spawnEntityInWorld(silverfish); + } } } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.BLOCK_FIRE_EXTINGUISH, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); - // Can't possibly get this far if nothing was spawned. - return true; + if(flag){ + world.playSoundAtEntity(caster, "random.fizz", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + } + // If no spiders were spawned (like in a 1x1 hole or something) then the spell does not use up mana. + return flag; } + } diff --git a/src/main/java/electroblob/wizardry/spell/SixthSense.java b/src/main/java/electroblob/wizardry/spell/SixthSense.java index f6505a75..9f221828 100644 --- a/src/main/java/electroblob/wizardry/spell/SixthSense.java +++ b/src/main/java/electroblob/wizardry/spell/SixthSense.java @@ -1,24 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Constants; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.Wizardry; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class SixthSense extends Spell { public SixthSense() { - super(Tier.APPRENTICE, 20, Element.EARTH, "sixth_sense", SpellType.UTILITY, 100, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 20, EnumElement.EARTH, "sixth_sense", EnumSpellType.UTILITY, 100, EnumAction.bow, false); } @Override @@ -27,13 +22,15 @@ public class SixthSense extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { - + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { + + ExtendedPlayer properties = ExtendedPlayer.get(caster); + // Cannot be cast when it has already been cast if(!world.isRemote){ - caster.addPotionEffect(new PotionEffect(WizardryPotions.sixth_sense, (int)(400*modifiers.get(WizardryItems.duration_upgrade)), (int)((modifiers.get(WizardryItems.range_upgrade)-1f)/Constants.RANGE_INCREASE_PER_LEVEL))); + caster.addPotionEffect(new PotionEffect(Wizardry.sixthSense.id, (int)(400*durationMultiplier), (int)((rangeMultiplier-1f)/Wizardry.RANGE_INCREASE_PER_LEVEL), true)); + world.playSoundAtEntity(caster, "mob.wither.shoot", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SHOOT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Slime.java b/src/main/java/electroblob/wizardry/spell/Slime.java index 6d9d5346..5311b535 100644 --- a/src/main/java/electroblob/wizardry/spell/Slime.java +++ b/src/main/java/electroblob/wizardry/spell/Slime.java @@ -1,84 +1,81 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.entity.living.EntityMagicSlime; -import electroblob.wizardry.registry.WizardryAchievements; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.entity.EntityMagicSlime; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.monster.EntitySkeleton; import net.minecraft.entity.monster.EntitySlime; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class Slime extends Spell { public Slime() { - super(Tier.ADVANCED, 20, Element.EARTH, "slime", SpellType.ATTACK, 50, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 20, EnumElement.EARTH, "slime", EnumSpellType.ATTACK, 50, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - Vec3d look = caster.getLookVec(); + Vec3 look = caster.getLookVec(); - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 8*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 8*rangeMultiplier); if(rayTrace != null && rayTrace.entityHit != null && rayTrace.entityHit instanceof EntityLivingBase){ EntityLivingBase target = (EntityLivingBase)rayTrace.entityHit; if(target instanceof EntitySlime){ - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", target.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", target.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else if(!(target instanceof EntityMagicSlime)){ - if(target instanceof EntitySkeleton) caster.addStat(WizardryAchievements.slime_skeleton); + if(target instanceof EntitySkeleton) caster.triggerAchievement(Wizardry.slimeSkeleton); if(!world.isRemote){ - EntityMagicSlime slime = new EntityMagicSlime(world, caster, target, (int)(200*modifiers.get(WizardryItems.duration_upgrade))); + EntityMagicSlime slime = new EntityMagicSlime(world, (int)(200*durationMultiplier)); + slime.setPosition(target.posX, target.posY, target.posZ); + slime.mountEntity(target); world.spawnEntityInWorld(slime); } } } if(world.isRemote){ - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ double x1 = caster.posX + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - world.spawnParticle(EnumParticleTypes.SLIME, x1, y1, z1, 0.0d, 0.0d, 0.0d); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.2f, 0.8f, 0.1f); + world.spawnParticle("slime", x1, y1, z1, 0.0d, 0.0d, 0.0d); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.2f, 0.8f, 0.1f); } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_SLIME_ATTACK, 1.0F, 0.5F); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "mob.slime.attack", 1.0F, 0.5F); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, 1.0F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null && !(target instanceof EntitySlime) && !(target instanceof EntityMagicSlime)){ if(!world.isRemote){ - EntityMagicSlime slime = new EntityMagicSlime(world, caster, target, (int)(200*modifiers.get(WizardryItems.duration_upgrade))); + EntityMagicSlime slime = new EntityMagicSlime(world, (int)(200*durationMultiplier)); + slime.setPosition(target.posX, target.posY, target.posZ); + slime.mountEntity(target); world.spawnEntityInWorld(slime); } @@ -88,20 +85,20 @@ public class Slime extends Spell { double dy = (target.posY - caster.posY)/caster.getDistanceToEntity(target); double dz = (target.posZ - caster.posZ)/caster.getDistanceToEntity(target); - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ double x1 = caster.posX + dx*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = caster.posY + caster.getEyeHeight() - 0.4f + dy*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + dz*i/2 + world.rand.nextFloat()/5 - 0.1f; - world.spawnParticle(EnumParticleTypes.SLIME, x1, y1, z1, 0.0d, 0.0d, 0.0d); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.2f, 0.8f, 0.1f); + world.spawnParticle("slime", x1, y1, z1, 0.0d, 0.0d, 0.0d); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.2f, 0.8f, 0.1f); } } - caster.swingArm(hand); - caster.playSound(SoundEvents.ENTITY_SLIME_ATTACK, 1.0F, 0.5F); - caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "mob.slime.attack", 1.0F, 0.5F); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/SmokeBomb.java b/src/main/java/electroblob/wizardry/spell/SmokeBomb.java index 6a71a532..2a49c833 100644 --- a/src/main/java/electroblob/wizardry/spell/SmokeBomb.java +++ b/src/main/java/electroblob/wizardry/spell/SmokeBomb.java @@ -1,24 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntitySmokeBomb; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class SmokeBomb extends Spell { public SmokeBomb() { - super(Tier.BASIC, 10, Element.FIRE, "smoke_bomb", SpellType.ATTACK, 20, EnumAction.NONE, false); + super(EnumTier.BASIC, 10, EnumElement.FIRE, "smoke_bomb", EnumSpellType.ATTACK, 20, EnumAction.none, false); } @Override @@ -27,31 +22,31 @@ public class SmokeBomb extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntitySmokeBomb smokebomb = new EntitySmokeBomb(world, caster, modifiers.get(SpellModifiers.DAMAGE), modifiers.get(WizardryItems.blast_upgrade)); + EntitySmokeBomb smokebomb = new EntitySmokeBomb(world, caster, damageMultiplier, blastMultiplier); world.spawnEntityInWorld(smokebomb); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + caster.swingItem(); + world.playSoundAtEntity(caster, "random.bow", 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntitySmokeBomb smokebomb = new EntitySmokeBomb(world, caster, modifiers.get(SpellModifiers.DAMAGE), modifiers.get(WizardryItems.blast_upgrade)); + EntitySmokeBomb smokebomb = new EntitySmokeBomb(world, caster, damageMultiplier, blastMultiplier); smokebomb.directTowards(target, 1.5f); world.spawnEntityInWorld(smokebomb); } - caster.swingArm(hand); - caster.playSound(SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + caster.swingItem(); + world.playSoundAtEntity(caster, "random.bow", 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Snare.java b/src/main/java/electroblob/wizardry/spell/Snare.java index 6d1b4815..ca3389c0 100644 --- a/src/main/java/electroblob/wizardry/spell/Snare.java +++ b/src/main/java/electroblob/wizardry/spell/Snare.java @@ -1,61 +1,58 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryBlocks; -import electroblob.wizardry.registry.WizardryItems; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.tileentity.TileEntityPlayerSave; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; public class Snare extends Spell { public Snare() { - super(Tier.BASIC, 10, Element.EARTH, "snare", SpellType.ATTACK, 10, EnumAction.NONE, false); + super(EnumTier.BASIC, 10, EnumElement.EARTH, "snare", EnumSpellType.ATTACK, 10, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.rayTrace(10*modifiers.get(WizardryItems.range_upgrade), world, caster, true); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(10*rangeMultiplier, world, caster, true); // Gets block the player is looking at and places snare - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ - BlockPos pos = rayTrace.getBlockPos(); + int blockHitX = rayTrace.blockX; + int blockHitY = rayTrace.blockY; + int blockHitZ = rayTrace.blockZ; + int blockHitSide = rayTrace.sideHit; - if(rayTrace.sideHit == EnumFacing.UP && world.isSideSolid(pos, EnumFacing.UP) && WizardryUtilities.canBlockBeReplaced(world, pos.up())){ + if(blockHitSide == 1 && world.isSideSolid(blockHitX, blockHitY, blockHitZ, ForgeDirection.UP) && WizardryUtilities.canBlockBeReplaced(world, blockHitX, blockHitY+1, blockHitZ)){ if(!world.isRemote){ - world.setBlockState(pos.up(), WizardryBlocks.snare.getDefaultState()); - ((TileEntityPlayerSave)world.getTileEntity(pos.up())).setCaster(caster); + world.setBlock(blockHitX, blockHitY+1, blockHitZ, Wizardry.snare); + ((TileEntityPlayerSave)world.getTileEntity(blockHitX, blockHitY+1, blockHitZ)).setCaster(caster); } - double dx = pos.getX() + 0.5 - caster.posX; - double dy = pos.getY() + 1.5 - (caster.posY + caster.height/2); - double dz = pos.getZ() + 0.5 - caster.posZ; + double dx = blockHitX + 0.5 - caster.posX; + double dy = blockHitY + 1.5 - (caster.posY + caster.height/2); + double dz = blockHitZ + 0.5 - caster.posZ; if(world.isRemote){ for(int i=1;i<5;i++){ float brightness = world.rand.nextFloat()/4; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0.0d, 0.0d, 0.0d, 20 + world.rand.nextInt(8), brightness, brightness + 0.1f, 0.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.LEAF, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, -0.01, 0, 40 + world.rand.nextInt(10)); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0.0d, 0.0d, 0.0d, 20 + world.rand.nextInt(8), brightness, brightness + 0.1f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.LEAF, world, caster.posX + (i*(dx/5)) + world.rand.nextFloat()/5, WizardryUtilities.getPlayerEyesPos(caster) + (i*(dy/5)) + world.rand.nextFloat()/5, caster.posZ + (i*(dz/5)) + world.rand.nextFloat()/5, 0, -0.01, 0, 40 + world.rand.nextInt(10)); } } - - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.BLOCK_GRASS_PLACE, 1.0F, world.rand.nextFloat() * 0.4F + 1.2F); + caster.swingItem(); + world.playSoundAtEntity(caster, "dig.grass", 1.0F, world.rand.nextFloat() * 0.4F + 1.2F); return true; } } diff --git a/src/main/java/electroblob/wizardry/spell/Snowball.java b/src/main/java/electroblob/wizardry/spell/Snowball.java index c5aed5ab..75c362a1 100644 --- a/src/main/java/electroblob/wizardry/spell/Snowball.java +++ b/src/main/java/electroblob/wizardry/spell/Snowball.java @@ -1,21 +1,18 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.projectile.EntitySnowball; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class Snowball extends Spell { public Snowball() { - super(Tier.BASIC, 1, Element.ICE, "snowball", SpellType.ATTACK, 1, EnumAction.NONE, false); + super(EnumTier.BASIC, 1, EnumElement.ICE, "snowball", EnumSpellType.ATTACK, 1, EnumAction.none, false); } @Override @@ -24,16 +21,23 @@ public class Snowball extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { - + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { + + Vec3 look = caster.getLookVec(); + if(!world.isRemote){ + EntitySnowball snowball = new EntitySnowball(world, caster); - snowball.setHeadingFromThrower(caster, caster.rotationPitch, caster.rotationYaw, 0.0f, 1.5f, 1.0f); + + //snowball.motionX = look.xCoord * 1.5; + //snowball.motionY = look.yCoord * 1.5; + //snowball.motionZ = look.zCoord * 1.5; + world.spawnEntityInWorld(snowball); } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); - caster.swingArm(hand); + world.playSoundAtEntity(caster, "random.bow", 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + caster.swingItem(); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/SparkBomb.java b/src/main/java/electroblob/wizardry/spell/SparkBomb.java index e0c55295..721c5661 100644 --- a/src/main/java/electroblob/wizardry/spell/SparkBomb.java +++ b/src/main/java/electroblob/wizardry/spell/SparkBomb.java @@ -1,24 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntitySparkBomb; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class SparkBomb extends Spell { public SparkBomb() { - super(Tier.APPRENTICE, 15, Element.LIGHTNING, "spark_bomb", SpellType.ATTACK, 25, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 15, EnumElement.LIGHTNING, "spark_bomb", EnumSpellType.ATTACK, 25, EnumAction.none, false); } @Override @@ -27,31 +22,31 @@ public class SparkBomb extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntitySparkBomb sparkBomb = new EntitySparkBomb(world, caster, modifiers.get(SpellModifiers.DAMAGE), modifiers.get(WizardryItems.blast_upgrade)); + EntitySparkBomb sparkBomb = new EntitySparkBomb(world, caster, damageMultiplier, blastMultiplier); world.spawnEntityInWorld(sparkBomb); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + caster.swingItem(); + world.playSoundAtEntity(caster, "random.bow", 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntitySparkBomb sparkBomb = new EntitySparkBomb(world, caster, modifiers.get(SpellModifiers.DAMAGE), modifiers.get(WizardryItems.blast_upgrade)); + EntitySparkBomb sparkBomb = new EntitySparkBomb(world, caster, damageMultiplier, blastMultiplier); sparkBomb.directTowards(target, 1.5f); world.spawnEntityInWorld(sparkBomb); } - caster.swingArm(hand); - caster.playSound(SoundEvents.ENTITY_SNOWBALL_THROW, 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); + caster.swingItem(); + world.playSoundAtEntity(caster, "random.bow", 0.5F, 0.4F / (world.rand.nextFloat() * 0.4F + 0.8F)); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/SpectralPathway.java b/src/main/java/electroblob/wizardry/spell/SpectralPathway.java index f544ffb3..1de47196 100644 --- a/src/main/java/electroblob/wizardry/spell/SpectralPathway.java +++ b/src/main/java/electroblob/wizardry/spell/SpectralPathway.java @@ -1,27 +1,21 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryBlocks; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.tileentity.TileEntityTimer; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumFacing.AxisDirection; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.MathHelper; import net.minecraft.world.World; public class SpectralPathway extends Spell { public SpectralPathway() { - super(Tier.ADVANCED, 40, Element.SORCERY, "spectral_pathway", SpellType.UTILITY, 300, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 40, EnumElement.SORCERY, "spectral_pathway", EnumSpellType.UTILITY, 300, EnumAction.bow, false); } @Override @@ -30,15 +24,31 @@ public class SpectralPathway extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { // Won't work if caster is airborne or if they are already on a bridge (prevents infinite bridges) - if(WizardryUtilities.getBlockEntityIsStandingOn(caster).getBlock() == Blocks.AIR - || WizardryUtilities.getBlockEntityIsStandingOn(caster).getBlock() == WizardryBlocks.spectral_block){ + if(WizardryUtilities.getBlockEntityIsStandingOn(caster) == Blocks.air + || WizardryUtilities.getBlockEntityIsStandingOn(caster) == Wizardry.spectralBlock){ return false; } - EnumFacing direction = caster.getHorizontalFacing(); + // Changes the yaw to 0, 1, 2 or 3 (compass directions) + //int direction = 0; + /*= (int)((entityplayer.rotationYawHead-45)/90); + if(direction == 4) direction = 0;*/ + /* + if(caster.rotationYawHead <= 45 || caster.rotationYawHead > 315){ + direction = 3; + }else if(caster.rotationYawHead > 45 && caster.rotationYawHead <= 135){ + direction = 0; + }else if(caster.rotationYawHead > 135 && caster.rotationYawHead <= 225){ + direction = 1; + }else if(caster.rotationYawHead > 225 && caster.rotationYawHead <= 315){ + direction = 2; + } + */ + + int direction = MathHelper.floor_double((double)(caster.rotationYaw * 4.0F / 360.0F) + 0.5D) & 3; boolean flag = false; @@ -46,35 +56,87 @@ public class SpectralPathway extends Spell { int baseLength = 15; - // Gets the coordinates of the nearest block intersection to the player's feet. - // Remember that a block always takes the coordinates of its northwestern corner. - BlockPos origin = new BlockPos(Math.round(caster.posX), (int)caster.getEntityBoundingBox().minY-1, Math.round(caster.posZ)); - - int startPoint = direction.getAxisDirection() == AxisDirection.POSITIVE ? -1 : 0; - - for(int i=0; i<(int)(baseLength*modifiers.get(WizardryItems.range_upgrade)); i++){ - // If either a block gets placed or one has already been placed, flag is set to true. - flag = placePathwayBlockIfPossible(world, origin.offset(direction, startPoint + i), modifiers.get(WizardryItems.duration_upgrade)) || flag; - flag = placePathwayBlockIfPossible(world, origin.offset(direction, startPoint + i) - // Moves the BlockPos minus one block perpendicular to direction. - .offset(EnumFacing.getFacingFromAxis(AxisDirection.NEGATIVE, direction.rotateY().getAxis())), modifiers.get(WizardryItems.duration_upgrade)) || flag; + //entityplayer.addChatMessage("Direction: " + direction); + switch(direction){ + case 0: + for(int i=0; i<(int)(baseLength*rangeMultiplier); i++){ + if(WizardryUtilities.canBlockBeReplacedB(world, (int)(caster.posX+0.5) - 1, (int)caster.posY-1, (int)(caster.posZ+0.5) + i - 1)){ + world.setBlock((int)(caster.posX+0.5) - 1, (int)caster.posY-1, (int)(caster.posZ+0.5) + i - 1, Wizardry.spectralBlock); + if(world.getTileEntity((int)(caster.posX+0.5) - 1, (int)caster.posY-1, (int)(caster.posZ+0.5) + i - 1) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity((int)(caster.posX+0.5) - 1, (int)caster.posY-1, (int)(caster.posZ+0.5) + i - 1)).setLifetime((int)(1200*durationMultiplier)); + } + flag = true; + } + if(WizardryUtilities.canBlockBeReplacedB(world, (int)(caster.posX+0.5) - 2, (int)caster.posY-1, (int)(caster.posZ+0.5) + i - 1)){ + world.setBlock((int)(caster.posX+0.5) - 2, (int)caster.posY-1, (int)(caster.posZ+0.5) + i - 1, Wizardry.spectralBlock); + if(world.getTileEntity((int)(caster.posX+0.5) - 2, (int)caster.posY-1, (int)(caster.posZ+0.5) + i - 1) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity((int)(caster.posX+0.5) - 2, (int)caster.posY-1, (int)(caster.posZ+0.5) + i - 1)).setLifetime((int)(1200*durationMultiplier)); + } + flag = true; + } + } + break; + case 1: + for(int i=0; i<(int)(baseLength*rangeMultiplier); i++){ + if(WizardryUtilities.canBlockBeReplacedB(world, (int)(caster.posX+0.5) - i - 1, (int)caster.posY-1, (int)(caster.posZ+0.5) - 1)){ + world.setBlock((int)(caster.posX+0.5) - i - 1, (int)caster.posY-1, (int)(caster.posZ+0.5) - 1, Wizardry.spectralBlock); + if(world.getTileEntity((int)(caster.posX+0.5) - i - 1, (int)caster.posY-1, (int)(caster.posZ+0.5) - 1) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity((int)(caster.posX+0.5) - i - 1, (int)caster.posY-1, (int)(caster.posZ+0.5) - 1)).setLifetime((int)(1200*durationMultiplier)); + } + flag = true; + } + if(WizardryUtilities.canBlockBeReplacedB(world, (int)(caster.posX+0.5) - i - 1, (int)caster.posY-1, (int)(caster.posZ+0.5))){ + world.setBlock((int)(caster.posX+0.5) - i - 1, (int)caster.posY-1, (int)(caster.posZ+0.5), Wizardry.spectralBlock); + if(world.getTileEntity((int)(caster.posX+0.5) - i - 1, (int)caster.posY-1, (int)(caster.posZ+0.5)) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity((int)(caster.posX+0.5) - i - 1, (int)caster.posY-1, (int)(caster.posZ+0.5))).setLifetime((int)(1200*durationMultiplier)); + } + flag = true; + } + } + break; + case 2: + for(int i=0; i<(int)(baseLength*rangeMultiplier); i++){ + if(WizardryUtilities.canBlockBeReplacedB(world, (int)(caster.posX+0.5) - 1, (int)caster.posY-1, (int)(caster.posZ+0.5) - i)){ + world.setBlock((int)(caster.posX+0.5) - 1, (int)caster.posY-1, (int)(caster.posZ+0.5) - i, Wizardry.spectralBlock); + if(world.getTileEntity((int)(caster.posX+0.5) - 1, (int)caster.posY-1, (int)(caster.posZ+0.5) - i) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity((int)(caster.posX+0.5) - 1, (int)caster.posY-1, (int)(caster.posZ+0.5) - i)).setLifetime((int)(1200*durationMultiplier)); + } + flag = true; + } + if(WizardryUtilities.canBlockBeReplacedB(world, (int)(caster.posX+0.5) - 2, (int)caster.posY-1, (int)(caster.posZ+0.5) - i)){ + world.setBlock((int)(caster.posX+0.5) - 2, (int)caster.posY-1, (int)(caster.posZ+0.5) - i, Wizardry.spectralBlock); + if(world.getTileEntity((int)(caster.posX+0.5) - 2, (int)caster.posY-1, (int)(caster.posZ+0.5) - i) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity((int)(caster.posX+0.5) - 2, (int)caster.posY-1, (int)(caster.posZ+0.5) - i)).setLifetime((int)(1200*durationMultiplier)); + } + flag = true; + } + } + break; + case 3: + for(int i=0; i<(int)(baseLength*rangeMultiplier); i++){ + if(WizardryUtilities.canBlockBeReplacedB(world, (int)(caster.posX+0.5) + i - 2, (int)caster.posY-1, (int)(caster.posZ+0.5) - 1)){ + world.setBlock((int)(caster.posX+0.5) + i - 2, (int)caster.posY-1, (int)(caster.posZ+0.5) - 1, Wizardry.spectralBlock); + if(world.getTileEntity((int)(caster.posX+0.5) + i - 2, (int)caster.posY-1, (int)(caster.posZ+0.5) - 1) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity((int)(caster.posX+0.5) + i - 2, (int)caster.posY-1, (int)(caster.posZ+0.5) - 1)).setLifetime((int)(1200*durationMultiplier)); + } + flag = true; + } + if(WizardryUtilities.canBlockBeReplacedB(world, (int)(caster.posX+0.5) + i - 2, (int)caster.posY-1, (int)(caster.posZ+0.5))){ + world.setBlock((int)(caster.posX+0.5) + i - 2, (int)caster.posY-1, (int)(caster.posZ+0.5), Wizardry.spectralBlock); + if(world.getTileEntity((int)(caster.posX+0.5) + i - 2, (int)caster.posY-1, (int)(caster.posZ+0.5)) instanceof TileEntityTimer){ + ((TileEntityTimer)world.getTileEntity((int)(caster.posX+0.5) + i - 2, (int)caster.posY-1, (int)(caster.posZ+0.5))).setLifetime((int)(1200*durationMultiplier)); + } + flag = true; + } + } + break; } } - // TODO: There may be some client/server discrepancies here. - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION_LARGE, 1.0f, 1.0f); + + if(flag) world.playSoundAtEntity(caster, "wizardry:largeaura", 1.0f, 1.0f); return flag; } - private static boolean placePathwayBlockIfPossible(World world, BlockPos pos, float durationMultiplier){ - if(WizardryUtilities.canBlockBeReplacedB(world, pos)){ - world.setBlockState(pos, WizardryBlocks.spectral_block.getDefaultState()); - if(world.getTileEntity(pos) instanceof TileEntityTimer){ - ((TileEntityTimer)world.getTileEntity(pos)).setLifetime((int)(1200*durationMultiplier)); - } - return true; - } - return false; - } - + } diff --git a/src/main/java/electroblob/wizardry/spell/Spell.java b/src/main/java/electroblob/wizardry/spell/Spell.java index 594f1ef2..adfb9c67 100644 --- a/src/main/java/electroblob/wizardry/spell/Spell.java +++ b/src/main/java/electroblob/wizardry/spell/Spell.java @@ -1,50 +1,39 @@ package electroblob.wizardry.spell; import java.util.ArrayList; -import java.util.HashSet; +import java.util.Collections; import java.util.List; -import java.util.Set; -import java.util.function.Predicate; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.WizardryRegistry; import electroblob.wizardry.entity.living.EntityWizard; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.util.SpellModifiers; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -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.StatCollector; import net.minecraft.world.World; -import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.registry.IForgeRegistry; -import net.minecraftforge.fml.common.registry.IForgeRegistryEntry; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -/** - * Generic spell class which is the superclass to all spells in wizardry. When extending this class, you must do +/** Generic spell class which is the superclass to all spells in wizardry. When extending this class, you must do * the following: *

    * - Have a constructor which passes all necessary constants into the super constructor. I define the constants here * so that the constructor for an individual spell has no parameters, but you may prefer to pass in the parameters when * the spell is registered, so all the mana costs etc. are in one place like a sort of sandbox. *

    - * - Implement the {@link Spell#cast(World, EntityPlayer, EnumHand, int, SpellModifiers)} method, in which you should + * - Implement the {@link Spell#cast(World, EntityPlayer, int, float, float, float, float)} method, in which you should * execute the code that makes the spell work, and return true or false depending on whether the spell succeeded and * therefore whether mana should be used up. *

    - * - Register the spell using {@link RegistryEvent.Register}, with {@link Spell} as the type parameter. Each spell - * should have a single instance, like blocks and items. - * As of Wizardry 2.1, spells use the Forge registry system. Related methods such as {@link Spell#id()} and - * {@link Spell#get(int)} have been re-routed to use this system, leaving minimal external changes. Note also that - * the constructor automatically sets the registry name for you, though you may change it afterwards if necessary. + * - Register the spell using {@link Spell#register(Spell)} during the init() method of your main mod class. Each spell + * should have a single instance, like blocks and items. Unlike with blocks and items however, it is usually not + * necessary to keep a reference to this instance unless something specific requires it (for example, the + * {@link Transportation} spell instance is stored in {@link WizardryRegistry} so that its name can be used in chat + * messages). *

    * Also note that you can override some other methods from this class. For example, to add a * specific kind of formatting to a spell name or description, you can override {@link Spell#getDisplayName()}, @@ -55,33 +44,38 @@ import net.minecraftforge.fml.relauncher.SideOnly; * This class is also home to some useful static methods for interacting with the spell registry:

    * {@link Spell#get(int)} gets a spell instance from its integer id, which corresponds to the metadata of its spell book.
    * {@link Spell#get(String)} gets a spell instance from its unlocalised name.
    - * {@link Spell#getSpells(Predicate)} returns a list of spell instances the match the given {@link Predicate}.
    + * {@link Spell#getSpells(Filter)} returns a list of spell instances the match the given {@link Filter}. * {@link Spell#getTotalSpellCount()} returns the total number of registered spells. *


    * Spell implements the {@link Comparable} interface, and as such, any collection of spells can be sorted. Spells are - * sorted by increasing tier (see {@link Tier}), from novice to master. Within each tier, spells are sorted by element, - * the order of which is as defined in {@link Element} (i.e. magic, fire, ice, lightning, necromancy, earth, sorcery, healing). + * sorted by increasing tier (see {@link EnumTier}), from novice to master. Within each tier, spells are sorted by element, + * the order of which is as defined in {@link EnumElement} (i.e. magic, fire, ice, lightning, necromancy, earth, sorcery, healing). *
    * @since Wizardry 1.0 * @see electroblob.wizardry.item.ItemSpellBook ItemSpellBook * @see electroblob.wizardry.item.ItemScroll ItemScroll - * @see Spells + * @see WizardryRegistry */ -public abstract class Spell extends IForgeRegistryEntry.Impl implements Comparable { + +public abstract class Spell implements Comparable { - /** Forge registry-based replacement for the internal spells list. */ - public static IForgeRegistry registry; + /** The internal list of all registered spells. This is deliberately made private since it shouldn't be fiddled with. */ + private static ArrayList spellsList = new ArrayList(1); + + /** The internal list of all registered spells' unlocalised names, used in commands. This is deliberately made + * private since it shouldn't be fiddled with. */ + private static ArrayList unlocalisedNames = new ArrayList(1); /** The tier this spell belongs to. */ - public final Tier tier; + public final EnumTier tier; /** Mana cost of the spell. If it is a continuous spell the cost is per second. */ public final int cost; /** The element this spell belongs to. */ - public final Element element; + public final EnumElement element; /** The unlocalised name of the spell. */ private final String unlocalisedName; /** The type of spell this is classified as. */ - public final SpellType type; + public final EnumSpellType type; /** Cooldown for the spell in ticks */ public final int cooldown; /** The action the player does when this spell is cast. */ @@ -89,10 +83,11 @@ public abstract class Spell extends IForgeRegistryEntry.Impl implements C /** Whether or not the spell is continuous (keeps going as long as the mouse button is held) */ public final boolean isContinuous; - /** ResourceLocation of the spell icon. */ - private final ResourceLocation icon; - /** Mod ID of the mod that added this spell; defaults to {@link Wizardry#MODID} if not specified. */ - private final String modID; + /** ResourceLocation of the spell icon. This is set up within the constructor; don't change it otherwise. */ + public ResourceLocation icon; + /** Mod ID of the mod that added this spell; defaults to Wizardry.MODID if not specified. This is set up within the + * constructor; don't change it otherwise. */ + public String modID; /** False if the spell has been disabled in the config file, true otherwise. This is now encapsulated to stop it * being fiddled with. */ @@ -100,21 +95,29 @@ public abstract class Spell extends IForgeRegistryEntry.Impl implements C /** * This constructor should be called from any subclasses, either feeding in the constants directly or through - * their own constructor from wherever the spell is registered. This is the constructor for wizardry's own spells; - * spells added by other mods should use {@link Spell#Spell(Tier, int, Element, String, SpellType, int, EnumAction, boolean, String)}. + * their own constructor from wherever the spell is registered. This is the constructor for original spells; + * spells added by other mods should use {@link Spell#Spell(EnumTier, int, EnumElement, String, EnumSpellType, int, EnumAction, boolean, String)}. * @param tier The tier this spell belongs to. * @param cost The amount of mana used to cast the spell. If this is a continuous spell, it represents mana cost * per second and should be a multiple of 5. * @param element The element this spell belongs to. - * @param name The registry name of the spell. This will also be the name of the icon file. The spell's - * unlocalised name will be a resource location with the format [modid]:[name]. + * @param name The unlocalised name of the spell This will also be the name of the icon file. * @param cooldown The cooldown time for this spell in ticks. * @param action The vanilla usage action to be displayed when casting this spell. * @param isContinuous Whether this spell is continuous, meaning you cast it for a length of time by holding the * right mouse button. */ - public Spell(Tier tier, int cost, Element element, String name, SpellType type, int cooldown, EnumAction action, boolean isContinuous){ - this(tier, cost, element, name, type, cooldown, action, isContinuous, Wizardry.MODID); + public Spell(EnumTier tier, int cost, EnumElement element, String name, EnumSpellType type, int cooldown, EnumAction action, boolean isContinuous){ + this.tier = tier; + this.cost = cost; + this.element = element; + this.unlocalisedName = name; + this.type = type; + this.cooldown = cooldown; + this.action = action; + this.isContinuous = isContinuous; + this.modID = Wizardry.MODID; + this.icon = new ResourceLocation(this.modID, "textures/spells/" + this.unlocalisedName + ".png"); } /** @@ -124,8 +127,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl implements C * @param cost The amount of mana used to cast the spell. If this is a continuous spell, it represents mana cost * per second and should be a multiple of 5. * @param element The element this spell belongs to. - * @param name The registry name of the spell, excluding the mod id. This will also be the name of the icon - * file. The spell's unlocalised name will be a resource location with the format [modid]:[name]. + * @param name The unlocalised name of the spell. This will also be the name of the icon file. * @param cooldown The cooldown time for this spell in ticks. * @param action The vanilla usage action to be displayed when casting this spell (see {@link}EnumAction) * @param isContinuous Whether this spell is continuous, meaning you cast it for a length of time by holding the @@ -133,18 +135,10 @@ public abstract class Spell extends IForgeRegistryEntry.Impl implements C * @param modID The mod id of the mod that added this spell. This allows wizardry to use the correct file * path for the spell icon, and also more generally to distinguish between original and addon spells. */ - public Spell(Tier tier, int cost, Element element, String name, SpellType type, int cooldown, EnumAction action, boolean isContinuous, String modID){ - this.tier = tier; - this.cost = cost; - this.element = element; - this.type = type; - this.cooldown = cooldown; - this.action = action; - this.isContinuous = isContinuous; + public Spell(EnumTier tier, int cost, EnumElement element, String name, EnumSpellType type, int cooldown, EnumAction action, boolean isContinuous, String modID){ + this(tier, cost, element, name, type, cooldown, action, isContinuous); this.modID = modID; - this.setRegistryName(modID, name); - this.unlocalisedName = this.getRegistryName().toString(); - this.icon = new ResourceLocation(this.modID, "textures/spells/" + name + ".png"); + this.icon = new ResourceLocation(this.modID, "textures/spells/" + this.unlocalisedName + ".png"); } /** @@ -161,15 +155,17 @@ public abstract class Spell extends IForgeRegistryEntry.Impl implements C * are discrepancies between client and server. * @param world A reference to the world object. Again this is for convenience, you can also use caster.worldObj. * @param caster The EntityPlayer that cast the spell. - * @param hand The hand that is holding the item used to cast the spell. If no item was used, this will be the main hand. * @param ticksInUse The number of ticks the spell has already been cast for. For all non-continuous spells, this is 0 and * is not used. For continuous spells, it is passed in as the maximum use duration of the item minus the count parameter in * onUsingItemTick and therefore it increases by 1 each tick. - * @param modifiers A {@link SpellModifiers} object containing the modifiers that have been applied to the spell. See - * the javadoc for that class for more information. If no modifiers are required, pass in {@code new SpellModifiers()}. + * @param damageMultiplier The damage multiplier to apply; pass in 1 if no multiplier is needed. + * @param rangeMultiplier The range multiplier to apply; pass in 1 if no multiplier is needed. + * @param durationMultiplier The duration multiplier to apply; pass in 1 if no multiplier is needed. + * @param blastMultiplier The blast radius multiplier to apply; pass in 1 if no multiplier is needed. + * * @return True if the spell succeeded and mana should be used up, false if not. */ - public abstract boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers); + public abstract boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier); /** Casts the spell, but with an EntityLiving as the caster. Each subclass can optionally override this method and * within it execute the code to make the spell work. Returns a boolean to allow whatever calls this method to check if the spell @@ -188,21 +184,21 @@ public abstract class Spell extends IForgeRegistryEntry.Impl implements C * It's worth noting that on the client side, this method only gets called if the server side * cast() method succeeded, so you can put any particle spawning code outside of any success conditions if there * are discrepancies between client and server. + * * @param world A reference to the world object. This is for convenience, you can also use caster.worldObj. * @param caster The EntityLiving that cast the spell. - * @param hand The hand that is holding the item used to cast the spell. This will almost certainly be the main hand. - * @param ticksInUse The number of ticks the spell has already been cast for. For all non-continuous spells, this is 0 and - * is not used. - * @param target The EntityLivingBase that is targeted by the spell. May be null in some cases. - * @param modifiers A {@link SpellModifiers} object containing the modifiers that have been applied to the spell. See - * the javadoc for that class for more information. If no modifiers are required, pass in {@code new SpellModifiers()}. + * @param target The EntityLivingBase that is targeted by the spell. You must check if this parameter is null when overriding. + * @param damageMultiplier The damage multiplier to apply; pass in 1 if no multiplier is needed. + * @param rangeMultiplier The range multiplier to apply; pass in 1 if no multiplier is needed. + * @param durationMultiplier The duration multiplier to apply; pass in 1 if no multiplier is needed. + * @param blastMultiplier The blast radius multiplier to apply; pass in 1 if no multiplier is needed. * @return True if the spell succeeded, false if not. Returns false by default. */ - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ return false; } - /** Whether NPCs such as wizards can cast this spell. If you have overridden {@link Spell#cast(World, EntityLiving, EnumHand, int, EntityLivingBase, SpellModifiers)}, + /** Whether NPCs such as wizards can cast this spell. If you have overridden {@link Spell#cast(World, EntityLiving, EntityLivingBase, float, float, float, float)}, * you should override this to return true. */ public boolean canBeCastByNPCs(){ return false; @@ -223,68 +219,31 @@ public abstract class Spell extends IForgeRegistryEntry.Impl implements C return true; } - /** Returns this spell's id number, which now corresponds to its position in the spell registry. + /** Returns this spell's id number, which now corresponds to its position in the spells ArrayList. * Returns -1 if the spell has not been registered. */ // This is final so nothing can override it, because that would cause all kinds of problems! public final int id(){ - return registry.getValues().indexOf(this); + return spellsList.indexOf(this); } - /** Returns the mod ID for this spell, which should be the ID of the mod that added it. The mod ID is - * used to tell wizardry which filepath to use for the spell's icon. As of Wizardry 1.2, the field itself is - * private, but this getter is provided for external use (though it is never called in the main Wizardry mod). */ - public final String getModID(){ - return modID; - } - - /** Returns the ResourceLocation for this spell's icon. */ - public final ResourceLocation getIcon(){ - return icon; - } - - /** Returns the unlocalised name of the spell, without any prefixes or suffixes, e.g. "flame_ray". This should - * only be used for translation purposes. */ - public final String getUnlocalisedName(){ + /** Returns the unlocalised name of the spell. */ + public String getUnlocalisedName(){ return unlocalisedName; } - - /* The general idea with translation is to use net.minecraft.client.resources.I18n directly on the client side (and - * just prepend formatting codes where necessary), and to use TextComponentTranslation on the server (setting the - * style as necessary). TextComponentTranslation effectively stores what needs to be translated, without actually - * translating it. If, for whatever reason, you need to supply an ITextComponent but don't want it translated - * (perhaps a name?), you can use TextComponentString, which will simply keep the raw string it is given. */ - /** Returns the translated display name of the spell, without formatting (i.e. not coloured). Client-side only! - * On the server side, use {@link TextComponentTranslation} (see {@link Spell#getNameForTranslation()}). */ - @SideOnly(Side.CLIENT) + /** Returns the translated display name of the spell, without formatting (i.e. not coloured). */ public String getDisplayName(){ - return net.minecraft.client.resources.I18n.format("spell." + unlocalisedName); - } - - /** Returns a {@code TextComponentTranslation} which will be translated to the display name of the spell, without - * formatting (i.e. not coloured). */ - public TextComponentTranslation getNameForTranslation(){ - return new TextComponentTranslation("spell." + unlocalisedName); + return StatCollector.translateToLocal("spell." + unlocalisedName); } - /** Returns the translated display name of the spell, with formatting (i.e. coloured). Client-side only! - * On the server side, use {@link TextComponentTranslation} (see {@link Spell#getNameForTranslationFormatted()}). */ - @SideOnly(Side.CLIENT) + /** Returns the translated display name of the spell, with formatting (i.e. coloured). */ public String getDisplayNameWithFormatting(){ - return this.element.getFormattingCode() + net.minecraft.client.resources.I18n.format("spell." + unlocalisedName); - } - - /** Returns a {@code TextComponentTranslation} which will be translated to the display name of the spell, with - * formatting (i.e. coloured). */ - public ITextComponent getNameForTranslationFormatted(){ - return new TextComponentTranslation("spell." + unlocalisedName).setStyle(this.element.getColour()); + return this.element.colour + StatCollector.translateToLocal("spell." + unlocalisedName); } - /** Returns the translated description of the spell, without formatting. Client-side only! You should not - * need to use this on the server side. */ - @SideOnly(Side.CLIENT) + /** Returns the translated description of the spell, without formatting. */ public String getDescription(){ - return net.minecraft.client.resources.I18n.format("spell." + unlocalisedName + ".desc"); + return StatCollector.translateToLocal("spell." + unlocalisedName + ".desc"); } /** Returns whether the spell is enabled in the config. */ @@ -319,49 +278,79 @@ public abstract class Spell extends IForgeRegistryEntry.Impl implements C // ================================================ Static methods ================================================== + /** + * Registers a spell with the wizardry mod. Each spell should have a single instance, like blocks and items (this + * instance does not usually need to be stored, but you will have to store it if you want to reference a specific + * spell directly, for example transportation requires an accessible instance for printing of chat messages). + * Spells must be registered in the preInit method in your main mod class for them to be added to the config + * file automatically. + * + * @param spell The spell instance to register + * @throws NullPointerException if the passed in spell is null (why would you ever do that?). + */ + public static void register(Spell spell){ + if(spell == null){ + // If the null value was added to the list, it would cause an NPE later when it tries to sort the list. + // If the null value was ignored and not added, there would be no record of what went wrong. + // Therefore the best way is to throw an NPE here so whoever caused it knows why it went wrong. + throw new NullPointerException("Tried to register a spell, but the passed in spell was null."); + }else{ + spellsList.add(spell); + if(!(spell instanceof None)) unlocalisedNames.add(spell.unlocalisedName); + } + } + + /** Called from the postInit method in the main wizardry class to sort all the spells. + *

    Deprecated in favour of sorting the books and scrolls themselves in the creative tab. */ + @Deprecated + public static void sortSpells(){ + Collections.sort(spellsList); + } + /** Returns the total number of registered spells, excluding the 'None' spell. Returns the same number that would * be returned by Spell.getSpells(Spell.allSpells).size(), but this method is more efficient. */ public static int getTotalSpellCount(){ - return registry.getValues().size() - 1; + return spellsList.size() - 1; } - /** Gets a spell instance from its integer id, which now corresponds to its id in the spell registry. + /** Gets a spell instance from its integer id, which now corresponds to its position in the spells ArrayList. * If the given id has no spell (i.e. is less than 0 or greater than the total number of spells - 1) * then it will return the {@link None} spell. *

    - * If you are calling this from inside a loop in which you are iterating through the spells, there is - * probably a better way; see {@link Spell#getSpells(Predicate)}. */ + * If you are calling this from inside a loop in which you are iterating through the spells, there is + * probably a better way; see {@link Spell#getSpells(Filter)}. */ public static Spell get(int id){ - if(id < 0 || id >= registry.getValues().size()){ - return Spells.none; + return id < 0 || id >= spellsList.size() ? WizardryRegistry.none : spellsList.get(id); + } + + /** Returns the spell with the given unlocalised name, or null if no such spell exists. */ + public static Spell get(String unlocalisedName){ + for(Spell spell : Spell.getSpells(allSpells)){ + if(spell.unlocalisedName.equals(unlocalisedName)){ + return spell; + } } - Spell spell = registry.getValues().get(id); - return spell == null ? Spells.none : spell; + return null; } - /** Returns the spell with the given registry name, or null if no such spell exists. - * @param name The registry name of the spell, in the form [mod id]:[spell name]. If no mod id is specified, it - * defaults to {@link Wizardry#MODID}. */ - public static Spell get(String name){ - ResourceLocation key = new ResourceLocation(name); - if(key.getResourceDomain().equals("minecraft")) key = new ResourceLocation(Wizardry.MODID, name); - return registry.getValue(key); + /** Returns a list of all registered spells' unlocalised names, excluding the 'none' spell. Used in commands. */ + public static String[] getUnlocalisedNames(){ + return unlocalisedNames.toArray(new String[unlocalisedNames.size()]); } - /** Returns a list of all registered spells' registry names, excluding the 'none' spell. Used in commands. */ - public static String[] getSpellNames(){ - // Maybe it would be better to store all of this statically? - Set keys = new HashSet(registry.getKeys()); - keys.remove(registry.getKey(Spells.none)); - // Streams! - return keys.stream().map(ResourceLocation::toString).toArray(String[]::new); - } + /* The following method is an example of where I would have liked to use the java 8 predicate and removeIf + * functionality. However, since people don't update their java, I am trying to stick to java 6, annoying as that + * is... so this is the most flexible I can make it within the constraints of java 6. The aim is to remove the need + * to EVER iterate through the spells by id number and use spell.get(id).[condition], because this is cumbersome and + * inefficient and often leads to timeouts. It's far better to restrict the RNG to only the spells you want it + * to select from. Even when you're not using RNG, the for each loop is nicer and more efficient than constantly + * calling Spell.get(i). */ /** - * Returns a list containing all spells matching the given {@link Predicate}. The returned list is separate from the + * Returns a list containing all spells matching the given filter. The returned list is separate from the * internal spells list; any changes you make to the returned list will have no effect on wizardry since the - * returned list is local to this method. Never includes the {@link None} spell. For convenience, there are some - * predefined predicates in the Spell class (some of these really aren't shortcuts any more): + * returned list is local to this method. Never includes the 'none' spell. For convenience, there are some + * predefined filters in the Spell class: *

    * {@link Spell#allSpells} will allow all spells to be returned
    * {@link Spell#enabledSpells} will filter out any spells that are disabled in the config
    @@ -369,40 +358,74 @@ public abstract class Spell extends IForgeRegistryEntry.Impl implements C * {@link Spell#nonContinuousSpells} will filter out continuous spells but not disabled spells
    * {@link Spell.TierElementFilter} will only allow enabled spells of the specified tier and element * - * @param filter A Predicate<Spell> that the returned spells must satisfy. + * @param filter see {@link Spell.Filter} * - * @return A local, modifiable list of spells matching the given predicate. Note that this list may be empty. + * @return A list of spells matching the given filter. Note that this list may be empty. * */ - public static List getSpells(Predicate filter){ + public static List getSpells(Filter filter){ ArrayList spells = new ArrayList(1); - for(Spell spell : registry.getValues()){ - if(filter.test(spell) && spell != Spells.none) spells.add(spell); + for(Spell spell : spellsList){ + if(filter.test(spell) && spell != WizardryRegistry.none) spells.add(spell); } return spells; } - /** Predicate which allows all spells. */ - public static Predicate allSpells = s -> true; + /** To allow Java 6 compatibility, this is defined here instead of using the jdk 8 predicate. Function is exactly + * the same, but specifically for spells. For convenience, there are some predefined filters in the {@link Spell} + * class: + *

    + * {@link Spell#allSpells} will allow all spells to be returned
    + * {@link Spell#enabledSpells} will filter out any spells that are disabled in the config
    + * {@link Spell#npcSpells} will only allow enabled spells that can be cast by NPCs (see {@link Spell#canBeCastByNPCs()})
    + * {@link Spell#nonContinuousSpells} will filter out continuous spells but not disabled spells
    + * {@link Spell.TierElementFilter} will only allow enabled spells of the specified tier and element + *

    + * Edit: Turns out the google stuff has a predicate class. Oh well. */ + public static interface Filter { + public boolean test(Spell spell); + } - /** Predicate which allows all enabled spells. */ - public static Predicate enabledSpells = Spell::isEnabled; + /** Filter which allows all spells. */ + public static Filter allSpells = new Filter(){ + @Override + public boolean test(Spell spell) { + return true; + } + }; - /** Predicate which allows all non-continuous spells, even those that have been disabled. */ - public static Predicate nonContinuousSpells = s -> !s.isContinuous; + /** Filter which allows all enabled spells. */ + public static Filter enabledSpells = new Filter(){ + @Override + public boolean test(Spell spell) { + return spell.isEnabled(); + } + }; - /** Predicate which allows all enabled spells for which {@link Spell#canBeCastByNPCs()} returns true. */ - public static Predicate npcSpells = s -> s.isEnabled() && s.canBeCastByNPCs(); + /** Filter which allows all non-continuous spells, even those that have been disabled. */ + public static Filter nonContinuousSpells = new Filter(){ + @Override + public boolean test(Spell spell) { + return !spell.isContinuous; + } + }; - /** Predicate which allows all enabled spells of the given tier and element (create an instance of this class - * each time you want to use it). This is somewhat useless now that Wizardry uses Java 8, but it is more readable - * than a lambda expression and you don't need to remember to check that the spell is enabled every time. */ - public static class TierElementFilter implements Predicate { + /** Filter which allows all enabled spells for which {@link Spell#canBeCastByNPCs()} returns true. */ + public static Filter npcSpells = new Filter(){ + @Override + public boolean test(Spell spell) { + return spell.isEnabled() && spell.canBeCastByNPCs(); + } + }; + + /** Filter type which allows all enabled spells of the given tier and element (create an instance of this class + * each time you want to use it). */ + public static class TierElementFilter implements Filter { - private Tier tier; - private Element element; + private EnumTier tier; + private EnumElement element; /** * Creates a new TierElementFilter that checks for the given tier and element. Does not allow spells that have @@ -410,7 +433,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl implements C * @param tier The EnumTier to check for. Pass in null to allow all tiers. * @param element The EnumElement to check for. Pass in null to allow all elements. */ - public TierElementFilter(Tier tier, Element element){ + public TierElementFilter(EnumTier tier, EnumElement element){ this.tier = tier; this.element = element; } diff --git a/src/main/java/electroblob/wizardry/spell/SpiderSwarm.java b/src/main/java/electroblob/wizardry/spell/SpiderSwarm.java index a7c6a90a..80356b1a 100644 --- a/src/main/java/electroblob/wizardry/spell/SpiderSwarm.java +++ b/src/main/java/electroblob/wizardry/spell/SpiderSwarm.java @@ -1,25 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.living.EntitySpiderMinion; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; public class SpiderSwarm extends Spell { public SpiderSwarm() { - super(Tier.ADVANCED, 45, Element.EARTH, "spider_swarm", SpellType.MINION, 200, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 45, EnumElement.EARTH, "spider_swarm", EnumSpellType.MINION, 200, EnumAction.bow, false); } @Override @@ -28,43 +22,57 @@ public class SpiderSwarm extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { - + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { + + boolean flag = false; + if(!world.isRemote){ for(int i=0;i<5;i++){ - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 3, 6); - // The spell instantly fails if no space was found (see javadoc for the above method). - if(pos == null) return false; - - EntitySpiderMinion spider = new EntitySpiderMinion(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); - world.spawnEntityInWorld(spider); + double x = caster.posX + world.rand.nextDouble()*6 - 3; + double z = caster.posZ + world.rand.nextDouble()*6 - 3; + // Allows for height variation. + if(world.getTopSolidOrLiquidBlock((int)x, (int)z) - caster.posY < 6){ + flag = true; + double y = Math.max(caster.posY, world.getTopSolidOrLiquidBlock((int)x, (int)z)); + EntitySpiderMinion spider = new EntitySpiderMinion(world, x, y, z, caster, (int)(600*durationMultiplier)); + world.spawnEntityInWorld(spider); + } } } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.BLOCK_FIRE_EXTINGUISH, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); - // Can't possibly get this far if nothing was spawned. - return true; + if(flag){ + world.playSoundAtEntity(caster, "random.fizz", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + } + // If no spiders were spawned (like in a 1x1 hole or something) then the spell does not use up mana. + return flag; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers) { + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { + + boolean flag = false; if(!world.isRemote){ for(int i=0;i<5;i++){ - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 3, 6); - // The spell instantly fails if no space was found (see javadoc for the above method). - if(pos == null) return false; - - EntitySpiderMinion spider = new EntitySpiderMinion(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); - world.spawnEntityInWorld(spider); + double x = caster.posX + world.rand.nextDouble()*6 - 3; + double z = caster.posZ + world.rand.nextDouble()*6 - 3; + // Allows for height variation. + if(world.getTopSolidOrLiquidBlock((int)x, (int)z) - caster.posY < 6){ + flag = true; + double y = Math.max(caster.posY, world.getTopSolidOrLiquidBlock((int)x, (int)z)); + EntitySpiderMinion spider = new EntitySpiderMinion(world, x, y, z, caster, (int)(600*durationMultiplier)); + world.spawnEntityInWorld(spider); + } } } - - caster.playSound(SoundEvents.BLOCK_FIRE_EXTINGUISH, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); - // Can't possibly get this far if nothing was spawned. - return true; + + if(flag){ + world.playSoundAtEntity(caster, "random.fizz", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + } + // If no spiders were spawned (like in a 1x1 hole or something) then the spell does not use up mana. + return flag; } - + @Override public boolean canBeCastByNPCs(){ return true; diff --git a/src/main/java/electroblob/wizardry/spell/StaticAura.java b/src/main/java/electroblob/wizardry/spell/StaticAura.java index 851c260f..2a1f94d1 100644 --- a/src/main/java/electroblob/wizardry/spell/StaticAura.java +++ b/src/main/java/electroblob/wizardry/spell/StaticAura.java @@ -1,25 +1,21 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.Wizardry; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class StaticAura extends Spell { public StaticAura() { - super(Tier.ADVANCED, 40, Element.LIGHTNING, "static_aura", SpellType.DEFENCE, 250, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 40, EnumElement.LIGHTNING, "static_aura", EnumSpellType.DEFENCE, 250, EnumAction.bow, false); } @Override @@ -28,29 +24,29 @@ public class StaticAura extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { // Cannot be cast when it has already been cast - if(!caster.isPotionActive(WizardryPotions.static_aura)){ + if(!caster.isPotionActive(Wizardry.staticAura)){ if(!world.isRemote){ - caster.addPotionEffect(new PotionEffect(WizardryPotions.static_aura, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 0)); + caster.addPotionEffect(new PotionEffect(Wizardry.staticAura.id, (int)(600*durationMultiplier), 0, true)); + world.playSoundAtEntity(caster, "wizardry:arc", 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); return true; } return false; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers) { + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(target != null){ // Cannot be cast when it has already been cast - if(!caster.isPotionActive(WizardryPotions.static_aura)){ + if(!caster.isPotionActive(Wizardry.staticAura)){ if(!world.isRemote){ - caster.addPotionEffect(new PotionEffect(WizardryPotions.static_aura, (int)(600*modifiers.get(WizardryItems.duration_upgrade)), 0)); + caster.addPotionEffect(new PotionEffect(Wizardry.staticAura.id, (int)(600*durationMultiplier), 0, true)); + world.playSoundAtEntity(caster, "wizardry:arc", 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); } - caster.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.4F); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/SummonBlaze.java b/src/main/java/electroblob/wizardry/spell/SummonBlaze.java index 3882eae8..e191fa32 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonBlaze.java +++ b/src/main/java/electroblob/wizardry/spell/SummonBlaze.java @@ -1,25 +1,22 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntityBlazeMinion; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; public class SummonBlaze extends Spell { public SummonBlaze() { - super(Tier.ADVANCED, 40, Element.FIRE, "summon_blaze", SpellType.MINION, 200, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 40, EnumElement.FIRE, "summon_blaze", EnumSpellType.MINION, 200, EnumAction.bow, false); } @Override @@ -28,34 +25,44 @@ public class SummonBlaze extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; - - EntityBlazeMinion blaze = new EntityBlazeMinion(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); + EntityBlazeMinion blaze = new EntityBlazeMinion(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) blaze.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), blaze.getCommandSenderName())); world.spawnEntityInWorld(blaze); } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_AMBIENT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "mob.wither.idle", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(!world.isRemote){ + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; - - EntityBlazeMinion blaze = new EntityBlazeMinion(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); + EntityBlazeMinion blaze = new EntityBlazeMinion(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) blaze.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), blaze.getCommandSenderName())); world.spawnEntityInWorld(blaze); } - caster.playSound(SoundEvents.ENTITY_WITHER_AMBIENT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "mob.wither.idle", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/SummonIceGiant.java b/src/main/java/electroblob/wizardry/spell/SummonIceGiant.java index 26e986f8..843e81d7 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonIceGiant.java +++ b/src/main/java/electroblob/wizardry/spell/SummonIceGiant.java @@ -1,49 +1,52 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntityIceGiant; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; public class SummonIceGiant extends Spell { public SummonIceGiant() { - super(Tier.MASTER, 100, Element.ICE, "summon_ice_giant", SpellType.MINION, 400, EnumAction.BOW, false); + super(EnumTier.MASTER, 100, EnumElement.ICE, "summon_ice_giant", EnumSpellType.MINION, 400, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { + + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; - if(!world.isRemote){ - - EntityIceGiant icegiant = new EntityIceGiant(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); + EntityIceGiant icegiant = new EntityIceGiant(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) icegiant.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), icegiant.getCommandSenderName())); world.spawnEntityInWorld(icegiant); } - if(world.isRemote){ - for(int i=0; i<10; i++){ - double x1 = (double)((float)pos.getX() + world.rand.nextFloat()*2 - 1.0F); - double y1 = (double)((float)pos.getY() + 0.5F + world.rand.nextFloat()); - double z1 = (double)((float)pos.getZ() + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0, 0, 48 + world.rand.nextInt(12), 0.6f, 0.6f, 1.0f); + for(int i=0; i<10; i++){ + double x1 = (double)((float)x + world.rand.nextFloat()*2 - 1.0F); + double y1 = (double)((float)y + 0.5F + world.rand.nextFloat()); + double z1 = (double)((float)z + world.rand.nextFloat()*2 - 1.0F); + if(world.isRemote){ + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0, 0, 48 + world.rand.nextInt(12), 0.6f, 0.6f, 1.0f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, world.rand.nextFloat() * 0.1F + 0.2F); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, world.rand.nextFloat() * 0.1F + 0.2F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/SummonIceWraith.java b/src/main/java/electroblob/wizardry/spell/SummonIceWraith.java index 6f914344..6c0346ad 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonIceWraith.java +++ b/src/main/java/electroblob/wizardry/spell/SummonIceWraith.java @@ -1,25 +1,22 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntityIceWraith; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; public class SummonIceWraith extends Spell { public SummonIceWraith() { - super(Tier.ADVANCED, 40, Element.ICE, "summon_ice_wraith", SpellType.MINION, 200, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 40, EnumElement.ICE, "summon_ice_wraith", EnumSpellType.MINION, 200, EnumAction.bow, false); } @Override @@ -28,33 +25,42 @@ public class SummonIceWraith extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; - - EntityIceWraith iceWraith = new EntityIceWraith(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); + EntityIceWraith iceWraith = new EntityIceWraith(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) iceWraith.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), iceWraith.getCommandSenderName())); world.spawnEntityInWorld(iceWraith); } - - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_AMBIENT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "mob.wither.idle", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(!world.isRemote){ + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; - - EntityIceWraith iceWraith = new EntityIceWraith(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); + EntityIceWraith iceWraith = new EntityIceWraith(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) iceWraith.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), iceWraith.getCommandSenderName())); world.spawnEntityInWorld(iceWraith); } - caster.playSound(SoundEvents.ENTITY_WITHER_AMBIENT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "mob.wither.idle", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/SummonIronGolem.java b/src/main/java/electroblob/wizardry/spell/SummonIronGolem.java index 4f510f4d..6b665b3c 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonIronGolem.java +++ b/src/main/java/electroblob/wizardry/spell/SummonIronGolem.java @@ -1,48 +1,51 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.monster.EntityIronGolem; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; public class SummonIronGolem extends Spell { public SummonIronGolem() { - super(Tier.MASTER, 175, Element.SORCERY, "summon_iron_golem", SpellType.MINION, 400, EnumAction.BOW, false); + super(EnumTier.MASTER, 175, EnumElement.SORCERY, "summon_iron_golem", EnumSpellType.MINION, 400, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); + if(!world.isRemote){ EntityIronGolem golem = new EntityIronGolem(world); - golem.setPosition(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5); + if(Wizardry.showSummonedCreatureNames) golem.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), golem.getCommandSenderName())); + golem.setPosition(x, y, z); world.spawnEntityInWorld(golem); } - for(int i=0; i<10; i++){ - double x1 = (double)((float)pos.getX() + world.rand.nextFloat()*2 - 1.0F); - double y1 = (double)((float)pos.getY() + 0.5F + world.rand.nextFloat()); - double z1 = (double)((float)pos.getZ() + world.rand.nextFloat()*2 - 1.0F); + double x1 = (double)((float)x + world.rand.nextFloat()*2 - 1.0F); + double y1 = (double)((float)y + 0.5F + world.rand.nextFloat()); + double z1 = (double)((float)z + world.rand.nextFloat()*2 - 1.0F); if(world.isRemote){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0, 0, 48 + world.rand.nextInt(12), 0.6f, 0.6f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0, 0, 48 + world.rand.nextInt(12), 0.6f, 0.6f, 1.0f); } } - - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SPAWN, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "mob.wither.spawn", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/SummonLightningWraith.java b/src/main/java/electroblob/wizardry/spell/SummonLightningWraith.java index 6c74adf1..654dd0fe 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonLightningWraith.java +++ b/src/main/java/electroblob/wizardry/spell/SummonLightningWraith.java @@ -1,25 +1,22 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntityLightningWraith; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; public class SummonLightningWraith extends Spell { public SummonLightningWraith() { - super(Tier.ADVANCED, 40, Element.LIGHTNING, "summon_lightning_wraith", SpellType.MINION, 200, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 40, EnumElement.LIGHTNING, "summon_lightning_wraith", EnumSpellType.MINION, 200, EnumAction.bow, false); } @Override @@ -28,32 +25,42 @@ public class SummonLightningWraith extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; - - EntityLightningWraith lightningWraith = new EntityLightningWraith(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); + EntityLightningWraith lightningWraith = new EntityLightningWraith(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) lightningWraith.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), lightningWraith.getCommandSenderName())); world.spawnEntityInWorld(lightningWraith); } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_AMBIENT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "mob.wither.idle", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(!world.isRemote){ - - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); - EntityLightningWraith lightningWraith = new EntityLightningWraith(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); + EntityLightningWraith lightningWraith = new EntityLightningWraith(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) lightningWraith.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), lightningWraith.getCommandSenderName())); world.spawnEntityInWorld(lightningWraith); } - caster.playSound(SoundEvents.ENTITY_WITHER_AMBIENT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "mob.wither.idle", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/SummonPhoenix.java b/src/main/java/electroblob/wizardry/spell/SummonPhoenix.java index 5dc24a07..65d144ff 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonPhoenix.java +++ b/src/main/java/electroblob/wizardry/spell/SummonPhoenix.java @@ -1,23 +1,20 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntityPhoenix; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; public class SummonPhoenix extends Spell { public SummonPhoenix() { - super(Tier.MASTER, 150, Element.FIRE, "summon_phoenix", SpellType.MINION, 400, EnumAction.BOW, false); + super(EnumTier.MASTER, 150, EnumElement.FIRE, "summon_phoenix", EnumSpellType.MINION, 400, EnumAction.bow, false); } @Override @@ -26,19 +23,23 @@ public class SummonPhoenix extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); - EntityPhoenix phoenix = new EntityPhoenix(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, - (int)(600*modifiers.get(WizardryItems.duration_upgrade))); + EntityPhoenix phoenix = new EntityPhoenix(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) phoenix.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), phoenix.getCommandSenderName())); world.spawnEntityInWorld(phoenix); } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_AMBIENT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "mob.wither.idle", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/SummonShadowWraith.java b/src/main/java/electroblob/wizardry/spell/SummonShadowWraith.java index 621cfeab..cfdc539e 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonShadowWraith.java +++ b/src/main/java/electroblob/wizardry/spell/SummonShadowWraith.java @@ -1,25 +1,20 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntityShadowWraith; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; public class SummonShadowWraith extends Spell { public SummonShadowWraith() { - super(Tier.MASTER, 100, Element.NECROMANCY, "summon_shadow_wraith", SpellType.MINION, 400, EnumAction.BOW, false); + super(EnumTier.MASTER, 100, EnumElement.NECROMANCY, "summon_shadow_wraith", EnumSpellType.MINION, 400, EnumAction.bow, false); } @Override @@ -28,21 +23,25 @@ public class SummonShadowWraith extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); - EntityShadowWraith shadowWraith = new EntityShadowWraith(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); + EntityShadowWraith shadowWraith = new EntityShadowWraith(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) shadowWraith.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), shadowWraith.getCommandSenderName())); world.spawnEntityInWorld(shadowWraith); } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_AMBIENT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "mob.wither.idle", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } - @SideOnly(Side.CLIENT) @Override public String getDescription(){ return "\u00A7k" + super.getDescription(); diff --git a/src/main/java/electroblob/wizardry/spell/SummonSkeleton.java b/src/main/java/electroblob/wizardry/spell/SummonSkeleton.java index 7c086e9f..4c901d57 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonSkeleton.java +++ b/src/main/java/electroblob/wizardry/spell/SummonSkeleton.java @@ -1,28 +1,24 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntitySkeletonMinion; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; -import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; public class SummonSkeleton extends Spell { public SummonSkeleton() { - super(Tier.APPRENTICE, 15, Element.NECROMANCY, "summon_skeleton", SpellType.MINION, 50, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 15, EnumElement.NECROMANCY, "summon_skeleton", EnumSpellType.MINION, 50, EnumAction.bow, false); } @Override @@ -31,36 +27,46 @@ public class SummonSkeleton extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); - EntitySkeletonMinion skeleton = new EntitySkeletonMinion(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); - skeleton.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.BOW)); - skeleton.setDropChance(EntityEquipmentSlot.MAINHAND, 0.0f); + EntitySkeletonMinion skeleton = new EntitySkeletonMinion(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) skeleton.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), skeleton.getCommandSenderName())); + skeleton.setCurrentItemOrArmor(0, new ItemStack(Items.bow)); + skeleton.setEquipmentDropChance(0, 0.0f); world.spawnEntityInWorld(skeleton); } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SUMMONING, 7.0f, 0.6f); + world.playSoundAtEntity(caster, "wizardry:darkaura", 7.0f, 0.6f); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(!world.isRemote){ - - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); - EntitySkeletonMinion skeleton = new EntitySkeletonMinion(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); - skeleton.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.BOW)); - skeleton.setDropChance(EntityEquipmentSlot.MAINHAND, 0.0f); + EntitySkeletonMinion skeleton = new EntitySkeletonMinion(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) skeleton.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), skeleton.getCommandSenderName())); + skeleton.setCurrentItemOrArmor(0, new ItemStack(Items.bow)); + skeleton.setEquipmentDropChance(0, 0.0f); world.spawnEntityInWorld(skeleton); } - caster.playSound(WizardrySounds.SPELL_SUMMONING, 7.0f, 0.6f); + world.playSoundAtEntity(caster, "wizardry:darkaura", 7.0f, 0.6f); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/SummonSkeletonLegion.java b/src/main/java/electroblob/wizardry/spell/SummonSkeletonLegion.java index 69a373ff..38ba20d9 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonSkeletonLegion.java +++ b/src/main/java/electroblob/wizardry/spell/SummonSkeletonLegion.java @@ -1,26 +1,21 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; import electroblob.wizardry.entity.living.EntitySkeletonMinion; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; -import net.minecraft.init.SoundEvents; -import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; public class SummonSkeletonLegion extends Spell { public SummonSkeletonLegion() { - super(Tier.MASTER, 100, Element.NECROMANCY, "summon_skeleton_legion", SpellType.MINION, 400, EnumAction.BOW, false); + super(EnumTier.MASTER, 100, EnumElement.NECROMANCY, "summon_skeleton_legion", EnumSpellType.MINION, 400, EnumAction.bow, false); } @Override @@ -29,46 +24,56 @@ public class SummonSkeletonLegion extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { - + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { + + boolean flag = false; + if(!world.isRemote){ - // Archers for(int i=0;i<3;i++){ - // This is all so much neater now thanks to this method. - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 3, 6); - // The spell instantly fails if no space was found (see javadoc for the above method). - if(pos == null) return false; - - EntitySkeletonMinion skeleton = new EntitySkeletonMinion(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(1200*modifiers.get(WizardryItems.duration_upgrade))); - skeleton.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.BOW)); - skeleton.setItemStackToSlot(EntityEquipmentSlot.HEAD, new ItemStack(Items.CHAINMAIL_HELMET)); - skeleton.setItemStackToSlot(EntityEquipmentSlot.CHEST, new ItemStack(Items.CHAINMAIL_CHESTPLATE)); - skeleton.setDropChance(EntityEquipmentSlot.MAINHAND, 0.0f); - skeleton.setDropChance(EntityEquipmentSlot.HEAD, 0.0f); - skeleton.setDropChance(EntityEquipmentSlot.CHEST, 0.0f); - world.spawnEntityInWorld(skeleton); + double x = caster.posX + world.rand.nextDouble()*6 - 3; + double z = caster.posZ + world.rand.nextDouble()*6 - 3; + // Allows for height variation. + if(world.getTopSolidOrLiquidBlock((int)x, (int)z) - caster.posY < 6){ + flag = true; + double y = Math.max(caster.posY, world.getTopSolidOrLiquidBlock((int)x, (int)z)); + EntitySkeletonMinion skeleton = new EntitySkeletonMinion(world, x, y, z, caster, (int)(1200*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) skeleton.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), skeleton.getCommandSenderName())); + skeleton.setCurrentItemOrArmor(0, new ItemStack(Items.bow)); + skeleton.setCurrentItemOrArmor(4, new ItemStack(Items.chainmail_helmet)); + skeleton.setCurrentItemOrArmor(3, new ItemStack(Items.chainmail_chestplate)); + skeleton.setEquipmentDropChance(0, 0.0f); + skeleton.setEquipmentDropChance(3, 0.0f); + skeleton.setEquipmentDropChance(4, 0.0f); + world.spawnEntityInWorld(skeleton); + } } - // Swordsmen + for(int i=0;i<3;i++){ - - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 3, 6); - // The spell instantly fails if no space was found (see javadoc for the above method). - if(pos == null) return false; - - EntitySkeletonMinion skeleton = new EntitySkeletonMinion(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(1200*modifiers.get(WizardryItems.duration_upgrade))); - skeleton.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.IRON_SWORD)); - skeleton.setItemStackToSlot(EntityEquipmentSlot.HEAD, new ItemStack(Items.CHAINMAIL_HELMET)); - skeleton.setItemStackToSlot(EntityEquipmentSlot.CHEST, new ItemStack(Items.CHAINMAIL_CHESTPLATE)); - skeleton.setDropChance(EntityEquipmentSlot.MAINHAND, 0.0f); - skeleton.setDropChance(EntityEquipmentSlot.HEAD, 0.0f); - skeleton.setDropChance(EntityEquipmentSlot.CHEST, 0.0f); - world.spawnEntityInWorld(skeleton); + double x = caster.posX + world.rand.nextDouble()*6 - 3; + double z = caster.posZ + world.rand.nextDouble()*6 - 3; + // Allows for height variation. + if(world.getTopSolidOrLiquidBlock((int)x, (int)z) - caster.posY < 6){ + flag = true; + double y = Math.max(caster.posY, world.getTopSolidOrLiquidBlock((int)x, (int)z)); + EntitySkeletonMinion skeleton = new EntitySkeletonMinion(world, x, y, z, caster, (int)(1200*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) skeleton.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), skeleton.getCommandSenderName())); + skeleton.setCurrentItemOrArmor(0, new ItemStack(Items.iron_sword)); + skeleton.setCurrentItemOrArmor(4, new ItemStack(Items.chainmail_helmet)); + skeleton.setCurrentItemOrArmor(3, new ItemStack(Items.chainmail_chestplate)); + skeleton.setEquipmentDropChance(0, 0.0f); + skeleton.setEquipmentDropChance(3, 0.0f); + skeleton.setEquipmentDropChance(4, 0.0f); + world.spawnEntityInWorld(skeleton); + } } } - // Can't possibly get this far if nothing was spawned. - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SPAWN, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); - return true; + if(flag){ + world.playSoundAtEntity(caster, "mob.wither.spawn", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + } + + // If no skeletons were spawned (like in a 1x1 hole or something) then the spell does not use up mana. + return flag; } diff --git a/src/main/java/electroblob/wizardry/spell/SummonSnowGolem.java b/src/main/java/electroblob/wizardry/spell/SummonSnowGolem.java index 7867c74a..37818847 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonSnowGolem.java +++ b/src/main/java/electroblob/wizardry/spell/SummonSnowGolem.java @@ -1,46 +1,50 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.monster.EntitySnowman; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; public class SummonSnowGolem extends Spell { public SummonSnowGolem() { - super(Tier.APPRENTICE, 15, Element.ICE, "summon_snow_golem", SpellType.MINION, 20, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 15, EnumElement.ICE, "summon_snow_golem", EnumSpellType.MINION, 20, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y2 = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); if(!world.isRemote){ EntitySnowman snowman = new EntitySnowman(world); - snowman.setPosition(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5); + if(Wizardry.showSummonedCreatureNames) snowman.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), snowman.getCommandSenderName())); + snowman.setPosition(x, y2, z); world.spawnEntityInWorld(snowman); } for(int i=0; i<10; i++){ - double x1 = (double)((float)pos.getX() + world.rand.nextFloat()*2 - 1.0F); - double y1 = (double)((float)pos.getY() + 0.5F + world.rand.nextFloat()); - double z1 = (double)((float)pos.getZ() + world.rand.nextFloat()*2 - 1.0F); + double x1 = (double)((float)x + world.rand.nextFloat()*2 - 1.0F); + double y1 = (double)((float)y2 + 0.5F + world.rand.nextFloat()); + double z1 = (double)((float)z + world.rand.nextFloat()*2 - 1.0F); if(world.isRemote){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.6f, 0.6f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.6f, 0.6f, 1.0f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/SummonSpiritHorse.java b/src/main/java/electroblob/wizardry/spell/SummonSpiritHorse.java index 277bc15c..6579ef94 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonSpiritHorse.java +++ b/src/main/java/electroblob/wizardry/spell/SummonSpiritHorse.java @@ -1,23 +1,21 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.WizardData; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntitySpiritHorse; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; public class SummonSpiritHorse extends Spell { public SummonSpiritHorse() { - super(Tier.ADVANCED, 50, Element.EARTH, "summon_spirit_horse", SpellType.MINION, 150, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 50, EnumElement.EARTH, "summon_spirit_horse", EnumSpellType.MINION, 150, EnumAction.bow, false); } @Override @@ -26,24 +24,29 @@ public class SummonSpiritHorse extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - WizardData properties = WizardData.get(caster); + ExtendedPlayer properties = ExtendedPlayer.get(caster); if(!properties.hasSpiritHorse){ if(!world.isRemote){ - - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; + double x1 = caster.posX + world.rand.nextDouble()*4 - 2; + double z1 = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x1, (int)caster.posY, (int)z1, 5) == -1){ + return false; + } + double y1 = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x1, (int)caster.posY, (int)z1, 5)); EntitySpiritHorse horse = new EntitySpiritHorse(world); - horse.setPosition(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5); + if(Wizardry.showSummonedCreatureNames) horse.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), horse.getCommandSenderName())); + horse.setPosition(x1, y1, z1); horse.setTamedBy(caster); horse.setHorseSaddled(true); world.spawnEntityInWorld(horse); } properties.hasSpiritHorse = true; - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/SummonSpiritWolf.java b/src/main/java/electroblob/wizardry/spell/SummonSpiritWolf.java index a7285484..1d0ce482 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonSpiritWolf.java +++ b/src/main/java/electroblob/wizardry/spell/SummonSpiritWolf.java @@ -1,23 +1,23 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.WizardData; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntitySpiritWolf; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; public class SummonSpiritWolf extends Spell { public SummonSpiritWolf() { - super(Tier.APPRENTICE, 25, Element.EARTH, "summon_spirit_wolf", SpellType.MINION, 100, EnumAction.BOW, false); + super(EnumTier.APPRENTICE, 25, EnumElement.EARTH, "summon_spirit_wolf", EnumSpellType.MINION, 100, EnumAction.bow, false); } @Override @@ -26,24 +26,29 @@ public class SummonSpiritWolf extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - WizardData properties = WizardData.get(caster); + ExtendedPlayer properties = ExtendedPlayer.get(caster); if(!properties.hasSpiritWolf){ if(!world.isRemote){ - - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; + double x1 = caster.posX + world.rand.nextDouble()*4 - 2; + double z1 = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x1, (int)caster.posY, (int)z1, 5) == -1){ + return false; + } + double y1 = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x1, (int)caster.posY, (int)z1, 5)); EntitySpiritWolf wolf = new EntitySpiritWolf(world); - wolf.setPosition(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5); + if(Wizardry.showSummonedCreatureNames) wolf.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), wolf.getCommandSenderName())); + wolf.setPosition(x1, y1, z1); wolf.setTamed(true); - wolf.setOwnerId(caster.getUniqueID()); + wolf.func_152115_b(caster.getUniqueID().toString()); world.spawnEntityInWorld(wolf); } properties.hasSpiritWolf = true; - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } return false; diff --git a/src/main/java/electroblob/wizardry/spell/SummonStormElemental.java b/src/main/java/electroblob/wizardry/spell/SummonStormElemental.java index 2e61aa45..8796ff9c 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonStormElemental.java +++ b/src/main/java/electroblob/wizardry/spell/SummonStormElemental.java @@ -1,23 +1,20 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntityStormElemental; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; public class SummonStormElemental extends Spell { public SummonStormElemental() { - super(Tier.MASTER, 100, Element.LIGHTNING, "summon_storm_elemental", SpellType.MINION, 400, EnumAction.BOW, false); + super(EnumTier.MASTER, 100, EnumElement.LIGHTNING, "summon_storm_elemental", EnumSpellType.MINION, 400, EnumAction.bow, false); } @Override @@ -26,17 +23,22 @@ public class SummonStormElemental extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); - EntityStormElemental stormElemental = new EntityStormElemental(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); + EntityStormElemental stormElemental = new EntityStormElemental(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) stormElemental.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), stormElemental.getCommandSenderName())); world.spawnEntityInWorld(stormElemental); } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_AMBIENT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "mob.wither.idle", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } } diff --git a/src/main/java/electroblob/wizardry/spell/SummonWitherSkeleton.java b/src/main/java/electroblob/wizardry/spell/SummonWitherSkeleton.java index d8b6c22a..506328d8 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonWitherSkeleton.java +++ b/src/main/java/electroblob/wizardry/spell/SummonWitherSkeleton.java @@ -1,29 +1,24 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntitySkeletonMinion; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.monster.SkeletonType; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Items; -import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.item.EnumAction; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; public class SummonWitherSkeleton extends Spell { public SummonWitherSkeleton() { - super(Tier.ADVANCED, 35, Element.NECROMANCY, "summon_wither_skeleton", SpellType.MINION, 150, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 35, EnumElement.NECROMANCY, "summon_wither_skeleton", EnumSpellType.MINION, 150, EnumAction.bow, false); } @Override @@ -32,38 +27,48 @@ public class SummonWitherSkeleton extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); - EntitySkeletonMinion skeleton = new EntitySkeletonMinion(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); - skeleton.setSkeletonType(SkeletonType.WITHER); - skeleton.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.STONE_SWORD)); - skeleton.setDropChance(EntityEquipmentSlot.MAINHAND, 0.0f); + EntitySkeletonMinion skeleton = new EntitySkeletonMinion(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) skeleton.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), skeleton.getCommandSenderName())); + skeleton.setSkeletonType(1); + skeleton.setCurrentItemOrArmor(0, new ItemStack(Items.stone_sword)); + skeleton.setEquipmentDropChance(0, 0.0f); world.spawnEntityInWorld(skeleton); } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SUMMONING, 7.0f, 0.6f); + world.playSoundAtEntity(caster, "wizardry:darkaura", 7.0f, 0.6f); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(!world.isRemote){ - - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); - EntitySkeletonMinion skeleton = new EntitySkeletonMinion(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); - skeleton.setSkeletonType(SkeletonType.WITHER); - skeleton.setItemStackToSlot(EntityEquipmentSlot.MAINHAND, new ItemStack(Items.STONE_SWORD)); - skeleton.setDropChance(EntityEquipmentSlot.MAINHAND, 0.0f); + EntitySkeletonMinion skeleton = new EntitySkeletonMinion(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) skeleton.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), skeleton.getCommandSenderName())); + skeleton.setSkeletonType(1); + skeleton.setCurrentItemOrArmor(0, new ItemStack(Items.stone_sword)); + skeleton.setEquipmentDropChance(0, 0.0f); world.spawnEntityInWorld(skeleton); } - caster.playSound(WizardrySounds.SPELL_SUMMONING, 7.0f, 0.6f); + world.playSoundAtEntity(caster, "wizardry:darkaura", 7.0f, 0.6f); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/SummonZombie.java b/src/main/java/electroblob/wizardry/spell/SummonZombie.java index 21718a87..8d487ff3 100644 --- a/src/main/java/electroblob/wizardry/spell/SummonZombie.java +++ b/src/main/java/electroblob/wizardry/spell/SummonZombie.java @@ -1,25 +1,22 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.Wizardry; +import electroblob.wizardry.WizardryUtilities; import electroblob.wizardry.entity.living.EntityZombieMinion; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.StatCollector; import net.minecraft.world.World; public class SummonZombie extends Spell { public SummonZombie() { - super(Tier.BASIC, 10, Element.NECROMANCY, "summon_zombie", SpellType.MINION, 40, EnumAction.BOW, false); + super(EnumTier.BASIC, 10, EnumElement.NECROMANCY, "summon_zombie", EnumSpellType.MINION, 40, EnumAction.bow, false); } @Override @@ -28,31 +25,40 @@ public class SummonZombie extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; - EntityZombieMinion zombie = new EntityZombieMinion(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); + EntityZombieMinion zombie = new EntityZombieMinion(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) zombie.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), zombie.getCommandSenderName())); world.spawnEntityInWorld(zombie); } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_SUMMONING, 7.0f, 0.6f); + world.playSoundAtEntity(caster, "wizardry:darkaura", 7.0f, 0.6f); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(!world.isRemote){ - - BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, 2, 4); - if(pos == null) return false; - - EntityZombieMinion zombie = new EntityZombieMinion(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, caster, (int)(600*modifiers.get(WizardryItems.duration_upgrade))); + double x = caster.posX + world.rand.nextDouble()*4 - 2; + double z = caster.posZ + world.rand.nextDouble()*4 - 2; + // Allows for height variation. + if(WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5) == -1){ + return false; + } + double y = Math.max(caster.posY, WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 5)); + EntityZombieMinion zombie = new EntityZombieMinion(world, x, y, z, caster, (int)(600*durationMultiplier)); + if(Wizardry.showSummonedCreatureNames) zombie.setCustomNameTag(StatCollector.translateToLocalFormatted("entity.wizardry.summonedcreature.nameplate", caster.getCommandSenderName(), zombie.getCommandSenderName())); world.spawnEntityInWorld(zombie); } - caster.playSound(WizardrySounds.SPELL_SUMMONING, 7.0f, 0.6f); + world.playSoundAtEntity(caster, "wizardry:darkaura", 7.0f, 0.6f); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Telekinesis.java b/src/main/java/electroblob/wizardry/spell/Telekinesis.java index d46608ea..9b079a95 100644 --- a/src/main/java/electroblob/wizardry/spell/Telekinesis.java +++ b/src/main/java/electroblob/wizardry/spell/Telekinesis.java @@ -1,29 +1,25 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.block.state.IBlockState; +import electroblob.wizardry.WizardryUtilities; +import net.minecraft.block.Block; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.world.World; public class Telekinesis extends Spell { public Telekinesis() { - super(Tier.BASIC, 5, Element.SORCERY, "telekinesis", SpellType.UTILITY, 5, EnumAction.NONE, false); + super(EnumTier.BASIC, 5, EnumElement.SORCERY, "telekinesis", EnumSpellType.UTILITY, 5, EnumAction.none, false); } @Override @@ -32,9 +28,9 @@ public class Telekinesis extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 8*modifiers.get(WizardryItems.range_upgrade), 3.0f); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 8*rangeMultiplier, 3.0f); if(rayTrace != null && rayTrace.entityHit != null){ @@ -44,62 +40,55 @@ public class Telekinesis extends Spell { entityHit.motionX = (caster.posX - entityHit.posX)/6; entityHit.motionY = (caster.posY + caster.eyeHeight - entityHit.posY)/6; entityHit.motionZ = (caster.posZ - entityHit.posZ)/6; - entityHit.playSound(WizardrySounds.SPELL_CONJURATION, 1.0F, 1.0f); - caster.swingArm(hand); + world.playSoundAtEntity(entityHit, "wizardry:aura", 1.0F, 1.0f); + caster.swingItem(); return true; - }else if(rayTrace.entityHit instanceof EntityPlayer && Wizardry.settings.telekineticDisarmament){ + }else if(rayTrace.entityHit instanceof EntityPlayer && Wizardry.telekineticDisarmament){ EntityPlayer target = (EntityPlayer)rayTrace.entityHit; - if(target.getHeldItemMainhand() != null){ + if(target.getHeldItem() != null){ if(!world.isRemote){ - EntityItem item = target.entityDropItem(target.getHeldItemMainhand(), 0.0f); + EntityItem item = target.entityDropItem(target.getHeldItem(), 0.0f); // Makes the item move towards the caster item.motionX = (caster.posX - target.posX)/20; item.motionZ = (caster.posZ - target.posZ)/20; } - - target.setHeldItem(EnumHand.MAIN_HAND, null); + target.setCurrentItemOrArmor(0, null); - target.playSound(WizardrySounds.SPELL_CONJURATION, 1.0F, 1.0f); - caster.swingArm(hand); + world.playSoundAtEntity(target, "wizardry:aura", 1.0F, 1.0f); + caster.swingItem(); return true; } } } - - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){ - - IBlockState blockstate = world.getBlockState(new BlockPos(rayTrace.getBlockPos())); - - if(blockstate.getBlock().onBlockActivated(world, rayTrace.getBlockPos(), blockstate, caster, hand, null, rayTrace.sideHit, 0, 0, 0)){ - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0F, 1.0f); - caster.swingArm(hand); + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.BLOCK){ + Block block = world.getBlock(rayTrace.blockX, rayTrace.blockY, rayTrace.blockZ); + if(block.onBlockActivated(world, rayTrace.blockX, rayTrace.blockY, rayTrace.blockZ, caster, 0, 0, 0, 0)){ + world.playSound(rayTrace.blockX, rayTrace.blockY, rayTrace.blockZ, "wizardry:aura", 1.0F, 1.0f, false); + caster.swingItem(); return true; } } return false; } - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ - if(target instanceof EntityPlayer && target.getHeldItemMainhand() != null){ + if(target instanceof EntityPlayer && target.getHeldItem() != null){ - // IDEA: Disarm the offhand if the mainhand is empty or otherwise harmless? - if(!world.isRemote){ - EntityItem item = target.entityDropItem(target.getHeldItemMainhand(), 0.0f); + EntityItem item = target.entityDropItem(target.getHeldItem(), 0.0f); // Makes the item move towards the caster item.motionX = (caster.posX - target.posX)/20; item.motionZ = (caster.posZ - target.posZ)/20; } - - target.setHeldItem(EnumHand.MAIN_HAND, null); + target.setCurrentItemOrArmor(0, null); - target.playSound(WizardrySounds.SPELL_CONJURATION, 1.0F, 1.0f); - caster.swingArm(hand); + world.playSoundAtEntity(target, "wizardry:aura", 1.0F, 1.0f); + caster.swingItem(); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Thunderbolt.java b/src/main/java/electroblob/wizardry/spell/Thunderbolt.java index a146975f..7ea6aa5b 100644 --- a/src/main/java/electroblob/wizardry/spell/Thunderbolt.java +++ b/src/main/java/electroblob/wizardry/spell/Thunderbolt.java @@ -1,23 +1,19 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.projectile.EntityThunderbolt; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class Thunderbolt extends Spell { public Thunderbolt() { - super(Tier.BASIC, 10, Element.LIGHTNING, "thunderbolt", SpellType.ATTACK, 15, EnumAction.NONE, false); + super(EnumTier.BASIC, 10, EnumElement.LIGHTNING, "thunderbolt", EnumSpellType.ATTACK, 15, EnumAction.none, false); } @Override @@ -26,31 +22,31 @@ public class Thunderbolt extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ - EntityThunderbolt thunderbolt = new EntityThunderbolt(world, caster, modifiers.get(SpellModifiers.DAMAGE)); + EntityThunderbolt thunderbolt = new EntityThunderbolt(world, caster, damageMultiplier); world.spawnEntityInWorld(thunderbolt); + world.playSoundAtEntity(caster, "wizardry:ice", 0.8F, world.rand.nextFloat() * 0.2F + 0.8F); } - - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 0.8F, world.rand.nextFloat() * 0.2F + 0.8F); - caster.swingArm(hand); + + caster.swingItem(); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ if(!world.isRemote){ - EntityThunderbolt thunderbolt = new EntityThunderbolt(world, caster, modifiers.get(SpellModifiers.DAMAGE)); + EntityThunderbolt thunderbolt = new EntityThunderbolt(world, caster, damageMultiplier); thunderbolt.directTowards(target, 2.5f); world.spawnEntityInWorld(thunderbolt); + world.playSoundAtEntity(caster, "wizardry:ice", 0.8F, world.rand.nextFloat() * 0.2F + 0.8F); } - - caster.playSound(WizardrySounds.SPELL_ICE, 0.8F, world.rand.nextFloat() * 0.2F + 0.8F); - caster.swingArm(hand); + + caster.swingItem(); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Thunderstorm.java b/src/main/java/electroblob/wizardry/spell/Thunderstorm.java index b1992941..83e70ab7 100644 --- a/src/main/java/electroblob/wizardry/spell/Thunderstorm.java +++ b/src/main/java/electroblob/wizardry/spell/Thunderstorm.java @@ -2,49 +2,44 @@ package electroblob.wizardry.spell; import java.util.List; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import electroblob.wizardry.entity.EntityArc; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.effect.EntityLightningBolt; +import net.minecraft.entity.monster.EntityCreeper; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; public class Thunderstorm extends Spell { public Thunderstorm() { - super(Tier.MASTER, 100, Element.LIGHTNING, "thunderstorm", SpellType.ATTACK, 250, EnumAction.BOW, false); + super(EnumTier.MASTER, 100, EnumElement.LIGHTNING, "thunderstorm", EnumSpellType.ATTACK, 250, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - if(world.canBlockSeeSky(new BlockPos(caster))){ + if(world.canBlockSeeTheSky((int)caster.posX, (int)caster.posY, (int)caster.posZ)){ for(int r=0; r<10; r++){ - double radius = 4 + world.rand.nextDouble()*6*modifiers.get(WizardryItems.blast_upgrade); + double radius = 4 + world.rand.nextDouble()*6*blastMultiplier; double angle = world.rand.nextDouble()*Math.PI*2; double x = caster.posX + radius*Math.cos(angle); double z = caster.posZ + radius*Math.sin(angle); - double y = WizardryUtilities.getNearestFloorLevel(world, new BlockPos(x, caster.posY, z), 10); + double y = WizardryUtilities.getNearestFloorLevel(world, (int)x, (int)caster.posY, (int)z, 10); if(!world.isRemote){ - EntityLightningBolt entitylightning = new EntityLightningBolt(world, x, y, z, false); + EntityLightningBolt entitylightning = new EntityLightningBolt(world, x, y, z); world.addWeatherEffect(entitylightning); } @@ -52,7 +47,7 @@ public class Thunderstorm extends Spell { //NBTTagCompound entityNBT = entitylightning.getEntityData(); //entityNBT.setInteger("summoningPlayer", entityplayer.entityId); - // Secondary chaining effect + //Secondary chaining effect double seekerRange = 10.0d; List secondaryTargets = WizardryUtilities.getEntitiesWithinRadius(seekerRange, x, y+1, z, world); @@ -69,14 +64,14 @@ public class Thunderstorm extends Spell { world.spawnEntityInWorld(arc); }else{ for(int j=0;j<8;j++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, secondaryTarget.posX + world.rand.nextFloat() - 0.5, secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height/2 + world.rand.nextFloat()*2 - 1, secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); - world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, secondaryTarget.posX + world.rand.nextFloat() - 0.5, secondaryTarget.getEntityBoundingBox().minY + secondaryTarget.height/2 + world.rand.nextFloat()*2 - 1, secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, world, secondaryTarget.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(secondaryTarget) + secondaryTarget.height/2 + world.rand.nextFloat()*2 - 1, secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); + world.spawnParticle("largesmoke", secondaryTarget.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(secondaryTarget) + secondaryTarget.height/2 + world.rand.nextFloat()*2 - 1, secondaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); } } - secondaryTarget.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); + world.playSoundAtEntity(secondaryTarget, "wizardry:arc", 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); - secondaryTarget.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 10.0f * modifiers.get(SpellModifiers.DAMAGE)); + secondaryTarget.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 10.0f * damageMultiplier); //Tertiary chaining effect @@ -95,14 +90,14 @@ public class Thunderstorm extends Spell { world.spawnEntityInWorld(arc); }else{ for(int k=0;k<8;k++){ - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, tertiaryTarget.posX + world.rand.nextFloat() - 0.5, tertiaryTarget.getEntityBoundingBox().minY + tertiaryTarget.height/2 + world.rand.nextFloat()*2 - 1, tertiaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); - world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, tertiaryTarget.posX + world.rand.nextFloat() - 0.5, tertiaryTarget.getEntityBoundingBox().minY + tertiaryTarget.height/2 + world.rand.nextFloat()*2 - 1, tertiaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARK, world, tertiaryTarget.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(tertiaryTarget) + tertiaryTarget.height/2 + world.rand.nextFloat()*2 - 1, tertiaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); + world.spawnParticle("largesmoke", tertiaryTarget.posX + world.rand.nextFloat() - 0.5, WizardryUtilities.getEntityFeetPos(tertiaryTarget) + tertiaryTarget.height/2 + world.rand.nextFloat()*2 - 1, tertiaryTarget.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); } } - tertiaryTarget.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); + world.playSoundAtEntity(tertiaryTarget, "wizardry:arc", 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); - tertiaryTarget.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 8.0f * modifiers.get(SpellModifiers.DAMAGE)); + tertiaryTarget.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK), 8.0f * damageMultiplier); } } } diff --git a/src/main/java/electroblob/wizardry/spell/Tornado.java b/src/main/java/electroblob/wizardry/spell/Tornado.java index c0f60744..77511207 100644 --- a/src/main/java/electroblob/wizardry/spell/Tornado.java +++ b/src/main/java/electroblob/wizardry/spell/Tornado.java @@ -1,24 +1,20 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.entity.construct.EntityTornado; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.entity.projectile.EntityMagicMissile; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class Tornado extends Spell { public Tornado() { - super(Tier.ADVANCED, 35, Element.EARTH, "tornado", SpellType.ATTACK, 80, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 35, EnumElement.EARTH, "tornado", EnumSpellType.ATTACK, 80, EnumAction.none, false); } @Override @@ -27,23 +23,23 @@ public class Tornado extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ double x = caster.posX + caster.getLookVec().xCoord; double y = caster.posY; double z = caster.posZ + caster.getLookVec().zCoord; - EntityTornado tornado = new EntityTornado(world, x, y, z, caster, (int)(200*modifiers.get(WizardryItems.duration_upgrade)), caster.getLookVec().xCoord/3, caster.getLookVec().zCoord/3, modifiers.get(SpellModifiers.DAMAGE)); + EntityTornado tornado = new EntityTornado(world, x, y, z, caster, (int)(200*durationMultiplier), caster.getLookVec().xCoord/3, caster.getLookVec().zCoord/3, damageMultiplier); world.spawnEntityInWorld(tornado); } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 1.0F, 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, 1.0F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ @@ -52,11 +48,11 @@ public class Tornado extends Spell { double y = caster.posY; double z = caster.posZ + caster.getLookVec().zCoord; - EntityTornado tornado = new EntityTornado(world, x, y, z, caster, (int)(200*modifiers.get(WizardryItems.duration_upgrade)), caster.getLookVec().xCoord/3, caster.getLookVec().zCoord/3, modifiers.get(SpellModifiers.DAMAGE)); + EntityTornado tornado = new EntityTornado(world, x, y, z, caster, (int)(200*durationMultiplier), caster.getLookVec().xCoord/3, caster.getLookVec().zCoord/3, damageMultiplier); world.spawnEntityInWorld(tornado); } - caster.swingArm(hand); - caster.playSound(WizardrySounds.SPELL_ICE, 1.0F, 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 1.0F, 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Transience.java b/src/main/java/electroblob/wizardry/spell/Transience.java index 96d3f1c7..4232e188 100644 --- a/src/main/java/electroblob/wizardry/spell/Transience.java +++ b/src/main/java/electroblob/wizardry/spell/Transience.java @@ -1,30 +1,20 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; -import net.minecraft.entity.EntityLivingBase; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; +import electroblob.wizardry.Wizardry; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; -import net.minecraftforge.event.entity.living.LivingAttackEvent; -import net.minecraftforge.event.world.BlockEvent; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -@Mod.EventBusSubscriber public class Transience extends Spell { public Transience() { - super(Tier.ADVANCED, 50, Element.HEALING, "transience", SpellType.DEFENCE, 100, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 50, EnumElement.HEALING, "transience", EnumSpellType.DEFENCE, 100, EnumAction.bow, false); } @Override @@ -33,50 +23,20 @@ public class Transience extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { - - if(!caster.isPotionActive(WizardryPotions.transience)){ + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { + + ExtendedPlayer properties = ExtendedPlayer.get(caster); + + if(!caster.isPotionActive(Wizardry.transience)){ if(!world.isRemote){ - caster.addPotionEffect(new PotionEffect(WizardryPotions.transience, (int)(400*modifiers.get(WizardryItems.duration_upgrade)), 0)); - caster.addPotionEffect(new PotionEffect(MobEffects.INVISIBILITY, (int)(400*modifiers.get(WizardryItems.duration_upgrade)), 0, false, false)); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_CONJURATION, 1.0f, 1.0f); + caster.addPotionEffect(new PotionEffect(Wizardry.transience.id, (int)(400*durationMultiplier), 0, true)); + caster.addPotionEffect(new PotionEffect(Potion.invisibility.id, (int)(400*durationMultiplier), 0, true)); + world.playSoundAtEntity(caster, "wizardry:aura", 1.0f, 1.0f); } return true; } return false; } - @SubscribeEvent - public static void onLivingAttackEvent(LivingAttackEvent event){ - if(event.getSource() != null){ - // Prevents all blockable damage while transience is active - if(event.getEntityLiving().isPotionActive(WizardryPotions.transience) && !event.getSource().isUnblockable()){ - event.setCanceled(true); - } - // Prevents transient entities from causing any damage - if(event.getSource().getEntity() instanceof EntityLivingBase - && ((EntityLivingBase)event.getSource().getEntity()).isPotionActive(WizardryPotions.transience)){ - event.setCanceled(true); - } - } - } - - @SubscribeEvent - public static void onBlockPlaceEvent(BlockEvent.PlaceEvent event){ - // Prevents transient players from placing blocks - if(event.getPlayer().isPotionActive(WizardryPotions.transience)){ - event.setCanceled(true); - return; - } - } - - @SubscribeEvent - public static void onBlockBreakEvent(BlockEvent.BreakEvent event){ - // Prevents transient players from breaking blocks - if(event.getPlayer().isPotionActive(WizardryPotions.transience)){ - event.setCanceled(true); - return; - } - } } diff --git a/src/main/java/electroblob/wizardry/spell/Transportation.java b/src/main/java/electroblob/wizardry/spell/Transportation.java index 23caeaf1..87d63985 100644 --- a/src/main/java/electroblob/wizardry/spell/Transportation.java +++ b/src/main/java/electroblob/wizardry/spell/Transportation.java @@ -1,25 +1,21 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.WizardData; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.ExtendedPlayer; import electroblob.wizardry.block.BlockTransportationStone; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; import net.minecraft.world.World; public class Transportation extends Spell { - public Transportation(){ - super(Tier.ADVANCED, 100, Element.SORCERY, "transportation", SpellType.UTILITY, 100, EnumAction.BOW, false); + public Transportation() { + super(EnumTier.ADVANCED, 100, EnumElement.SORCERY, "transportation", EnumSpellType.UTILITY, 100, EnumAction.bow, false); } @Override @@ -28,30 +24,28 @@ public class Transportation extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - WizardData properties = WizardData.get(caster); - // Fixes the sound not playing in first person. - if(world.isRemote) WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.BLOCK_PORTAL_TRIGGER, 1.0f, 1.0f); + ExtendedPlayer properties = ExtendedPlayer.get(caster); // Only works when the caster is in the same dimension. - if(properties != null && properties.getTpCountdown() == 0){ - if(caster.dimension == properties.getStoneCircleDimension()){ + if(properties != null && properties.tpTimer == 0){ + if(caster.dimension == properties.transportDimension){ // Has to be y since x and z could reasonably be -1. - if(properties.getStoneCircleLocation() != null){ - if(BlockTransportationStone.testForCircle(world, properties.getStoneCircleLocation())){ - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.BLOCK_PORTAL_TRIGGER, 1.0f, 1.0f); - caster.addPotionEffect(new PotionEffect(MobEffects.NAUSEA, 150, 0)); - properties.setTpCountdown(75); + if(properties.transportY > -1){ + if(BlockTransportationStone.testForCircle(world, properties.transportX, properties.transportY, properties.transportZ)){ + world.playSoundAtEntity(caster, "portal.trigger", 1.0f, 1.0f); + caster.addPotionEffect(new PotionEffect(Potion.confusion.id, 150, 0)); + properties.tpTimer = 75; return true; }else{ - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.transportation.missing")); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.transportation.missing")); } }else{ - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.transportation.undefined")); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.transportation.undefined")); } }else{ - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.transportation.wrongdimension")); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.transportation.wrongdimension")); } } return false; diff --git a/src/main/java/electroblob/wizardry/spell/VanishingBox.java b/src/main/java/electroblob/wizardry/spell/VanishingBox.java index 85bc13b6..f91153ea 100644 --- a/src/main/java/electroblob/wizardry/spell/VanishingBox.java +++ b/src/main/java/electroblob/wizardry/spell/VanishingBox.java @@ -1,21 +1,17 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.SoundEvents; import net.minecraft.inventory.InventoryEnderChest; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class VanishingBox extends Spell { public VanishingBox() { - super(Tier.ADVANCED, 45, Element.SORCERY, "vanishing_box", SpellType.UTILITY, 70, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 45, EnumElement.SORCERY, "vanishing_box", EnumSpellType.UTILITY, 70, EnumAction.bow, false); } @Override @@ -24,7 +20,7 @@ public class VanishingBox extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { if(!world.isRemote){ @@ -35,7 +31,7 @@ public class VanishingBox extends Spell { } } - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.BLOCK_ENDERCHEST_OPEN, 1, 1); + world.playSoundAtEntity(caster, "wizardry:aura", 1, 1); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/WallOfFrost.java b/src/main/java/electroblob/wizardry/spell/WallOfFrost.java index 285719bf..fba7c809 100644 --- a/src/main/java/electroblob/wizardry/spell/WallOfFrost.java +++ b/src/main/java/electroblob/wizardry/spell/WallOfFrost.java @@ -1,89 +1,100 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryBlocks; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class WallOfFrost extends Spell { public WallOfFrost() { - super(Tier.MASTER, 15, Element.ICE, "wall_of_frost", SpellType.UTILITY, 0, EnumAction.NONE, true); + super(EnumTier.MASTER, 15, EnumElement.ICE, "wall_of_frost", EnumSpellType.UTILITY, 0, EnumAction.none, true); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - // IDEA: Use frosted ice instead of ice statue + Vec3 look = caster.getLookVec(); - Vec3d look = caster.getLookVec(); - - RayTraceResult rayTrace = WizardryUtilities.rayTrace(10*modifiers.get(WizardryItems.range_upgrade), world, caster, true); + MovingObjectPosition rayTrace = WizardryUtilities.rayTrace(10*rangeMultiplier, world, caster, true); if(rayTrace != null && !world.isRemote){ - - BlockPos pos = rayTrace.getBlockPos(); + int x = rayTrace.blockX; + int y = rayTrace.blockY; + int z = rayTrace.blockZ; // Stops the ice being placed floating above snow and grass. Directions other than up included for completeness. - if(WizardryUtilities.canBlockBeReplaced(world, pos)){ - // Moves the blockpos back into the block - pos = pos.offset(rayTrace.sideHit.getOpposite()); + if(WizardryUtilities.canBlockBeReplaced(world, x, y, z)){ + switch(rayTrace.sideHit){ + case 0: y++; break; + case 1: y--; break; + case 2: z++; break; + case 3: z--; break; + case 4: x++; break; + case 5: x--; break; + } } - if(caster.getDistance(pos.getX(), pos.getY(), pos.getZ()) > 2 && world.getBlockState(pos).getBlock() != WizardryBlocks.ice_statue){ + if(caster.getDistance(x, y, z) > 2 && world.getBlock(x, y, z) != Wizardry.iceStatue){ - pos = pos.offset(rayTrace.sideHit); - - if(WizardryUtilities.canBlockBeReplaced(world, pos)){ - world.setBlockState(pos, WizardryBlocks.ice_statue.getDefaultState()); - } - - // Builds a 2 block high wall if it hits the ground - if(rayTrace.sideHit == EnumFacing.UP){ - pos = pos.offset(rayTrace.sideHit); - - if(WizardryUtilities.canBlockBeReplaced(world, pos)){ - world.setBlockState(pos, WizardryBlocks.ice_statue.getDefaultState()); + switch(rayTrace.sideHit){ + case 0: + break; + case 1: + if(WizardryUtilities.canBlockBeReplaced(world, x, y+1, z)){ + world.setBlock(x, y+1, z, Wizardry.iceStatue); } + if(WizardryUtilities.canBlockBeReplaced(world, x, y+2, z)){ + world.setBlock(x, y+2, z, Wizardry.iceStatue); + } + break; + case 2: + if(WizardryUtilities.canBlockBeReplaced(world, x, y, z-1)){ + world.setBlock(x, y, z-1, Wizardry.iceStatue); + } + break; + case 3: + if(WizardryUtilities.canBlockBeReplaced(world, x, y, z+1)){ + world.setBlock(x, y, z+1, Wizardry.iceStatue); + } + break; + case 4: + if(WizardryUtilities.canBlockBeReplaced(world, x-1, y, z)){ + world.setBlock(x-1, y, z, Wizardry.iceStatue); + } + break; + case 5: + if(WizardryUtilities.canBlockBeReplaced(world, x+1, y, z)){ + world.setBlock(x+1, y, z, Wizardry.iceStatue); + } + break; } } } - for(int i=0; i<20; i++){ - if(world.isRemote){ - double x1 = caster.posX + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, look.xCoord*modifiers.get(WizardryItems.range_upgrade), look.yCoord*modifiers.get(WizardryItems.range_upgrade), look.zCoord*modifiers.get(WizardryItems.range_upgrade), 8 + world.rand.nextInt(12), 0.4f, 0.6f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, look.xCoord*rangeMultiplier, look.yCoord*rangeMultiplier, look.zCoord*rangeMultiplier, 8 + world.rand.nextInt(12), 0.4f, 0.6f, 1.0f); x1 = caster.posX + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, look.xCoord*modifiers.get(WizardryItems.range_upgrade), look.yCoord*modifiers.get(WizardryItems.range_upgrade), look.zCoord*modifiers.get(WizardryItems.range_upgrade), 8 + world.rand.nextInt(12), 1.0f, 1.0f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, look.xCoord*rangeMultiplier, look.yCoord*rangeMultiplier, look.zCoord*rangeMultiplier, 8 + world.rand.nextInt(12), 1.0f, 1.0f, 1.0f); } } - if(ticksInUse % 12 == 0){ - if(ticksInUse == 0) WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 0.5F, 1.0f); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_LOOP_ICE, 0.5F, 1.0f); + if(ticksInUse == 0) world.playSoundAtEntity(caster, "wizardry:ice", 0.5F, 1.0f); + world.playSoundAtEntity(caster, "wizardry:frostray", 0.5F, 1.0f); } - return true; } diff --git a/src/main/java/electroblob/wizardry/spell/WaterBreathing.java b/src/main/java/electroblob/wizardry/spell/WaterBreathing.java index c132a85b..4ce6df42 100644 --- a/src/main/java/electroblob/wizardry/spell/WaterBreathing.java +++ b/src/main/java/electroblob/wizardry/spell/WaterBreathing.java @@ -1,40 +1,36 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; import net.minecraft.world.World; public class WaterBreathing extends Spell { public WaterBreathing() { - super(Tier.ADVANCED, 30, Element.EARTH, "water_breathing", SpellType.UTILITY, 250, EnumAction.BOW, false); + super(EnumTier.ADVANCED, 30, EnumElement.EARTH, "water_breathing", EnumSpellType.UTILITY, 250, EnumAction.bow, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - caster.addPotionEffect(new PotionEffect(MobEffects.WATER_BREATHING, (int)(1200*modifiers.get(WizardryItems.duration_upgrade)), 0, false, false)); + caster.addPotionEffect(new PotionEffect(Potion.waterBreathing.id, (int)(1200*durationMultiplier), 0, true)); if(world.isRemote){ for(int i=0; i<10; i++){ double x1 = (double)((float)caster.posX + world.rand.nextFloat()*2 - 1.0F); double y1 = (double)((float)WizardryUtilities.getPlayerEyesPos(caster) - 0.5F + world.rand.nextFloat()); double z1 = (double)((float)caster.posZ + world.rand.nextFloat()*2 - 1.0F); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.3f, 0.3f, 1.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0, 0.1F, 0, 48 + world.rand.nextInt(12), 0.3f, 0.3f, 1.0f); } } - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_HEAL, 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); + world.playSoundAtEntity(caster, "wizardry:heal", 0.7F, world.rand.nextFloat() * 0.4F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Whirlwind.java b/src/main/java/electroblob/wizardry/spell/Whirlwind.java index 9a76561c..59be14b3 100644 --- a/src/main/java/electroblob/wizardry/spell/Whirlwind.java +++ b/src/main/java/electroblob/wizardry/spell/Whirlwind.java @@ -1,33 +1,28 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardrySounds; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.WizardryUtilities; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.EnumAction; -import net.minecraft.network.play.server.SPacketEntityVelocity; -import net.minecraft.util.EnumHand; -import net.minecraft.util.EnumParticleTypes; -import net.minecraft.util.math.RayTraceResult; +import net.minecraft.network.play.server.S12PacketEntityVelocity; +import net.minecraft.util.MovingObjectPosition; import net.minecraft.world.World; public class Whirlwind extends Spell { public Whirlwind() { - super(Tier.APPRENTICE, 10, Element.EARTH, "whirlwind", SpellType.DEFENCE, 15, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 10, EnumElement.EARTH, "whirlwind", EnumSpellType.DEFENCE, 15, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier); if(rayTrace != null && rayTrace.entityHit instanceof EntityLivingBase){ EntityLivingBase target = (EntityLivingBase) rayTrace.entityHit; @@ -40,7 +35,7 @@ public class Whirlwind extends Spell { // Player motion is handled on that player's client so needs packets if(target instanceof EntityPlayerMP){ - ((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target)); + ((EntityPlayerMP)target).playerNetServerHandler.sendPacket(new S12PacketEntityVelocity(target)); } } @@ -49,19 +44,19 @@ public class Whirlwind extends Spell { double x2 = (double)(caster.posX + world.rand.nextFloat() - 0.5F + caster.getLookVec().xCoord*caster.getDistanceToEntity(target)*0.5); double y2 = (double)(WizardryUtilities.getPlayerEyesPos(caster) + world.rand.nextFloat() - 0.5F + caster.getLookVec().yCoord*caster.getDistanceToEntity(target)*0.5); double z2 = (double)(caster.posZ + world.rand.nextFloat() - 0.5F + caster.getLookVec().zCoord*caster.getDistanceToEntity(target)*0.5); - world.spawnParticle(EnumParticleTypes.CLOUD, x2, y2, z2, caster.getLookVec().xCoord, caster.getLookVec().yCoord, caster.getLookVec().zCoord); + world.spawnParticle("cloud", x2, y2, z2, caster.getLookVec().xCoord, caster.getLookVec().yCoord, caster.getLookVec().zCoord); //Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySparkleFX(world, x2, y2, z2, entityplayer.getLookVec().xCoord, entityplayer.getLookVec().yCoord, entityplayer.getLookVec().zCoord, null, 1.0f, 1.0f, 0.8f, 10)); } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, WizardrySounds.SPELL_ICE, 0.8F, world.rand.nextFloat() * 0.2F + 0.6F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 0.8F, world.rand.nextFloat() * 0.2F + 0.6F); return true; } return false; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ @@ -72,7 +67,7 @@ public class Whirlwind extends Spell { // Player motion is handled on that player's client so needs packets if(target instanceof EntityPlayerMP){ - ((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target)); + ((EntityPlayerMP)target).playerNetServerHandler.sendPacket(new S12PacketEntityVelocity(target)); } } if(world.isRemote){ @@ -80,11 +75,11 @@ public class Whirlwind extends Spell { double x2 = (double)(caster.posX + world.rand.nextFloat() - 0.5F + caster.getLookVec().xCoord*caster.getDistanceToEntity(target)*0.5); double y2 = (double)(caster.posY + caster.getEyeHeight() + world.rand.nextFloat() - 0.5F + caster.getLookVec().yCoord*caster.getDistanceToEntity(target)*0.5); double z2 = (double)(caster.posZ + world.rand.nextFloat() - 0.5F + caster.getLookVec().zCoord*caster.getDistanceToEntity(target)*0.5); - world.spawnParticle(EnumParticleTypes.CLOUD, x2, y2, z2, caster.getLookVec().xCoord, caster.getLookVec().yCoord, caster.getLookVec().zCoord); + world.spawnParticle("cloud", x2, y2, z2, caster.getLookVec().xCoord, caster.getLookVec().yCoord, caster.getLookVec().zCoord); } } - caster.swingArm(hand); - caster.playSound(WizardrySounds.SPELL_ICE, 0.8F, world.rand.nextFloat() * 0.2F + 0.6F); + caster.swingItem(); + world.playSoundAtEntity(caster, "wizardry:ice", 0.8F, world.rand.nextFloat() * 0.2F + 0.6F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/Wither.java b/src/main/java/electroblob/wizardry/spell/Wither.java index 878cf0bb..ba24106f 100644 --- a/src/main/java/electroblob/wizardry/spell/Wither.java +++ b/src/main/java/electroblob/wizardry/spell/Wither.java @@ -1,59 +1,58 @@ package electroblob.wizardry.spell; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumParticleType; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; +import electroblob.wizardry.MagicDamage; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.util.MagicDamage; -import electroblob.wizardry.util.MagicDamage.DamageType; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryParticleType; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.WizardryUtilities; +import electroblob.wizardry.MagicDamage.DamageType; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.boss.EntityWither; +import net.minecraft.entity.monster.EntitySkeleton; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.init.MobEffects; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; +import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; -import net.minecraft.util.text.TextComponentTranslation; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.MovingObjectPosition.MovingObjectType; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class Wither extends Spell { public Wither() { - super(Tier.APPRENTICE, 10, Element.NECROMANCY, "wither", SpellType.ATTACK, 20, EnumAction.NONE, false); + super(EnumTier.APPRENTICE, 10, EnumElement.NECROMANCY, "wither", EnumSpellType.ATTACK, 20, EnumAction.none, false); } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - Vec3d look = caster.getLookVec(); + Vec3 look = caster.getLookVec(); - RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*modifiers.get(WizardryItems.range_upgrade)); + MovingObjectPosition rayTrace = WizardryUtilities.standardEntityRayTrace(world, caster, 10*rangeMultiplier); - if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ + if(rayTrace != null && rayTrace.typeOfHit == MovingObjectType.ENTITY && rayTrace.entityHit instanceof EntityLivingBase){ EntityLivingBase target = (EntityLivingBase) rayTrace.entityHit; // Has no effect on withers or wither skeletons. if(MagicDamage.isEntityImmune(DamageType.WITHER, target)){ - if(!world.isRemote) caster.addChatComponentMessage(new TextComponentTranslation("spell.resist", target.getName(), this.getNameForTranslationFormatted())); + if(!world.isRemote) caster.addChatComponentMessage(new ChatComponentTranslation("spell.resist", target.getCommandSenderName(), this.getDisplayNameWithFormatting())); }else{ - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.WITHER), 1.0f * modifiers.get(SpellModifiers.DAMAGE)); - target.addPotionEffect(new PotionEffect(MobEffects.WITHER, (int)(200*modifiers.get(WizardryItems.duration_upgrade)), 1)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.WITHER), 1.0f * damageMultiplier); + target.addPotionEffect(new PotionEffect(Potion.wither.id, (int)(200*durationMultiplier), 1)); } } if(world.isRemote){ - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ // I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet! // This is a test for lining up the ray with the wand tip. Not sure if I like it or not. /* - Vec3d origin = Wizardry.proxy.getWandTipPosition(caster); + Vec3 origin = Wizardry.proxy.getWandTipPosition(caster); double x1 = origin.xCoord + look.xCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = origin.yCoord + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = origin.zCoord + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; @@ -62,23 +61,23 @@ public class Wither extends Spell { double y1 = WizardryUtilities.getPlayerEyesPos(caster) - 0.4f + look.yCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + look.zCoord*i/2 + world.rand.nextFloat()/5 - 0.1f; //world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord); - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.1f, 0.0f, 0.05f); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.1f, 0.0f, 0.05f); } } - caster.swingArm(hand); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_HURT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "mob.wither.hurt", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ // Has no effect on withers or wither skeletons. if(!MagicDamage.isEntityImmune(DamageType.WITHER, target) && !world.isRemote){ - target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.WITHER), 1.0f * modifiers.get(SpellModifiers.DAMAGE)); - target.addPotionEffect(new PotionEffect(MobEffects.WITHER, (int)(200*modifiers.get(WizardryItems.duration_upgrade)), 1)); + target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.WITHER), 1.0f * damageMultiplier); + target.addPotionEffect(new PotionEffect(Potion.wither.id, (int)(200*durationMultiplier), 1)); } if(world.isRemote){ @@ -87,18 +86,18 @@ public class Wither extends Spell { double dy = (target.posY - caster.posY)/caster.getDistanceToEntity(target); double dz = (target.posZ - caster.posZ)/caster.getDistanceToEntity(target); - for(int i=1; i<(int)(25*modifiers.get(WizardryItems.range_upgrade)); i+=2){ + for(int i=1; i<(int)(25*rangeMultiplier); i+=2){ double x1 = caster.posX + dx*i/2 + world.rand.nextFloat()/5 - 0.1f; double y1 = caster.posY + caster.getEyeHeight() - 0.4f + dy*i/2 + world.rand.nextFloat()/5 - 0.1f; double z1 = caster.posZ + dz*i/2 + world.rand.nextFloat()/5 - 0.1f; - Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); - Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.1f, 0.0f, 0.05f); + Wizardry.proxy.spawnParticle(EnumParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 0, 0.1f, 0.0f, 0.0f); + Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x1, y1, z1, 0.0d, 0.0d, 0.0d, 12 + world.rand.nextInt(8), 0.1f, 0.0f, 0.05f); } } - caster.swingArm(hand); - caster.playSound(SoundEvents.ENTITY_WITHER_HURT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + caster.swingItem(); + world.playSoundAtEntity(caster, "mob.wither.hurt", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); return true; } diff --git a/src/main/java/electroblob/wizardry/spell/WitherSkull.java b/src/main/java/electroblob/wizardry/spell/WitherSkull.java index ce0f642e..27e25650 100644 --- a/src/main/java/electroblob/wizardry/spell/WitherSkull.java +++ b/src/main/java/electroblob/wizardry/spell/WitherSkull.java @@ -1,24 +1,21 @@ package electroblob.wizardry.spell; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.SpellType; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.util.SpellModifiers; -import electroblob.wizardry.util.WizardryUtilities; +import electroblob.wizardry.EnumElement; +import electroblob.wizardry.EnumSpellType; +import electroblob.wizardry.EnumTier; import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityLargeFireball; import net.minecraft.entity.projectile.EntityWitherSkull; -import net.minecraft.init.SoundEvents; import net.minecraft.item.EnumAction; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.Vec3; import net.minecraft.world.World; public class WitherSkull extends Spell { public WitherSkull() { - super(Tier.ADVANCED, 20, Element.NECROMANCY, "wither_skull", SpellType.ATTACK, 30, EnumAction.NONE, false); + super(EnumTier.ADVANCED, 20, EnumElement.NECROMANCY, "wither_skull", EnumSpellType.ATTACK, 30, EnumAction.none, false); } @Override @@ -27,9 +24,9 @@ public class WitherSkull extends Spell { } @Override - public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers) { + public boolean cast(World world, EntityPlayer caster, int ticksInUse, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier) { - Vec3d look = caster.getLookVec(); + Vec3 look = caster.getLookVec(); if(!world.isRemote){ EntityWitherSkull witherskull = new EntityWitherSkull(world, caster, 1, 1, 1); @@ -41,14 +38,14 @@ public class WitherSkull extends Spell { witherskull.accelerationY = look.yCoord * 0.1; witherskull.accelerationZ = look.zCoord * 0.1; world.spawnEntityInWorld(witherskull); - WizardryUtilities.playSoundAtPlayer(caster, SoundEvents.ENTITY_WITHER_SHOOT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "mob.wither.shoot", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); } - caster.swingArm(hand); + caster.swingItem(); return true; } @Override - public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){ + public boolean cast(World world, EntityLiving caster, EntityLivingBase target, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){ if(target != null){ @@ -57,7 +54,7 @@ public class WitherSkull extends Spell { EntityWitherSkull witherskull = new EntityWitherSkull(world, caster, 1, 1, 1); double dx = target.posX - caster.posX; - double dy = target.getEntityBoundingBox().minY + (double)(target.height / 2.0F) - (caster.posY + (double)(caster.height / 2.0F)); + double dy = target.boundingBox.minY + (double)(target.height / 2.0F) - (caster.posY + (double)(caster.height / 2.0F)); double dz = target.posZ - caster.posZ; witherskull.accelerationX = dx/caster.getDistanceToEntity(target) * 0.1; @@ -67,10 +64,10 @@ public class WitherSkull extends Spell { witherskull.setPosition(caster.posX, caster.posY + caster.getEyeHeight(), caster.posZ); world.spawnEntityInWorld(witherskull); - caster.playSound(SoundEvents.ENTITY_WITHER_SHOOT, 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); + world.playSoundAtEntity(caster, "mob.wither.shoot", 1.0F, world.rand.nextFloat() * 0.2F + 1.0F); } - caster.swingArm(hand); + caster.swingItem(); return true; } diff --git a/src/main/java/electroblob/wizardry/tileentity/ContainerArcaneWorkbench.java b/src/main/java/electroblob/wizardry/tileentity/ContainerArcaneWorkbench.java index 6e0f4e55..e93e6e39 100644 --- a/src/main/java/electroblob/wizardry/tileentity/ContainerArcaneWorkbench.java +++ b/src/main/java/electroblob/wizardry/tileentity/ContainerArcaneWorkbench.java @@ -1,461 +1,252 @@ package electroblob.wizardry.tileentity; -import java.util.HashSet; -import java.util.Set; - -import electroblob.wizardry.WizardData; +import electroblob.wizardry.WandHelper; import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Constants; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.event.SpellBindEvent; import electroblob.wizardry.item.ItemArcaneTome; import electroblob.wizardry.item.ItemArmourUpgrade; import electroblob.wizardry.item.ItemSpellBook; import electroblob.wizardry.item.ItemWand; import electroblob.wizardry.item.ItemWizardArmour; -import electroblob.wizardry.registry.Spells; -import electroblob.wizardry.registry.WizardryAchievements; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.spell.Spell; -import electroblob.wizardry.util.WandHelper; -import electroblob.wizardry.util.WizardryUtilities; +import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.Container; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.common.MinecraftForge; -public class ContainerArcaneWorkbench extends Container { +public class ContainerArcaneWorkbench extends Container +{ + public TileEntityArcaneWorkbench tileEntityArcaneWorkbench; + + public static final int CRYSTAL_SLOT = 8; + public static final int WAND_SLOT = 9; + public static final int UPGRADE_SLOT = 10; + + private static final int[][][] spellBookSlotCoords = { + {{80, 22}, {121, 51}, {106, 98}, {54, 98}, {39, 51}, {-999, -999}, {-999, -999}, {-999, -999}}, + {{80, 22}, {117, 43}, {117, 85}, {80, 106}, {43, 85}, {43, 43}, {-999, -999}, {-999, -999}}, + {{80, 22}, {113, 38}, {121, 74}, {98, 102}, {62, 102}, {39, 74}, {47, 38}, {-999, -999}}, + {{80, 22}, {111, 33}, {122, 64}, {111, 95}, {80, 106}, {49, 95}, {38, 64}, {49, 33}} + }; + + // Does slot.func_146977_a have something to do with whether the slot is enabled? - /** The arcane workbench tile entity associated with this container. */ - public TileEntityArcaneWorkbench tileentity; + public ContainerArcaneWorkbench(IInventory inventory, TileEntityArcaneWorkbench tileentity){ + + this.tileEntityArcaneWorkbench = tileentity; + + ItemStack wand = tileentity.getStackInSlot(WAND_SLOT); + + for(int i=0; i<8; i++){ + this.addSlotToContainer(new SlotWizardry(tileentity, i, -999, -999, 1, -1, Wizardry.spellBook)); + } + + this.addSlotToContainer(new SlotWizardry(tileentity, CRYSTAL_SLOT, 8, 88, 64, 1, Wizardry.magicCrystal)); + this.addSlotToContainer(new SlotWandArmour(tileentity, WAND_SLOT, 80, 64, this)); + this.addSlotToContainer(new SlotWizardry(tileentity, UPGRADE_SLOT, 8, 106, 1, 2, Wizardry.arcaneTome, + Wizardry.condenserUpgrade, Wizardry.siphonUpgrade, Wizardry.storageUpgrade, Wizardry.rangeUpgrade, + Wizardry.durationUpgrade, Wizardry.cooldownUpgrade, Wizardry.blastUpgrade, Wizardry.attunementUpgrade, + Wizardry.armourUpgrade)); - public static final ResourceLocation EMPTY_SLOT_CRYSTAL = new ResourceLocation(Wizardry.MODID, "gui/empty_slot_crystal"); - public static final ResourceLocation EMPTY_SLOT_UPGRADE = new ResourceLocation(Wizardry.MODID, "gui/empty_slot_upgrade"); - - public static final int CRYSTAL_SLOT = 8; - public static final int WAND_SLOT = 9; - public static final int UPGRADE_SLOT = 10; - - private static final int[][][] SPELL_BOOK_SLOT_COORDS = { - {{80, 22}, {121, 51}, {106, 98}, {54, 98}, {39, 51}, {-999, -999}, {-999, -999}, {-999, -999}}, - {{80, 22}, {117, 43}, {117, 85}, {80, 106}, {43, 85}, {43, 43}, {-999, -999}, {-999, -999}}, - {{80, 22}, {113, 38}, {121, 74}, {98, 102}, {62, 102}, {39, 74}, {47, 38}, {-999, -999}}, - {{80, 22}, {111, 33}, {122, 64}, {111, 95}, {80, 106}, {49, 95}, {38, 64}, {49, 33}} - }; - - public ContainerArcaneWorkbench(IInventory inventory, TileEntityArcaneWorkbench tileentity){ - - this.tileentity = tileentity; - - ItemStack wand = tileentity.getStackInSlot(WAND_SLOT); - - for(int i=0; i<8; i++){ - this.addSlotToContainer(new SlotItemList(tileentity, i, -999, -999, 1, WizardryItems.spell_book)); - } - - this.addSlotToContainer(new SlotItemList(tileentity, CRYSTAL_SLOT, 8, 88, 64, WizardryItems.magic_crystal)) - .setBackgroundName(EMPTY_SLOT_CRYSTAL.toString()); - - this.addSlotToContainer(new SlotWandArmour(tileentity, WAND_SLOT, 80, 64, this)); - - Set upgrades = new HashSet(WandHelper.getSpecialUpgrades()); // Can't be done statically. - upgrades.add(WizardryItems.arcane_tome); - upgrades.add(WizardryItems.armour_upgrade); - - this.addSlotToContainer(new SlotItemList(tileentity, UPGRADE_SLOT, 8, 106, 1, upgrades.toArray(new Item[0]))) - .setBackgroundName(EMPTY_SLOT_UPGRADE.toString()); - - for(int x = 0; x < 9; x++){ + for(int x = 0; x < 9; x++){ this.addSlotToContainer(new Slot(inventory, x, 8 + x * 18, 196)); } - + for(int y = 0; y < 3; y++){ for(int x = 0; x < 9; x++){ this.addSlotToContainer(new Slot(inventory, 9 + x + y * 9, 8 + x * 18, 138 + y * 18)); } } - + this.onSlotChanged(WAND_SLOT, wand, null); - } + } + + @Override + public boolean canInteractWith(EntityPlayer par1EntityPlayer) + { + return this.tileEntityArcaneWorkbench.isUseableByPlayer(par1EntityPlayer); + } + + public void onSlotChanged(int slotNumber, ItemStack stack, EntityPlayer player) { - @Override - public boolean canInteractWith(EntityPlayer player){ - return this.tileentity.isUseableByPlayer(player); - } + if(slotNumber == WAND_SLOT){ + + if(stack == null || (!(stack.getItem() instanceof ItemWand) && stack.getItem() != Wizardry.blankScroll)){ + // If the stack has been removed + for(int i=0; i

    - * Most external interaction with SpellModifiers objects will be in {@link SpellCastEvent.Pre}, where you can add additional - * modifiers to them if desired for use with your own spells, or modify the existing ones. If you have added a wand - * upgrade, this is not done automatically for you; you will have to do it yourself (for the simple reason that - * not all wand upgrades affect spells). SpellModifiers objects are mutable, so you can simply change the values - * they contain to modify the spell. - *

    - * To use a SpellModifiers object within the Spell.cast methods, simply retrieve the desired multiplier - * using {@link SpellModifiers#get(Item)} for wand upgrades, or {@link SpellModifiers#get(String)} if the multiplier - * is not from a wand upgrade. - * @author Electroblob - * @since Wizardry 1.2 - * @see WandHelper - */ -// I have made the decision that the USERS of this class must decide whether the modifiers need syncing or not, on a -// case-by-case basis. Why? Because assigning keys to either sync or not sync would be unnecessarily restrictive, and -// would mean they have to be registered, and part of the point of SpellModifiers is that they can be added to on the -// fly. -public final class SpellModifiers { - - /** Constant string identifier for the damage modifier. All the other modifiers in Wizardry have items. */ - public static final String DAMAGE = "damage"; - - private Map multiplierMap; - private Map syncedMultiplierMap; - - /** Creates an empty SpellModifiers object. All calls to get(...) on an empty SpellModifiers object - * will return a value of 1. */ - public SpellModifiers(){ - multiplierMap = new HashMap(); - syncedMultiplierMap = new HashMap(); - } - - /** - * Adds the given multiplier to this SpellModifiers object, using the string identifier that the given wand - * upgrade item was registered with. - * @throws IllegalArgumentException if the given item is not a registered special wand upgrade. - * @param upgrade The upgrade item the multiplier corresponds to. - * @param multiplier The multiplier value, with 1 being default. Usage of modifiers is up to individual spells to - * implement. - * @param needsSyncing Whether this multiplier should be synchronised with the client via packets. Only set this - * to true if particles will be spawned which need to know the value of the multiplier. - * @return The SpellModifiers object, allowing this method to be chained onto the constructor. - */ - public SpellModifiers set(Item upgrade, float multiplier, boolean needsSyncing){ - this.set(WandHelper.getIdentifier(upgrade), multiplier, needsSyncing); - return this; - } - - /** - * Adds the given multiplier to this SpellModifiers object, using the given string key. In most cases, the - * multiplier will correspond to a wand upgrade, in which case use {@link SpellModifiers#set(Item, float, boolean)} - * instead. - * @param key The key used to identify the multiplier. - * @param multiplier The multiplier value, with 1 being default. Usage of modifiers is up to individual spells to - * implement. - * @param needsSyncing Whether this multiplier should be synchronised with the client via packets. Only set this - * to true if particles will be spawned which depend on the multiplier. - * @return The SpellModifiers object, allowing this method to be chained onto the constructor. - */ - public SpellModifiers set(String key, float multiplier, boolean needsSyncing){ - multiplierMap.put(key, multiplier); - if(needsSyncing) syncedMultiplierMap.put(key, multiplier); - return this; - } - - /** Returns the multiplier corresponding to the given wand upgrade item, or 1 if no multiplier was stored. - * @throws IllegalArgumentException if the given item is not a registered special wand upgrade. */ - public float get(Item upgrade){ - return get(WandHelper.getIdentifier(upgrade)); - } - - /** Returns the multiplier corresponding to the given string key, or 1 if no multiplier was stored. In most cases, - * the multiplier will correspond to a wand upgrade, in which case use {@link SpellModifiers#get(Item)} - * instead. */ - public float get(String key){ - Float value = multiplierMap.get(key); - // Must check for null before unboxing, and if it is null, return the default 1. - return value == null ? 1 : value; - } - - /** Returns an unmodifiable map of the modifiers stored in this SpellModifiers object. Useful for iterating through - * the modifiers. */ - public Map getModifiers(){ - return Collections.unmodifiableMap(this.multiplierMap); - } - - /** Removes all modifiers from this SpellModifiers object, effectively resetting them all to 1. */ - public void reset(){ - this.multiplierMap.clear(); - this.syncedMultiplierMap.clear(); - } - - /** Reads this SpellModifiers object from the given ByteBuf. */ - public void read(ByteBuf buf){ - int entryCount = buf.readInt(); - for(int i=0; i entry : syncedMultiplierMap.entrySet()){ - ByteBufUtils.writeUTF8String(buf, entry.getKey()); - buf.writeFloat(entry.getValue()); - } - } - - /** Creates a new SpellModifiers object from the given NBTTagCompound. The NBTTagCompound should have 1 or more - * float tags, which will be stored as modifiers under the same name as the tag. For example, the following NBT - * tag (in command syntax) will create a SpellModifiers object with a damage modifier of 1.5 and a range modifier of - * 2:

    {damage:1.5, range:2}

    - * Note that needsSyncing is set to true for all returned modifiers. */ - public static SpellModifiers fromNBT(NBTTagCompound nbt){ - SpellModifiers modifiers = new SpellModifiers(); - for(String key : nbt.getKeySet()){ - modifiers.set(key, nbt.getFloat(key), true); - } - return modifiers; - } - -} diff --git a/src/main/java/electroblob/wizardry/util/WizardryParticleType.java b/src/main/java/electroblob/wizardry/util/WizardryParticleType.java deleted file mode 100644 index 53093f2c..00000000 --- a/src/main/java/electroblob/wizardry/util/WizardryParticleType.java +++ /dev/null @@ -1,19 +0,0 @@ -package electroblob.wizardry.util; - -/** Enum constants representing the different types of particle added by wizardry. This was renamed from the previous - * EnumParticleType in the 1.10.2 port to avoid confusion with the vanilla version, EnumParticleTypes. */ -public enum WizardryParticleType { - BLIZZARD, - BRIGHT_DUST, - DARK_MAGIC, - DUST, - ICE, - LEAF, - MAGIC_BUBBLE, - MAGIC_FIRE, - PATH, - SNOW, - SPARK, - SPARKLE, - SPARKLE_ROTATING -} diff --git a/src/main/java/electroblob/wizardry/util/WizardryPathFinder.java b/src/main/java/electroblob/wizardry/util/WizardryPathFinder.java deleted file mode 100644 index 2a431b38..00000000 --- a/src/main/java/electroblob/wizardry/util/WizardryPathFinder.java +++ /dev/null @@ -1,138 +0,0 @@ -package electroblob.wizardry.util; - -import java.util.Set; - -import javax.annotation.Nullable; - -import com.google.common.collect.Sets; - -import electroblob.wizardry.spell.Clairvoyance; -import net.minecraft.entity.EntityLiving; -import net.minecraft.pathfinding.NodeProcessor; -import net.minecraft.pathfinding.Path; -import net.minecraft.pathfinding.PathHeap; -import net.minecraft.pathfinding.PathPoint; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IBlockAccess; - -/** Minecraft's pathfinder refused to play nicely, so I 'borrowed' its code and fiddled with it. Currently this is only - * used for the {@link Clairvoyance} spell. */ -public class WizardryPathFinder { - - /** The path being generated */ - private final PathHeap path = new PathHeap(); - private final Set closedSet = Sets.newHashSet(); - /** Selection of path points to add to the path */ - private final PathPoint[] pathOptions = new PathPoint[32]; - private final NodeProcessor nodeProcessor; - - public WizardryPathFinder(NodeProcessor processor){ - this.nodeProcessor = processor; - } - - @Nullable - public Path findPath(IBlockAccess world, EntityLiving entity, BlockPos destination, float range){ - return this.findPath(world, entity, (double)((float)destination.getX() + 0.5F), (double)((float)destination.getY() + 0.5F), (double)((float)destination.getZ() + 0.5F), range); - } - - @Nullable - private Path findPath(IBlockAccess world, EntityLiving entity, double x, double y, double z, float range){ - this.path.clearPath(); - this.nodeProcessor.initProcessor(world, entity); - PathPoint pathpoint = this.nodeProcessor.getStart(); - PathPoint pathpoint1 = this.nodeProcessor.getPathPointToCoords(x, y, z); - Path path = this.findPath(pathpoint, pathpoint1, range); - this.nodeProcessor.postProcess(); - return path; - } - - @Nullable - private Path findPath(PathPoint start, PathPoint end, float range){ - - start.totalPathDistance = 0.0F; - start.distanceToNext = start.distanceManhattan(end); - start.distanceToTarget = start.distanceToNext; - this.path.clearPath(); - this.closedSet.clear(); - this.path.addPoint(start); - PathPoint pathpoint = start; - int i = 0; - - while(!this.path.isPathEmpty()){ - - ++i; - - // This is the offending line - timeout limit changed from 200 to 5000. - if(i >= 5000){ - break; - } - - PathPoint pathpoint1 = this.path.dequeue(); - - if(pathpoint1.equals(end)){ - pathpoint = end; - break; - } - - if(pathpoint1.distanceManhattan(end) < pathpoint.distanceManhattan(end)){ - pathpoint = pathpoint1; - } - - pathpoint1.visited = true; - int j = this.nodeProcessor.findPathOptions(this.pathOptions, pathpoint1, end, range); - - for(int k = 0; k < j; ++k){ - - PathPoint pathpoint2 = this.pathOptions[k]; - float f = pathpoint1.distanceManhattan(pathpoint2); - pathpoint2.distanceFromOrigin = pathpoint1.distanceFromOrigin + f; - pathpoint2.cost = f + pathpoint2.costMalus; - float f1 = pathpoint1.totalPathDistance + pathpoint2.cost; - - if(pathpoint2.distanceFromOrigin < range && (!pathpoint2.isAssigned() || f1 < pathpoint2.totalPathDistance)){ - - pathpoint2.previous = pathpoint1; - pathpoint2.totalPathDistance = f1; - pathpoint2.distanceToNext = pathpoint2.distanceManhattan(end) + pathpoint2.costMalus; - - if(pathpoint2.isAssigned()){ - this.path.changeDistance(pathpoint2, pathpoint2.totalPathDistance + pathpoint2.distanceToNext); - }else{ - pathpoint2.distanceToTarget = pathpoint2.totalPathDistance + pathpoint2.distanceToNext; - this.path.addPoint(pathpoint2); - } - } - } - } - - if(pathpoint == start){ - return null; - }else{ - Path path = this.createEntityPath(start, pathpoint); - return path; - } - } - - /** - * Returns a new PathEntity for a given start and end point - */ - private Path createEntityPath(PathPoint start, PathPoint end){ - - int i = 1; - - for(PathPoint pathpoint = end; pathpoint.previous != null; pathpoint = pathpoint.previous){ - ++i; - } - - PathPoint[] points = new PathPoint[i]; - PathPoint pathpoint1 = end; - --i; - - for(points[i] = end; pathpoint1.previous != null; points[i] = pathpoint1){ - pathpoint1 = pathpoint1.previous; - --i; - } - - return new Path(points); - } -} \ No newline at end of file diff --git a/src/main/java/electroblob/wizardry/util/WizardryUtilities.java b/src/main/java/electroblob/wizardry/util/WizardryUtilities.java deleted file mode 100644 index 1d84a83d..00000000 --- a/src/main/java/electroblob/wizardry/util/WizardryUtilities.java +++ /dev/null @@ -1,976 +0,0 @@ -package electroblob.wizardry.util; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Random; -import java.util.UUID; -import java.util.function.Function; - -import javax.annotation.Nullable; - -import org.apache.commons.lang3.tuple.ImmutablePair; - -import electroblob.wizardry.CommonProxy; -import electroblob.wizardry.WizardData; -import electroblob.wizardry.Wizardry; -import electroblob.wizardry.constants.Element; -import electroblob.wizardry.constants.Tier; -import electroblob.wizardry.entity.living.ISummonedCreature; -import electroblob.wizardry.registry.WizardryItems; -import electroblob.wizardry.registry.WizardryPotions; -import electroblob.wizardry.spell.MindControl; -import electroblob.wizardry.spell.Spell; -import net.minecraft.block.state.IBlockState; -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLiving; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.monster.EntityCreeper; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.inventory.EntityEquipmentSlot; -import net.minecraft.inventory.EntityEquipmentSlot.Type; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTBase; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.network.datasync.DataParameter; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.DamageSource; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.SoundCategory; -import net.minecraft.util.SoundEvent; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.ReflectionHelper; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -/** This class contains some useful static methods for use anywhere - items, entities, spells, events, blocks, etc. - * Broadly speaking, these fall into the following categories: - *

    - * - In-world utilities (position calculating, retrieving entities, etc.)
    - * - Raytracing
    - * - Drawing utilities (client-only)
    - * - NBT and data storage utilities
    - * - Interaction with the ally designation system
    - * - Loot and weighting utilities - * @see CommonProxy - * @see WandHelper - * @since Wizardry 1.0 - * @author Electroblob */ -public final class WizardryUtilities { - - /** Constant which is simply an array of the four armour slots. (Could've sworn this exists somewhere in - * vanilla, but I can't find it anywhere...) */ - public static final EntityEquipmentSlot[] ARMOUR_SLOTS; - /** Changed to a constant in wizardry 2.1, since this is a lot more efficient. */ - private static final DataParameter POWERED; - - static { - // The list of slots needs to be mutable. - List slots = new ArrayList(Arrays.asList(EntityEquipmentSlot.values())); - slots.removeIf(slot -> slot.getSlotType() != Type.ARMOR); - ARMOUR_SLOTS = slots.toArray(new EntityEquipmentSlot[0]); - - // Null is passed in deliberately since POWERED is a static field. - POWERED = ReflectionHelper.getPrivateValue(EntityCreeper.class, null, "POWERED", "field_184714_b"); - } - - // SECTION Block/Entity/World Utilities - // =============================================================================================================== - - /** - * Returns whether the block at the given coordinates can be replaced by another one (works as if a block is being placed by a player). - * True for air, liquids, vines, tall grass and snow layers but not for flowers, signs etc. - * This is a shortcut for world.getBlockState(pos).getMaterial().isReplaceable(). - * @see WizardryUtilities#canBlockBeReplacedB(World, BlockPos) - */ - public static boolean canBlockBeReplaced(World world, BlockPos pos){ - return world.isAirBlock(new BlockPos(pos)) || world.getBlockState(pos).getMaterial().isReplaceable(); - } - - /** - * Returns whether the block at the given coordinates can be replaced by another one (works as if a block is being placed by a player) - * and is not a liquid. - * True for air, vines, tall grass and snow layers but not for flowers, signs etc. or any liquids. - * @see WizardryUtilities#canBlockBeReplaced(World, BlockPos) - */ - public static boolean canBlockBeReplacedB(World world, BlockPos pos){ - return canBlockBeReplaced(world, pos) && !world.getBlockState(pos).getMaterial().isLiquid(); - } - - /** - * Returns whether the block at the given coordinates is unbreakable in survival mode. In vanilla this is true for - * bedrock and end portal frame, for example. - * This is a shortcut for world.getBlockState(pos).getBlockHardness(world, pos) == -1.0f. - * Not much of a shortcut any more, since block ids have been phased out. - */ - public static boolean isBlockUnbreakable(World world, BlockPos pos){ - return world.isAirBlock(new BlockPos(pos)) ? false : world.getBlockState(pos).getBlockHardness(world, pos) == -1.0f; - } - - /** - * Finds the nearest floor level to the given y coord within the range specified at the given x and z coords. - * Liquids and other blocks that cannot be built on top of do not count, but stuff like signs does. - * (Technically any block is allowed to be the floor according to the code, but seeing as it searches upwards and - * non-solid blocks usually need a supporting block, the floor is likely to always be solid). - * @param world - * @param x The x coordinate to search in - * @param y The y coordinate to search from - * @param z The z coordinate to search in - * @param range The maximum distance from the given y coordinate to search. - * @return The y coordinate of the closest floor level, or -1 if there is none. Returns the actual level of the floor - * as would be seen in the debug screen when the player is standing on it. - * @see WizardryUtilities#getNearestFloorLevelB(World, BlockPos, int) - */ - public static int getNearestFloorLevel(World world, BlockPos pos, int range){ - - int yCoord = -2; - for(int i = -range; i <= range; i++){ - // The last bit determines whether the block found to be a suitable floor is closer than the previous one found. - if(world.isSideSolid(pos.up(i), EnumFacing.UP) && (world.isAirBlock(pos.up(i+1)) || !world.isSideSolid(pos.up(i+1), EnumFacing.UP)) - && (i < yCoord-pos.getY() || yCoord == -2)){ - yCoord = pos.getY() + i; - } - } - return yCoord + 1; - } - - /** - * Finds the nearest floor level to the given y coord within the range specified at the given x and z coords. - * Only works if the block above the floor is actually air and the floor is solid or a liquid. - * @param world - * @param x The x coordinate to search in - * @param y The y coordinate to search from - * @param z The z coordinate to search in - * @param range The maximum distance from the given y coordinate to search. - * @return The y coordinate of the closest floor level, or -1 if there is none. Returns the actual level of the floor - * as would be seen in the debug screen when the player is standing on it. - * @see WizardryUtilities#getNearestFloorLevel(World, BlockPos, int) - */ - public static int getNearestFloorLevelB(World world, BlockPos pos, int range){ - int yCoord = -2; - for(int i = -range; i <= range; i++){ - if(world.isAirBlock(new BlockPos(pos.up(i+1))) && (world.getBlockState(pos.up(i)).getMaterial().isLiquid() || world.isSideSolid(pos.up(i), EnumFacing.UP)) - && (i < yCoord-pos.getY() || yCoord == -2)){ - // The last bit determines whether the block found to be a suitable floor is closer than the previous one found. - yCoord = pos.getY() + i; - } - } - return yCoord + 1; - } - - /** - * Finds the nearest floor level to the given y coord within the range specified at the given x and z coords. - * Everything that is not air is treated as floor, even stuff that can't be walked on. - * @param world - * @param x The x coordinate to search in - * @param y The y coordinate to search from - * @param z The z coordinate to search in - * @param range The maximum distance from the given y coordinate to search. - * @return The y coordinate of the closest floor level, or -1 if there is none. Returns the actual level of the floor - * as would be seen in the debug screen when the player is standing on it. - * @see WizardryUtilities#getNearestFloorLevel(World, BlockPos, int) - */ - public static int getNearestFloorLevelC(World world, BlockPos pos, int range){ - int yCoord = -2; - for(int i = -range; i <= range; i++){ - if(world.isAirBlock(new BlockPos(pos.up(i+1))) && (i < yCoord-pos.getY() || yCoord == -2)){ - // The last bit determines whether the block found to be a suitable floor is closer than the previous one found. - yCoord = pos.getY() + i; - } - } - return yCoord + 1; - } - - /** - * Gets a random position on the ground near the player within the specified horizontal and vertical ranges. Used - * to find a position to spawn entities in summoning spells. - * @param entity The entity around which to search - * @param horizontalRange The maximum number of blocks on the x or z axis the returned position can be from the - * given entity. The number of operations performed by this method is proportional to the square of this - * parameter, so for performance reasons it is recommended that it does not exceed around 10. - * @param verticalRange The maximum number of blocks on the y axis the returned position can be from the given - * entity - * @return A BlockPos with the coordinates of the block directly above the ground at the position found, or null - * if none were found within range. Importantly, since this method checks all possible positions within - * range (i.e. randomness only occurs when deciding between the possible positions), if it returns null once - * then it will always return null given the same circumstances and parameters. What this means is that you can - * (and should) immediately stop trying to cast a summoning spell if this returns null. - */ - @Nullable - public static BlockPos findNearbyFloorSpace(Entity entity, int horizontalRange, int verticalRange){ - - World world = entity.worldObj; - List possibleLocations = new ArrayList(); - BlockPos origin = new BlockPos(entity); - - for(int x = -horizontalRange; x <= horizontalRange; x++){ - for(int z = -horizontalRange; z <= horizontalRange; z++){ - int y = WizardryUtilities.getNearestFloorLevel(world, origin.add(x, 0, z), verticalRange); - if(y > -1) possibleLocations.add(new BlockPos(origin.getX() + x, y, origin.getZ() + z)); - } - } - - if(possibleLocations.isEmpty()){ - return null; - }else{ - return possibleLocations.get(world.rand.nextInt(possibleLocations.size())); - } - - } - - /** - * Gets the blockstate of the block the specified entity is standing on. Uses {@link MathHelper#floor_double(double)} because casting to int will not - * return the correct coordinate when x or z is negative. - */ - public static IBlockState getBlockEntityIsStandingOn(Entity entity){ - BlockPos pos = new BlockPos(MathHelper.floor_double(entity.posX), (int)entity.getEntityBoundingBox().minY-1, MathHelper.floor_double(entity.posZ)); - return entity.worldObj.getBlockState(pos); - } - - /** - * Shorthand for {@link WizardryUtilities#getEntitiesWithinRadius(double, double, double, double, World, Class)} - * with EntityLivingBase as the entity type. This is by far the most common use for that method, which is why this - * shorthand exists. - * @param radius The search radius - * @param x The x coordinate to search around - * @param y The y coordinate to search around - * @param z The z coordinate to search around - * @param world The world to search in - */ - public static List getEntitiesWithinRadius(double radius, double x, double y, double z, World world){ - return getEntitiesWithinRadius(radius, x, y, z, world, EntityLivingBase.class); - } - - /** - * Returns all entities of the specified type within the specified radius of the given coordinates. This is different to using - * a raw AABB because a raw AABB will search in a cube volume rather than a sphere. - * Note that this does not exclude any entities; if any specific entities are to be excluded this must be - * checked when iterating through the list. - * @see {@link WizardryUtilities#getEntitiesWithinRadius(double, double, double, double, World)} - * @param radius The search radius - * @param x The x coordinate to search around - * @param y The y coordinate to search around - * @param z The z coordinate to search around - * @param world The world to search in - * @param entityType The class of entity to search for; pass in Entity.class for all entities - */ - public static List getEntitiesWithinRadius(double radius, double x, double y, double z, World world, Class entityType){ - AxisAlignedBB aabb = new AxisAlignedBB(x - radius, y - radius, z - radius, x + radius, y + radius, z + radius); - List entityList = world.getEntitiesWithinAABB(entityType, aabb); - for(int i=0;i radius){ - entityList.remove(i); - } - } - return entityList; - } - - /** - * Gets an entity from its UUID. Note that you should check this isn't null. If the UUID is known to belong - * to an EntityPlayer, use the more efficient {@link World#getPlayerEntityByUUID(UUID)} instead. - * @param world The world the entity is in - * @param id The entity's UUID - * @return The Entity that has the given UUID, or null if no such entity exists in the specified world. - */ - @Nullable - public static Entity getEntityByUUID(World world, UUID id){ - - for(Entity entity : world.loadedEntityList){ - // This is a perfect example of where you need to use .equals() and not ==. For most applications, - // this was unnoticeable until world reload because the UUID instance or entity instance is stored. - // Fixed now though. - if(entity.getUniqueID().equals(id)){ - return entity; - } - } - return null; - } - - // No point allowing anything other than players for these methods since other entities can use Entity#playSound. - - /** Shortcut for {@link World#playSound(EntityPlayer, double, double, double, SoundEvent, SoundCategory, float, float)} - * where the player is null but the x, y and z coordinates are those of the passed in player. Use in preference to - * {@link EntityPlayer#playSound(SoundEvent, float, float)} if there are client-server discrepancies. */ - public static void playSoundAtPlayer(EntityPlayer player, SoundEvent sound, SoundCategory category, float volume, float pitch){ - player.worldObj.playSound(null, player.posX, player.posY, player.posZ, sound, category, volume, pitch); - } - - /** See {@link WizardryUtilities#playSoundAtPlayer(EntityPlayer, SoundEvent, SoundCategory, float, float)}. Category - * defaults to {@link SoundCategory#PLAYERS}. */ - public static void playSoundAtPlayer(EntityPlayer player, SoundEvent sound, float volume, float pitch){ - player.worldObj.playSound(null, player.posX, player.posY, player.posZ, sound, SoundCategory.PLAYERS, volume, pitch); - } - - /** - * Returns the entity riding the given entity, or null if there is none. Allows for neater code now that - * entities have a list of passengers, because it is necessary to check that the list is not null or empty first. - */ - @Nullable - public static Entity getRider(Entity entity){ - return entity.getPassengers() != null && !entity.getPassengers().isEmpty() ? entity.getPassengers().get(0) : null; - } - - /** - * Attacks the given entity with the given damage source and amount, but preserving the entity's original velocity - * instead of applying knockback, as would happen with {@link EntityLivingBase#attackEntityFrom(DamageSource, float)} - * (More accurately, calls that method as normal and then resets the entity's velocity to what it was before). - * Handy for when you need to damage an entity repeatedly in a short space of time. - * @param entity The entity to attack - * @param source The source of the damage - * @param amount The amount of damage to apply - * @return True if the attack succeeded, false if not. - */ - public static boolean attackEntityWithoutKnockback(Entity entity, DamageSource source, float amount){ - double vx = entity.motionX; double vy = entity.motionY; double vz = entity.motionZ; - boolean succeeded = entity.attackEntityFrom(source, amount); - entity.motionX = vx; entity.motionY = vy; entity.motionZ = vz; - return succeeded; - } - - /** - * Applies the standard (non-enchanted) amount of knockback to the given target, using the same calculation as - * {@link EntityLivingBase#attackEntityFrom(DamageSource, float)}. Use in conjunction with - * {@link WizardryUtilities#attackEntityWithoutKnockback(Entity, DamageSource, float)} to change the source of - * knockback for an attack. - * @param attacker The entity that caused the knockback; the target will be pushed away from this entity. - * @param target The entity to be knocked back. - */ - public static void applyStandardKnockback(Entity attacker, EntityLivingBase target){ - double dx = attacker.posX - target.posX; - double dz; - for(dz = attacker.posZ - target.posZ; dx * dx + dz * dz < 1.0E-4D; dz = (Math.random() - Math.random()) * 0.01D){ - dx = (Math.random() - Math.random()) * 0.01D; - } - // The first argument is never used. - target.knockBack(null, 0.4f, dx, dz); - } - - // Just what benefit does having posY be the eye position on the first person client actually give? - - /** - * Gets the y coordinate of the given player's eyes. This is to cover an inconsistency between the value of - * EntityPlayer.posY on the first person client and everywhere else; in first person (i.e. when - * Minecraft.getMinecraft().thePlayer == player) player.posY is the eye position, but everywhere else it is the - * feet position. This is intended for use when spawning particles, since this is the only situation where the - * discrepancy is likely to matter. - *

    - * As of Wizardry 1.2, this is just a shorthand for:

    - *

    player.getEntityBoundingBox().minY + player.getEyeHeight()
    - */ - public static double getPlayerEyesPos(EntityPlayer player){ - return player.getEntityBoundingBox().minY + player.getEyeHeight(); - } - - /** Returns a list of the itemstacks in the given player's hotbar. Defined here for convenience and to - * centralise the (unfortunately unavoidable) use of hardcoded numbers to reference the inventory slots. The - * returned list is a modifiable copy of part of the player's inventory stack list; as such, changes to the list - * are not written through to the player's inventory. However, the ItemStack instances themselves are not - * copied, so changes to any of their fields (size, metadata...) will change those in the player's inventory. - * @since Wizardry 1.2 */ - public static List getHotbar(EntityPlayer player){ - return new ArrayList(Arrays.asList(player.inventory.mainInventory).subList(0, 9)); - } - - /** Returns a list of the itemstacks in the given player's hotbar and offhand, sorted into the following order: - * main hand, offhand, rest of hotbar left-to-right. The returned list is a modifiable copy of part of the player's - * inventory stack list; as such, changes to the list are not written through to the player's inventory. - * However, the ItemStack instances themselves are not copied, so changes to any of their fields (size, metadata...) - * will change those in the player's inventory. - * @since Wizardry 1.2 */ - public static List getPrioritisedHotbarAndOffhand(EntityPlayer player){ - List hotbar = WizardryUtilities.getHotbar(player); - // Adds the offhand item to the beginning of the list so it is processed before the hotbar - hotbar.add(0, player.getHeldItemOffhand()); - // Moves the item in the main hand to the beginning of the list so it is processed first - hotbar.remove(player.getHeldItemMainhand()); - hotbar.add(0, player.getHeldItemMainhand()); - return hotbar; - } - - /** Tests whether the specified player has any of the specified item in their entire inventory, including armour - * slots and offhand. */ - public static boolean doesPlayerHaveItem(EntityPlayer player, Item item){ - - for(ItemStack stack : player.inventory.mainInventory){ - if(stack != null && stack.getItem() == item){ - return true; - } - } - - for(ItemStack stack : player.inventory.armorInventory){ - if(stack != null && stack.getItem() == item){ - return true; - } - } - - for(ItemStack stack : player.inventory.offHandInventory){ - if(stack != null && stack.getItem() == item){ - return true; - } - } - - return false; - } - - /** Checks if the given player is opped on the given server. If the server is a singleplayer or LAN server, this - * means they have cheats enabled. */ - public static boolean isPlayerOp(EntityPlayer player, MinecraftServer server){ - return server.getPlayerList().getOppedPlayers().getEntry(player.getGameProfile()) != null; - } - - /** Turns the given creeper into a charged creeper. In 1.10, this requires reflection since the DataManager keys - * are private. (You could call {@link EntityCreeper#onStruckByLightning(...)} and then heal it and - * extinguish it, but that's a bit awkward.) */ - public static void chargeCreeper(EntityCreeper creeper){ - creeper.getDataManager().set(POWERED, true); - } - - // SECTION Raytracing - // =============================================================================================================== - - /** - * Does a block ray trace (NOT entities) from an entity's eyes (i.e. properly...) - */ - @Nullable - public static RayTraceResult rayTrace(double range, World world, EntityLivingBase entity, boolean hitLiquids){ - - Vec3d start = new Vec3d(entity.posX, entity.getEntityBoundingBox().minY + entity.getEyeHeight(), entity.posZ); - Vec3d look = entity.getLookVec(); - Vec3d end = start.addVector(look.xCoord * range, look.yCoord * range, look.zCoord * range); - return world.rayTraceBlocks(start, end, hitLiquids); - } - - /** - * Helper method which does a rayTrace for entities from an entity's eye level in the direction they are looking - * with a specified range, using the tracePath method. Tidies up the code a bit. Border size defaults to 1. - * - * @param world - * @param entity - * @param range - * @return - */ - @Nullable - public static RayTraceResult standardEntityRayTrace(World world, EntityLivingBase entity, double range){ - double dx = entity.getLookVec().xCoord * range; - double dy = entity.getLookVec().yCoord * range; - double dz = entity.getLookVec().zCoord * range; - HashSet hashset = new HashSet(1); - hashset.add(entity); - return WizardryUtilities.tracePath(world, (float)entity.posX, (float)(entity.getEntityBoundingBox().minY + entity.getEyeHeight()), (float)entity.posZ, (float)(entity.posX + dx), (float)(entity.posY + entity.getEyeHeight() + dy), (float)(entity.posZ + dz), 1.0f, hashset, false); - } - - /** - * Helper method which does a rayTrace for entities from a entity's eye level in the direction they are looking - * with a specified range and radius, using the tracePath method. Tidies up the code a bit. - * - * @param world - * @param entity - * @param range - * @param borderSize - * @return - */ - @Nullable - public static RayTraceResult standardEntityRayTrace(World world, EntityLivingBase entity, double range, float borderSize){ - double dx = entity.getLookVec().xCoord * range; - double dy = entity.getLookVec().yCoord * range; - double dz = entity.getLookVec().zCoord * range; - HashSet hashset = new HashSet(1); - hashset.add(entity); - return WizardryUtilities.tracePath(world, (float)entity.posX, (float)(entity.getEntityBoundingBox().minY + entity.getEyeHeight()), (float)entity.posZ, (float)(entity.posX + dx), (float)(entity.posY + entity.getEyeHeight() + dy), (float)(entity.posZ + dz), borderSize, hashset, false); - } - - /** - * Method for ray tracing entities (the useless default method doesn't work, despite EnumHitType having an ENTITY field...) - * You can also use this for seeking. - * - * @param world - * @param x startX - * @param y startY - * @param z startZ - * @param tx endX - * @param ty endY - * @param tz endZ - * @param borderSize extra area to examine around line for entities - * @param excluded any excluded entities (the player, etc) - * @return a RayTraceResult of either the block hit (no entity hit), the entity hit (hit an entity), or null for nothing hit - */ - @Nullable - public static RayTraceResult tracePath(World world, float x, float y, float z, float tx, float ty, float tz, float borderSize, HashSet excluded, boolean collideablesOnly){ - - Vec3d startVec = new Vec3d(x, y, z); - //Vec3d lookVec = new Vec3d(tx-x, ty-y, tz-z); - Vec3d endVec = new Vec3d(tx, ty, tz); - float minX = x < tx ? x : tx; - float minY = y < ty ? y : ty; - float minZ = z < tz ? z : tz; - float maxX = x > tx ? x : tx; - float maxY = y > ty ? y : ty; - float maxZ = z > tz ? z : tz; - AxisAlignedBB bb = new AxisAlignedBB(minX, minY, minZ, maxX, maxY, maxZ).expand(borderSize, borderSize, borderSize); - List allEntities = world.getEntitiesWithinAABBExcludingEntity(null, bb); - RayTraceResult blockHit = world.rayTraceBlocks(startVec, endVec); - startVec = new Vec3d(x, y, z); - endVec = new Vec3d(tx, ty, tz); - float maxDistance = (float) endVec.distanceTo(startVec); - if(blockHit!=null) - { - maxDistance = (float) blockHit.hitVec.distanceTo(startVec); - } - Entity closestHitEntity = null; - float closestHit = maxDistance; - float currentHit = 0.f; - AxisAlignedBB entityBb;// = ent.getBoundingBox(); - RayTraceResult intercept; - for(Entity ent : allEntities) - { - if((ent.canBeCollidedWith() || !collideablesOnly) && ((excluded != null && !excluded.contains(ent)) || excluded == null)) - { - float entBorder = ent.getCollisionBorderSize(); - entityBb = ent.getEntityBoundingBox(); - if(entityBb!=null) - { - entityBb = entityBb.expand(entBorder, entBorder, entBorder); - intercept = entityBb.calculateIntercept(startVec, endVec); - if(intercept!=null) - { - currentHit = (float) intercept.hitVec.distanceTo(startVec); - if(currentHit < closestHit || currentHit==0) - { - closestHit = currentHit; - closestHitEntity = ent; - } - } - } - } - } - if(closestHitEntity!=null) - { - blockHit = new RayTraceResult(closestHitEntity); - } - return blockHit; - } - - // SECTION Rendering and GUIs - // =============================================================================================================== - - // Doesn't seem right to put this in the proxies since it should only ever be called from client-side code, and I'm - // not about to make a whole separate utilities class just for one method. Fully qualified names it is! - /** - * [Client-side only] Draws a textured rectangle, taking the size of the image and the bit needed into - * account, unlike {@link net.minecraft.client.gui.Gui#drawTexturedModalRect(int, int, int, int, int, int) - * Gui.drawTexturedModalRect(int, int, int, int, int, int)}, which is harcoded for only 256x256 textures. Also - * handy for custom potion icons. - * @param x The x position of the rectangle - * @param y The y position of the rectangle - * @param u The x position of the top left corner of the section of the image wanted - * @param v The y position of the top left corner of the section of the image wanted - * @param width The width of the section - * @param height The height of the section - * @param textureWidth The width of the actual image. - * @param textureHeight The height of the actual image. - */ - @SideOnly(Side.CLIENT) - public static void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight){ - - float f = 1F / (float)textureWidth; - float f1 = 1F / (float)textureHeight; - - // Essentially the same as getting the tessellator. For most code, you'll want the tessellator AND the vertexbuffer - // stored in local variables. - net.minecraft.client.renderer.VertexBuffer buffer = net.minecraft.client.renderer.Tessellator.getInstance().getBuffer(); - // Equivalent of tessellator.startDrawingQuads() - buffer.begin(org.lwjgl.opengl.GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); - // Equivalent of tessellator.addVertex() - buffer.pos((double)(x), (double)(y + height), 0).tex((double)((float)(u) * f), (double)((float)(v + height) * f1)).endVertex(); - buffer.pos((double)(x + width), (double)(y + height), 0).tex((double)((float)(u + width) * f), (double)((float)(v + height) * f1)).endVertex(); - buffer.pos((double)(x + width), (double)(y), 0).tex((double)((float)(u + width) * f), (double)((float)(v) * f1)).endVertex(); - buffer.pos((double)(x), (double)(y), 0).tex((double)((float)(u) * f), (double)((float)(v) * f1)).endVertex(); - // Exactly the same as before. - net.minecraft.client.renderer.Tessellator.getInstance().draw(); - } - - /** Shorthand for {@link WizardryUtilities#drawTexturedRect(int, int, int, int, int, int, int, int)} which draws - * the entire texture (u and v are set to 0 and textureWidth and textureHeight are the same as width and height). */ - @SideOnly(Side.CLIENT) - public static void drawTexturedRect(int x, int y, int width, int height){ - drawTexturedRect(x, y, 0, 0, width, height, width, height); - } - - // SECTION NBT and Data Storage - // =============================================================================================================== - - /** - * Verifies that the given string is a valid string representation of a UUID. More specifically, returns true if and - * only if the given string is not null and matches the regular expression:

    - *

    /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/

    - * which is the regex equivalent of the standard string representation of a UUID as described in {@link UUID#toString()}. - * This method is intended to be used as a check to prevent an {@link IllegalArgumentException} from occurring when - * calling {@link UUID#fromString(String)}. - * @param string The string to be checked - * @return Whether the given string is a valid string representation of a UUID - * @deprecated UUIDs can now be stored in NBT directly; use that in preference to storing them as strings. - */ - @Deprecated - public static boolean verifyUUIDString(String string){ - return string != null && string.matches("/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/"); - } - - /** Generic method that stores any Map to an NBTTagList, given two functions that convert the key and value - * types in that map to subclasses of NBTBase. For what it's worth, there is very little point in using this unless - * you can use something more concise than an anonymous class to do the conversion. A lambda expression, or better, - * a method reference, would fit nicely. For example, take ExtendedPlayer's use of this to store conjured item - * durations: - *

    - * properties.setTag("conjuredItems", WizardryUtilities.mapToNBT(this.conjuredItemDurations, - * item -> new NBTTagInt(Item.getIdFromItem((Item)item)), NBTTagInt::new)); - *

    - * This is a lot nicer than simply iterating through the map, because for that you need to use the entry list, - * which introduces local variables that aren't really necessary. Notice that, since the values V in the map are - * simply Integer objects, a simple constructor reference to NBTTagInt::new can be used instead of a lambda - * expression (the Integer is auto-unboxed to int). - * - * @param The type of key stored in the given Map. - * @param The type of value stored in the given Map. - * @param The subtype of NBTBase that the keys (of type K) will be converted to. - * @param The subtype of NBTBase that the values (of type V) will be converted to. - * @param map The Map to be stored. - * @param keyFunction A Function that converts the keys in the map to NBT objects that can be stored. - * @param valueFunction A Function that converts the values in the map to NBT objects that can be stored. - * @param keyTagName The tag name to use for the key tags. - * @param valueTagName The tag name to use for the value tags. - * @return An NBTTagList that represents the given Map. - */ - public static NBTTagList mapToNBT(Map map, Function keyFunction, Function valueFunction, String keyTagName, String valueTagName){ - - NBTTagList tagList = new NBTTagList(); - - for(Entry entry : map.entrySet()){ - NBTTagCompound mapping = new NBTTagCompound(); - mapping.setTag(keyTagName, keyFunction.apply(entry.getKey())); - mapping.setTag(valueTagName, valueFunction.apply(entry.getValue())); - tagList.appendTag(mapping); - } - - return tagList; - } - - /** See {@link WizardryUtilities#mapToNBT(Map, Function, Function, String, String)}; this version is for when the - * names of the individual key/value tags are unimportant (they default to "key" and "value" respectively). */ - public static NBTTagList mapToNBT(Map map, Function keyFunction, Function valueFunction){ - return mapToNBT(map, keyFunction, valueFunction, "key", "value"); - } - - /** Generic method that reads a Map from an NBTTagList, given two functions that convert the key and value tag types - * into the key and value types in the returned map. The given NBTTagList remains unchanged after calling this method. - * - * @param The type of key stored in the returned Map. - * @param The type of value stored in the returned Map. - * @param The subtype of NBTBase that the keys are stored as. - * @param The subtype of NBTBase that the values are stored as. - * @param tagList The NBTTagList to be converted. This must be a list of compound tags. - * @param keyFunction A Function that converts the generic NBTBase tags in the list to keys of type K for the map. - * @param valueFunction A Function that converts the generic NBTBase tags in the list to values of type V for the map. - * @param keyTagName The tag name used for the key tags. - * @param valueTagName The tag name used for the value tags. - * @return A Map containing the keys and values stored in the given NBTTagList. Can be empty, but not null. - * @throws ClassCastException If the tags are not of the expected type. - * @see WizardryUtilities#mapToNBT(Map, Function, Function, String, String) - */ - @SuppressWarnings("unchecked") // Intentional, because throwing an exception is appropriate here. - public static Map NBTToMap(NBTTagList tagList, Function keyFunction, Function valueFunction, String keyTagName, String valueTagName){ - - Map map = new HashMap(); - - for(int i=0; i Map NBTToMap(NBTTagList tagList, Function keyFunction, Function valueFunction){ - return NBTToMap(tagList, keyFunction, valueFunction, "key", "value"); - } - - /** Generic method that stores any Collection to an NBTTagList, given a function that converts the elements in - * that collection to subclasses of NBTBase. For what it's worth, there is very little point in using this unless - * you can use something more concise than an anonymous class to do the conversion. A lambda expression, or better, - * a method reference, would fit nicely. - * - * @param The type of element stored in the given Collection. - * @param The NBT tag type that the elements will be converted to. - * @param list The Collection to be stored. - * @param function A Function that converts the elements in the collection to NBT objects that can be stored. - * @return An NBTTagList that represents the given Collection. - */ - public static NBTTagList listToNBT(Collection list, Function function){ - - NBTTagList tagList = new NBTTagList(); - // If the collection is ordered, it will preserve the order, even though we don't know what type it is yet. - for(E element : list){ - tagList.appendTag(function.apply(element)); - } - - return tagList; - } - - /** Generic method that reads a Collection from an NBTTagList, given a function that converts the element tag - * types to the element types in the returned collection. The given NBTTagList remains unchanged after calling this - * method. Unless the target variable for this method is of type Collection, you will need to create a new - * collection containing the elements in the returned collection via that collection's constructor (e.g. {@code new - * HashSet(collection)}). Although this method returns a Collection rather than any of its subtypes, it - * uses an ArrayList internally to guarantee the order of the elements in the returned collection is the same - * as the order in which they were stored. As such, you may safely cast to List should you wish. - * - * @param The type of element stored in the returned Collection. - * @param The subtype of NBTBase that the elements are stored as. - * @param tagList The NBTTagList to be converted. - * @param function A Function that converts the generic NBTBase tags in the list to elements for the collection. - * Chances are you will need to cast the NBTBase tag to whichever NBT tag type you are expecting in order to - * access the appropriate getter method. - * @return A Collection containing the elements stored in the given NBTTagList. Can be empty, but not null. - * @throws ClassCastException If the tags are not of the expected type. - */ - @SuppressWarnings("unchecked") // Intentional, because throwing an exception is appropriate here. - public static Collection NBTToList(NBTTagList tagList, Function function){ - // Uses an ArrayList to guarantee iteration order, and also to permit duplicate elements (which are - // perfectly reasonable in this context). - Collection list = new ArrayList(); - // The original tag list should remain unchanged, hence the copy. - NBTTagList tagList2 = (NBTTagList) tagList.copy(); - - while(!tagList2.hasNoTags()){ - NBTBase tag = tagList2.removeTag(0); - // Why oh why is NBTTagList not parametrised? It even has a tagType field, so it must know! - try { list.add(function.apply((T)tag)); } catch (ClassCastException e){ - Wizardry.logger.error("Error when reading list from NBT: unexpected tag type " + NBTBase.NBT_TYPES[tag.getId()], e); - } - } - - return list; - - } - - // TODO: Backport: It has recently become apparent that storing UUIDs as strings is not good practice, so backport these two - // methods to 1.7.10 and replace tag.setUniqueId and tag.getUniqueId with their respective contents from 1.10.2. - - /** Returns an NBTTagCompound which contains only the given UUID, stored using - * {@link NBTTagCompound#setUniqueId(String, UUID)}. Allows for neater storage to NBTTagLists. */ - public static NBTTagCompound UUIDtoTagCompound(UUID id){ - NBTTagCompound tag = new NBTTagCompound(); - tag.setUniqueId("uuid", id); - return tag; - } - - /** Wrapper for {@link NBTTagCompound#getUniqueId(String)} which converts an NBTTagCompound directly to a UUID. - * Intended to be used as the inverse of {@link WizardryUtilities#UUIDtoTagCompound(UUID)}.*/ - public static UUID tagCompoundToUUID(NBTTagCompound tag){ - return tag.getUniqueId("uuid"); - } - - // SECTION Ally Designation System - // =============================================================================================================== - - /** - * Returns whether the given target can be attacked by the given attacker. It is up to the caller of this method - * to work out what this means; it doesn't necessarily mean the target is completely immune (for example, revenge - * targeting might reasonably bypass this). This method is intended for use where the damage is indirect and/or - * unavoidable; direct attacks should not check this method. Currently this means the following situations check - * this method: - *

    - * - AI targeting for summoned creatures
    - * - AI targeting for mind-controlled creatures
    - * - Constructs with an area of effect
    - * - Instantaneous spells with an area of effect around the caster (e.g. forest's curse, thunderstorm)
    - * - Any lightning chaining effects
    - * - Any projectiles which seek targets - *

    - * Also note that the friendly fire option is dealt with - * in the event handler. This method acts as a sort of wrapper for all the ADS stuff in {@link WizardData}; more - * details about the ally designation system can be found there. - * - * @param attacker The entity that cast the spell originally - * @param target The entity being attacked - * - * @return False under any of the following circumstances, true otherwise: - *

    - * - Either entity is null - *

    - * - The target is the attacker (this isn't as stupid as it sounds - anything with an AoE might cause this to be - * true, as can summoned creatures) - *

    - * - The target and the attacker are both players and the target is an ally of the attacker (but the - * attacker need not be an ally of the target) - *

    - * - The target is a creature that was summoned/controlled by the attacker or by an ally of the attacker. - */ - public static boolean isValidTarget(Entity attacker, Entity target){ - - if(attacker == null || target == null) return false; - - // Tests whether the target is the attacker - if(target == attacker) return false; - - // Tests whether the target is a creature that was summoned by the attacker - if(target instanceof ISummonedCreature && ((ISummonedCreature)target).getCaster() == attacker){ - return false; - } - - // Tests whether the target is a creature that was mind controlled by the attacker - if(target instanceof EntityLiving && ((EntityLivingBase)target).isPotionActive(WizardryPotions.mind_control)){ - - NBTTagCompound entityNBT = target.getEntityData(); - - if(entityNBT != null && entityNBT.hasKey(MindControl.NBT_KEY)){ - if(attacker == WizardryUtilities.getEntityByUUID(target.worldObj, entityNBT.getUniqueId(MindControl.NBT_KEY))){ - return false; - } - } - } - - // Ally section - if(attacker instanceof EntityPlayer && WizardData.get((EntityPlayer)attacker) != null){ - - if(target instanceof EntityPlayer){ - // Tests whether the target is an ally of the attacker - if(WizardData.get((EntityPlayer)attacker).isPlayerAlly((EntityPlayer)target)){ - return false; - } - - }else if(target instanceof ISummonedCreature){ - // Tests whether the target is a creature that was summoned by an ally of the attacker - if(((ISummonedCreature)target).getCaster() instanceof EntityPlayer - && WizardData.get((EntityPlayer)attacker).isPlayerAlly((EntityPlayer)((ISummonedCreature)target).getCaster())){ - return false; - } - - }else if(target instanceof EntityLiving && ((EntityLivingBase)target).isPotionActive(WizardryPotions.mind_control)){ - // Tests whether the target is a creature that was mind controlled by an ally of the attacker - NBTTagCompound entityNBT = target.getEntityData(); - - if(entityNBT != null && entityNBT.hasKey(MindControl.NBT_KEY)){ - - Entity controller = WizardryUtilities.getEntityByUUID(target.worldObj, entityNBT.getUniqueId(MindControl.NBT_KEY)); - - if(controller instanceof EntityPlayer && WizardData.get((EntityPlayer)attacker).isPlayerAlly((EntityPlayer)controller)){ - return false; - } - } - } - } - - return true; - } - - /** Helper method for testing if the second player is an ally of the first player. Makes the code neater. */ - public static boolean isPlayerAlly(EntityPlayer allyOf, EntityPlayer possibleAlly) { - - WizardData properties = WizardData.get(allyOf); - - if(properties != null && properties.isPlayerAlly(possibleAlly)) return true; - - return false; - } - - // SECTION Loot and Weighting - // =============================================================================================================== - - /** - * See {@link WizardryUtilities#getStandardWeightedRandomSpellId(Random, boolean)}. nonContinuous defaults to false. - */ - public static int getStandardWeightedRandomSpellId(Random random){ - return getStandardWeightedRandomSpellId(random, false); - } - - /** - * Helper method which gets a spell id according to the standard weighting. The tier is a weighted random value; - * the actual spell within that tier is completely random. Will not return the id of a spell which has been - * disabled in the config. This is for simple stuff like chests and drops; more complex generators like wizard - * trades don't use this method. - *

    - * For reference, the standard weighting is as follows: - * Basic: 60%, Apprentice: 25%, Advanced: 10%, Master: 5% - * - * @param random An instance of {@link Random} to use for RNG - * @param nonContinuous Whether the spells must be non-continuous (used for scrolls) - * @return A random spell id number - */ - public static int getStandardWeightedRandomSpellId(Random random, boolean nonContinuous){ - - Tier tier = Tier.getWeightedRandomTier(random); - - List spells = Spell.getSpells(new Spell.TierElementFilter(tier, null)); - if(nonContinuous) spells.retainAll(Spell.getSpells(Spell.nonContinuousSpells)); - - // Ensures the tier chosen actually has spells in it, and if not uses BASIC instead. - if(spells.isEmpty()){ - spells = Spell.getSpells(new Spell.TierElementFilter(Tier.BASIC, null)); - if(nonContinuous) spells.retainAll(Spell.getSpells(Spell.nonContinuousSpells)); - } - - // Finds a random spell in the list and returns its id. - return spells.get(random.nextInt(spells.size())).id(); - } - - // TODO: These methods need a rethink. What are we trying to achieve with them? Should each use case look in the same - // pool of items? For example, might we (or someone else) want to have a wand which can generate in chests, but is - // not used by wizards? - - // I reckon this should be strictly for cases where we only ever want the standard wand set, i.e. wizards' gear, etc. - - /** - * Helper method to return the appropriate armour item based on element and slot. As of Wizardry 2.1, this uses - * the immutable map stored in {@link WizardryItems#ARMOUR_MAP}. - * Currently used to iterate through armour for registering charging recipes and for chest generation. - * @param element The EnumElement of the armour required. Null will be converted to {@link Element#MAGIC}. - * @param slot EntityEquipmentSlot of the armour piece required - * @return The armour item which corresponds to the given element and slot, or null if no such item exists. - * @throws IllegalArgumentException if the given slot is not an armour slot. - */ - public static Item getArmour(Element element, EntityEquipmentSlot slot){ - if(slot == null || slot.getSlotType() != Type.ARMOR) throw new IllegalArgumentException("Must be a valid armour slot"); - if(element == null) element = Element.MAGIC; - return WizardryItems.ARMOUR_MAP.get(ImmutablePair.of(slot, element)); - } - - /** - * Helper method to return the appropriate wand based on tier and element.As of Wizardry 2.1, this uses - * the immutable map stored in {@link WizardryItems#WAND_MAP}. - * Currently used in the packet handler for upgrading wands, for chest generation and to iterate through - * wands for charging recipes. - * @param tier The tier of the wand required. - * @param element The element of the wand required. Null will be converted to {@link Element#MAGIC}. - * @return The wand item which corresponds to the given element and slot, or null if no such item exists. - * @throws NullPointerException if the given tier is null. - */ - public static Item getWand(Tier tier, Element element){ - if(tier == null) throw new NullPointerException("The given tier cannot be null."); - if(element == null) element = Element.MAGIC; - return WizardryItems.WAND_MAP.get(ImmutablePair.of(tier, element)); - } -} diff --git a/src/main/resources/assets/wizardry/blockstates/arcane_workbench.json b/src/main/resources/assets/wizardry/blockstates/arcane_workbench.json deleted file mode 100644 index c5741b8e..00000000 --- a/src/main/resources/assets/wizardry/blockstates/arcane_workbench.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "forge_marker": 1, - "variants": { - "normal": { "model": "wizardry:arcane_workbench" } - } -} diff --git a/src/main/resources/assets/wizardry/blockstates/crystal_block.json b/src/main/resources/assets/wizardry/blockstates/crystal_block.json deleted file mode 100644 index d5ed94e1..00000000 --- a/src/main/resources/assets/wizardry/blockstates/crystal_block.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "forge_marker": 1, - "variants": { - "normal": { "model": "wizardry:crystal_block" } - } -} diff --git a/src/main/resources/assets/wizardry/blockstates/crystal_flower.json b/src/main/resources/assets/wizardry/blockstates/crystal_flower.json deleted file mode 100644 index 61e2d72c..00000000 --- a/src/main/resources/assets/wizardry/blockstates/crystal_flower.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "variants": { - "normal": { "model": "wizardry:crystal_flower" } - } -} diff --git a/src/main/resources/assets/wizardry/blockstates/crystal_ore.json b/src/main/resources/assets/wizardry/blockstates/crystal_ore.json deleted file mode 100644 index 234c9a97..00000000 --- a/src/main/resources/assets/wizardry/blockstates/crystal_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "forge_marker": 1, - "variants": { - "normal": { "model": "wizardry:crystal_ore" } - } -} diff --git a/src/main/resources/assets/wizardry/blockstates/ice_statue.json b/src/main/resources/assets/wizardry/blockstates/ice_statue.json deleted file mode 100644 index e2c0b099..00000000 --- a/src/main/resources/assets/wizardry/blockstates/ice_statue.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "forge_marker": 1, - "variants": { - "normal": { "model": "wizardry:ice_statue" } - } -} diff --git a/src/main/resources/assets/wizardry/blockstates/magic_light.json b/src/main/resources/assets/wizardry/blockstates/magic_light.json deleted file mode 100644 index df809b83..00000000 --- a/src/main/resources/assets/wizardry/blockstates/magic_light.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "forge_marker": 1, - "variants": { - "normal": { "model": "wizardry:magic_light" } - } -} diff --git a/src/main/resources/assets/wizardry/blockstates/meteor.json b/src/main/resources/assets/wizardry/blockstates/meteor.json deleted file mode 100644 index f1d33b5b..00000000 --- a/src/main/resources/assets/wizardry/blockstates/meteor.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "forge_marker": 1, - "variants": { - "normal": { "model": "wizardry:meteor" } - } -} diff --git a/src/main/resources/assets/wizardry/blockstates/petrified_stone.json b/src/main/resources/assets/wizardry/blockstates/petrified_stone.json deleted file mode 100644 index c8495ade..00000000 --- a/src/main/resources/assets/wizardry/blockstates/petrified_stone.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "forge_marker": 1, - "variants": { - "normal": { "model": "wizardry:petrified_stone" } - } -} diff --git a/src/main/resources/assets/wizardry/blockstates/snare.json b/src/main/resources/assets/wizardry/blockstates/snare.json deleted file mode 100644 index 594eb529..00000000 --- a/src/main/resources/assets/wizardry/blockstates/snare.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "forge_marker": 1, - "variants": { - "normal": { "model": "wizardry:snare" } - } -} diff --git a/src/main/resources/assets/wizardry/blockstates/spectral_block.json b/src/main/resources/assets/wizardry/blockstates/spectral_block.json deleted file mode 100644 index 79efd6b9..00000000 --- a/src/main/resources/assets/wizardry/blockstates/spectral_block.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "forge_marker": 1, - "variants": { - "normal": { "model": "wizardry:spectral_block" } - } -} diff --git a/src/main/resources/assets/wizardry/blockstates/transportation_stone.json b/src/main/resources/assets/wizardry/blockstates/transportation_stone.json deleted file mode 100644 index 67830c59..00000000 --- a/src/main/resources/assets/wizardry/blockstates/transportation_stone.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "forge_marker": 1, - "variants": { - "normal": { "model": "wizardry:transportation_stone" } - } -} diff --git a/src/main/resources/assets/wizardry/blockstates/vanishing_cobweb.json b/src/main/resources/assets/wizardry/blockstates/vanishing_cobweb.json deleted file mode 100644 index ce86f118..00000000 --- a/src/main/resources/assets/wizardry/blockstates/vanishing_cobweb.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "forge_marker": 1, - "variants": { - "normal": { "model": "wizardry:vanishing_cobweb" } - } -} diff --git a/src/main/resources/assets/wizardry/lang/en_GB.lang b/src/main/resources/assets/wizardry/lang/en_GB.lang index 8ae8a4d4..b7db3b1e 100644 --- a/src/main/resources/assets/wizardry/lang/en_GB.lang +++ b/src/main/resources/assets/wizardry/lang/en_GB.lang @@ -1,273 +1,272 @@ -tile.wizardry:arcane_workbench.name=Arcane Workbench -tile.wizardry:crystal_ore.name=Crystal Ore -tile.wizardry:petrified_stone.name=Petrified Stone -tile.wizardry:ice_statue.name=Ice Statue -tile.wizardry:crystal_flower.name=Crystal Flower -tile.wizardry:snare.name=Snare -tile.wizardry:transportation_stone.name=Stone of Transportation -tile.wizardry:spectral_block.name=Spectral Block -tile.wizardry:crystal_block.name=Block of Crystal +tile.arcaneWorkbench.name=Arcane Workbench +tile.crystalOre.name=Crystal Ore +tile.petrifiedStone.name=Petrified Stone +tile.iceStatue.name=Ice Statue +tile.crystalFlower.name=Crystal Flower +tile.snare.name=Snare +tile.transportationStone.name=Stone of Transportation +tile.spectralBlock.name=Spectral Block +tile.crystalBlock.name=Block of Crystal -item.wizardry:magic_crystal.name=Magic Crystal -item.wizardry:magic_wand.name=Magic Wand -item.wizardry:apprentice_wand.name=Apprentice Wand -item.wizardry:advanced_wand.name=Advanced Wand -item.wizardry:master_wand.name=Master Wand -item.wizardry:spell_book.name=Spell Book +item.magicCrystal.name=Magic Crystal +item.magicWand.name=Magic Wand +item.apprenticeWand.name=Apprentice Wand +item.advancedWand.name=Advanced Wand +item.masterWand.name=Master Wand +item.spellBook.name=Spell Book -item.wizardry:arcane_tome.name=Tome of Arcana -item.wizardry:arcane_tome.desc1=Upgrades any %1$s -item.wizardry:arcane_tome.desc2=wand to %1$s tier +item.arcaneTome.name=Tome of Arcana +item.arcaneTome.desc1=Upgrades any %1$s +item.arcaneTome.desc2=wand to %1$s tier -item.wizardry:wizard_handbook.name=The Wizard's Handbook -item.wizardry:wizard_handbook.desc=by %1$s +item.wizardHandbook.name=The Wizard's Handbook +item.wizardHandbook.desc=by %1$s -item.wizardry:wand.buff=+%1$s %2$s potency -item.wizardry:wand.spell=Current Spell: %1$s -item.wizardry:wand.mana=Mana: %1$s/%2$s +item.wand.buff=+%1$s %2$s potency +item.wand.spell=Current Spell: %1$s +item.wand.mana=Mana: %1$s/%2$s -item.wizardry:wand.addally=%1$s has been added to your list of allies -item.wizardry:wand.removeally=%1$s has been removed from your list of allies +item.wand.addally=%1$s has been added to your list of allies +item.wand.removeally=%1$s has been removed from your list of allies -item.wizardry:basic_fire_wand.name=Wand of Embers -item.wizardry:basic_ice_wand.name=Wand of Frost -item.wizardry:basic_lightning_wand.name=Wand of Sparks -item.wizardry:basic_necromancy_wand.name=Wand of Shadows -item.wizardry:basic_earth_wand.name=Wand of the Forest -item.wizardry:basic_sorcery_wand.name=Wand of Mystery -item.wizardry:basic_healing_wand.name=Wand of Healing +item.basicFireWand.name=Wand of Embers +item.basicIceWand.name=Wand of Frost +item.basicLightningWand.name=Wand of Sparks +item.basicNecromancyWand.name=Wand of Shadows +item.basicEarthWand.name=Wand of the Forest +item.basicSorceryWand.name=Wand of Mystery +item.basicHealingWand.name=Wand of Healing -item.wizardry:apprentice_fire_wand.name=Apprentice Pyromancer Wand -item.wizardry:apprentice_ice_wand.name=Apprentice Ice Mage Wand -item.wizardry:apprentice_lightning_wand.name=Apprentice Storm Mage Wand -item.wizardry:apprentice_necromancy_wand.name=Apprentice Necromancer Wand -item.wizardry:apprentice_earth_wand.name=Apprentice Earth Mage Wand -item.wizardry:apprentice_sorcery_wand.name=Apprentice Sorcerer Wand -item.wizardry:apprentice_healing_wand.name=Apprentice Healer Wand +item.apprenticeFireWand.name=Apprentice Pyromancer Wand +item.apprenticeIceWand.name=Apprentice Ice Mage Wand +item.apprenticeLightningWand.name=Apprentice Storm Mage Wand +item.apprenticeNecromancyWand.name=Apprentice Necromancer Wand +item.apprenticeEarthWand.name=Apprentice Earth Mage Wand +item.apprenticeSorceryWand.name=Apprentice Sorcerer Wand +item.apprenticeHealingWand.name=Apprentice Healer Wand -item.wizardry:advanced_fire_wand.name=Wand of the Pyromancer -item.wizardry:advanced_ice_wand.name=Wand of the Ice Mage -item.wizardry:advanced_lightning_wand.name=Wand of the Storm Mage -item.wizardry:advanced_necromancy_wand.name=Wand of the Necromancer -item.wizardry:advanced_earth_wand.name=Wand of the Earth Mage -item.wizardry:advanced_sorcery_wand.name=Wand of the Sorcerer -item.wizardry:advanced_healing_wand.name=Wand of the Healer +item.advancedFireWand.name=Wand of the Pyromancer +item.advancedIceWand.name=Wand of the Ice Mage +item.advancedLightningWand.name=Wand of the Storm Mage +item.advancedNecromancyWand.name=Wand of the Necromancer +item.advancedEarthWand.name=Wand of the Earth Mage +item.advancedSorceryWand.name=Wand of the Sorcerer +item.advancedHealingWand.name=Wand of the Healer -item.wizardry:master_fire_wand.name=Master Pyromancer Wand -item.wizardry:master_ice_wand.name=Master Ice Mage Wand -item.wizardry:master_lightning_wand.name=Master Storm Mage Wand -item.wizardry:master_necromancy_wand.name=Master Necromancer Wand -item.wizardry:master_earth_wand.name=Master Earth Mage Wand -item.wizardry:master_sorcery_wand.name=Master Sorcerer Wand -item.wizardry:master_healing_wand.name=Master Healer Wand +item.masterFireWand.name=Master Pyromancer Wand +item.masterIceWand.name=Master Ice Mage Wand +item.masterLightningWand.name=Master Storm Mage Wand +item.masterNecromancyWand.name=Master Necromancer Wand +item.masterEarthWand.name=Master Earth Mage Wand +item.masterSorceryWand.name=Master Sorcerer Wand +item.masterHealingWand.name=Master Healer Wand -item.wizardry:spectral_sword.name=Spectral Sword -item.wizardry:spectral_pickaxe.name=Spectral Pickaxe -item.wizardry:spectral_bow.name=Spectral Bow +item.spectralSword.name=Spectral Sword +item.spectralPickaxe.name=Spectral Pickaxe +item.spectralBow.name=Spectral Bow -item.wizardry:mana_flask.name=Mana Flask -item.wizardry:storage_upgrade.name=Wand Storage Upgrade -item.wizardry:siphon_upgrade.name=Wand Siphon Upgrade -item.wizardry:condenser_upgrade.name=Wand Condenser Upgrade -item.wizardry:range_upgrade.name=Wand Range Upgrade -item.wizardry:duration_upgrade.name=Wand Duration Upgrade -item.wizardry:cooldown_upgrade.name=Wand Cooldown Upgrade -item.wizardry:blast_upgrade.name=Wand Blast Upgrade -item.wizardry:attunement_upgrade.name=Wand Attunement Upgrade +item.manaFlask.name=Mana Flask +item.storageUpgrade.name=Wand Storage Upgrade +item.siphonUpgrade.name=Wand Siphon Upgrade +item.condenserUpgrade.name=Wand Condenser Upgrade +item.rangeUpgrade.name=Wand Range Upgrade +item.durationUpgrade.name=Wand Duration Upgrade +item.cooldownUpgrade.name=Wand Cooldown Upgrade +item.blastUpgrade.name=Wand Blast Upgrade +item.attunementUpgrade.name=Wand Attunement Upgrade -item.wizardry:flaming_axe.name=Flaming Axe -item.wizardry:frost_axe.name=Frost Axe +item.flamingAxe.name=Flaming Axe +item.frostAxe.name=Frost Axe -item.wizardry:firebomb.name=Firebomb -item.wizardry:poison_bomb.name=Poison Bomb -item.wizardry:smoke_bomb.name=Smoke Bomb +item.firebomb.name=Firebomb +item.poisonBomb.name=Poison Bomb +item.smoke_bomb.name=Smoke Bomb -item.wizardry:blank_scroll.name=Blank Scroll -item.wizardry:scroll.name=Scroll of %1$s -item.wizardry:scroll.undiscovered.name=Scroll "%1$s" -item.wizardry:identification_scroll.name=Scroll of Identification -item.wizardry:identification_scroll.desc1=%1$sIdentifies an unknown -item.wizardry:identification_scroll.desc2=%1$sspell book or scroll -item.wizardry:identification_scroll.nothing_to_identify=Nothing to identify! +item.blankScroll.name=Blank Scroll +item.scroll.name=Scroll of %1$s +item.scroll.undiscovered.name=Scroll "%1$s" +item.identification_scroll.name=Scroll of Identification +item.identification_scroll.desc1=%1$sIdentifies an unknown +item.identification_scroll.desc2=%1$sspell book or scroll +item.identification_scroll.nothing_to_identify=Nothing to identify! -item.wizardry:armour_upgrade.name=Arcane Seal of Protection -item.wizardry:armour_upgrade.desc1=%1$sUpgrades any wizard armour -item.wizardry:armour_upgrade.desc2=%1$sto make it %2$slegendary +item.armourUpgrade.name=Arcane Seal of Protection +item.armourUpgrade.desc1=%1$sUpgrades any wizard armour +item.armourUpgrade.desc2=%1$sto make it %2$slegendary -item.wizardry:magic_silk.name=Magical Silk +item.magicSilk.name=Magical Silk -item.wizardry:wizard_armour.legendary=Legendary -item.wizardry:wizard_armour.buff=-%1$s %2$s cost -item.wizardry:wizard_armour.mana=Mana: %1$s/%2$s +item.wizardArmour.legendary=Legendary +item.wizardArmour.buff=-%1$s %2$s cost +item.wizardArmour.mana=Mana: %1$s/%2$s -item.wizardry:wizard_hat.name=Wizard Hat -item.wizardry:wizard_robe.name=Wizard Robes -item.wizardry:wizard_leggings.name=Wizard Leggings -item.wizardry:wizard_boots.name=Wizard Boots +item.wizard_hat.name=Wizard Hat +item.wizard_robe.name=Wizard Robes +item.wizard_leggings.name=Wizard Leggings +item.wizard_boots.name=Wizard Boots -item.wizardry:wizard_hat_fire.name=Pyromancer Hat -item.wizardry:wizard_robe_fire.name=Pyromancer Robes -item.wizardry:wizard_leggings_fire.name=Pyromancer Leggings -item.wizardry:wizard_boots_fire.name=Pyromancer Boots +item.wizard_hat_fire.name=Pyromancer Hat +item.wizard_robe_fire.name=Pyromancer Robes +item.wizard_leggings_fire.name=Pyromancer Leggings +item.wizard_boots_fire.name=Pyromancer Boots -item.wizardry:wizard_hat_ice.name=Ice Mage Hat -item.wizardry:wizard_robe_ice.name=Ice Mage Robes -item.wizardry:wizard_leggings_ice.name=Ice Mage Leggings -item.wizardry:wizard_boots_ice.name=Ice Mage Boots +item.wizard_hat_ice.name=Ice Mage Hat +item.wizard_robe_ice.name=Ice Mage Robes +item.wizard_leggings_ice.name=Ice Mage Leggings +item.wizard_boots_ice.name=Ice Mage Boots -item.wizardry:wizard_hat_lightning.name=Storm Mage Hat -item.wizardry:wizard_robe_lightning.name=Storm Mage Robes -item.wizardry:wizard_leggings_lightning.name=Storm Mage Leggings -item.wizardry:wizard_boots_lightning.name=Storm Mage Boots +item.wizard_hat_lightning.name=Storm Mage Hat +item.wizard_robe_lightning.name=Storm Mage Robes +item.wizard_leggings_lightning.name=Storm Mage Leggings +item.wizard_boots_lightning.name=Storm Mage Boots -item.wizardry:wizard_hat_necromancy.name=Necromancer Hat -item.wizardry:wizard_robe_necromancy.name=Necromancer Robes -item.wizardry:wizard_leggings_necromancy.name=Necromancer Leggings -item.wizardry:wizard_boots_necromancy.name=Necromancer Boots +item.wizard_hat_necromancy.name=Necromancer Hat +item.wizard_robe_necromancy.name=Necromancer Robes +item.wizard_leggings_necromancy.name=Necromancer Leggings +item.wizard_boots_necromancy.name=Necromancer Boots -item.wizardry:wizard_hat_earth.name=Earth Mage Hat -item.wizardry:wizard_robe_earth.name=Earth Mage Robes -item.wizardry:wizard_leggings_earth.name=Earth Mage Leggings -item.wizardry:wizard_boots_earth.name=Earth Mage Boots +item.wizard_hat_earth.name=Earth Mage Hat +item.wizard_robe_earth.name=Earth Mage Robes +item.wizard_leggings_earth.name=Earth Mage Leggings +item.wizard_boots_earth.name=Earth Mage Boots -item.wizardry:wizard_hat_sorcery.name=Sorcerer Hat -item.wizardry:wizard_robe_sorcery.name=Sorcerer Robes -item.wizardry:wizard_leggings_sorcery.name=Sorcerer Leggings -item.wizardry:wizard_boots_sorcery.name=Sorcerer Boots +item.wizard_hat_sorcery.name=Sorcerer Hat +item.wizard_robe_sorcery.name=Sorcerer Robes +item.wizard_leggings_sorcery.name=Sorcerer Leggings +item.wizard_boots_sorcery.name=Sorcerer Boots -item.wizardry:wizard_hat_healing.name=Healer Hat -item.wizardry:wizard_robe_healing.name=Healer Robes -item.wizardry:wizard_leggings_healing.name=Healer Leggings -item.wizardry:wizard_boots_healing.name=Healer Boots +item.wizard_hat_healing.name=Healer Hat +item.wizard_robe_healing.name=Healer Robes +item.wizard_leggings_healing.name=Healer Leggings +item.wizard_boots_healing.name=Healer Boots -item.wizardry:spawn_wizard.name=Spawn Wizard -item.wizardry:spawn_evil_wizard.name=Spawn Evil Wizard +item.spawn_wizard.name=Spawn Wizard +item.spawn_evil_wizard.name=Spawn Evil Wizard -item.wizardry:spectral_helmet.name=Spectral Helmet -item.wizardry:spectral_chestplate.name=Spectral Chestplate -item.wizardry:spectral_leggings.name=Spectral Leggings -item.wizardry:spectral_boots.name=Spectral Boots +item.spectral_helmet.name=Spectral Helmet +item.spectral_chestplate.name=Spectral Chestplate +item.spectral_leggings.name=Spectral Leggings +item.spectral_boots.name=Spectral Boots entity.wizardry.summonedcreature.nameplate=%1$s's %2$s -entity.wizardry.summonedcreature.nameplate_fallback=Someone's %1$s -entity.wizardry.zombie_minion.name=Zombie -entity.wizardry.skeleton_minion.name=Skeleton -entity.wizardry.spider_minion.name=Spider -entity.wizardry.blaze_minion.name=Blaze -entity.wizardry.ice_wraith.name=Ice Wraith -entity.wizardry.lightning_wraith.name=Lightning Wraith -entity.wizardry.shadow_wraith.name=Shadow Wraith -entity.wizardry.spirit_wolf.name=Spirit Wolf -entity.wizardry.spirit_horse.name=Spirit Horse -entity.wizardry.ice_giant.name=Ice Giant -entity.wizardry.phoenix.name=Phoenix -entity.wizardry.wizard.name=Wizard -entity.wizardry.magic_slime.name=Magical Slime -entity.wizardry.silverfish_minion.name=Silverfish -entity.wizardry.storm_elemental.name=Storm Elemental -entity.wizardry.evil_wizard.name=Wizard -entity.wizardry.decoy.name=Decoy +entity.wizardry.Zombie Minion.name=Zombie +entity.wizardry.Skeleton Minion.name=Skeleton +entity.wizardry.Spider Minion.name=Spider +entity.wizardry.Blaze Minion.name=Blaze +entity.wizardry.Ice Wraith.name=Ice Wraith +entity.wizardry.Lightning Wraith.name=Lightning Wraith +entity.wizardry.Shadow Wraith.name=Shadow Wraith +entity.wizardry.Spirit Wolf.name=Spirit Wolf +entity.wizardry.Spirit Horse.name=Spirit Horse +entity.wizardry.Ice Giant.name=Ice Giant +entity.wizardry.Phoenix.name=Phoenix +entity.wizardry.Wizard.name=Wizard +entity.wizardry.Magic Slime.name=Magical Slime +entity.wizardry.Silverfish Minion.name=Silverfish +entity.wizardry.Storm Elemental.name=Storm Elemental +entity.wizardry.Evil Wizard.name=Wizard +entity.wizardry.Decoy.name=Decoy -entity.wizardry.magic_missile.name=Magic -entity.wizardry.arc.name=Magic -entity.wizardry.spark_bomb.name=Magic -entity.wizardry.ice_shard.name=Magic -entity.wizardry.firebomb.name=Magic -entity.wizardry.poison_bomb.name=Magic -entity.wizardry.force_orb.name=Magic -entity.wizardry.spark.name=Magic -entity.wizardry.darkness_orb.name=Magic -entity.wizardry.fire_sigil.name=Magic -entity.wizardry.frost_sigil.name=Magic -entity.wizardry.lightning_sigil.name=Magic -entity.wizardry.lightning_arrow.name=Magic -entity.wizardry.firebolt.name=Magic -entity.wizardry.ice_charge.name=Magic -entity.wizardry.force_arrow.name=Magic -entity.wizardry.dart.name=Magic -entity.wizardry.lightning_disc.name=Magic -entity.wizardry.thunderbolt.name=Magic -entity.wizardry.decay.name=Magic -entity.wizardry.ice_lance.name=Magic -entity.wizardry.smoke_bomb.name=Magic -entity.wizardry.ice_spike.name=Magic +entity.wizardry.Magic Missile.name=Magic +entity.wizardry.Arc.name=Magic +entity.wizardry.Spark Bomb.name=Magic +entity.wizardry.Ice Shard.name=Magic +entity.wizardry.Firebomb.name=Magic +entity.wizardry.Poison Bomb.name=Magic +entity.wizardry.Force Orb.name=Magic +entity.wizardry.Spark.name=Magic +entity.wizardry.Darkness Orb.name=Magic +entity.wizardry.Fire Sigil.name=Magic +entity.wizardry.Frost Sigil.name=Magic +entity.wizardry.Lightning Sigil.name=Magic +entity.wizardry.Lightning Arrow.name=Magic +entity.wizardry.Firebolt.name=Magic +entity.wizardry.Ice Charge.name=Magic +entity.wizardry.Force Arrow.name=Magic +entity.wizardry.Dart.name=Magic +entity.wizardry.Lightning Disc.name=Magic +entity.wizardry.Thunderbolt.name=Magic +entity.wizardry.Decay.name=Magic +entity.wizardry.Ice Lance.name=Magic +entity.wizardry.Smoke Bomb.name=Magic +entity.wizardry.Ice Spike.name=Magic -entity.wizardry.black_hole.name=Black Hole -entity.wizardry.shield.name=Shield -entity.wizardry.meteor.name=Meteor -entity.wizardry.blizzard.name=Blizzard -entity.wizardry.bubble.name=Bubble -entity.wizardry.tornado.name=Tornado -entity.wizardry.lightning_hammer.name=Lightning Hammer -entity.wizardry.arrow_rain.name=Arrow Rain -entity.wizardry.healing_aura.name=Healing Aura -entity.wizardry.forcefield.name=Forcefield -entity.wizardry.ring_of_fire.name=Ring of Fire -entity.wizardry.earthquake.name=Earthquake -entity.wizardry.falling_grass.name=Falling Grass -entity.wizardry.hailstorm.name=Hailstorm -entity.wizardry.lightning_pulse.name=Lightning Pulse +entity.wizardry.Black Hole.name=Black Hole +entity.wizardry.Shield.name=Shield +entity.wizardry.Meteor.name=Meteor +entity.wizardry.Blizzard.name=Blizzard +entity.wizardry.Bubble.name=Bubble +entity.wizardry.Tornado.name=Tornado +entity.wizardry.Lightning Hammer.name=Lightning Hammer +entity.wizardry.Arrow Rain.name=Arrow Rain +entity.wizardry.Healing Aura.name=Healing Aura +entity.wizardry.Forcefield.name=Forcefield +entity.wizardry.Ring of Fire.name=Ring of Fire +entity.wizardry.Earthquake.name=Earthquake +entity.wizardry.Falling Grass.name=Falling Grass +entity.wizardry.Hailstorm.name=Hailstorm +entity.wizardry.Lightning Pulse.name=Lightning Pulse -item_group.wizardry=Wizardry -item_group.wizardryspells=Spells +itemGroup.wizardry=Wizardry +itemGroup.wizardryspells=Wizardry Spells -achievement.crystal=A Curious Crystal... -achievement.crystal.desc=Mine a magic crystal -achievement.arcane_initiate=Arcane Initiate -achievement.arcane_initiate.desc=Craft a magic wand with a gold nugget, a stick and a magic crystal -achievement.apprentice=Wizard's Apprentice -achievement.apprentice.desc=Use a tome of arcana to upgrade your wand -achievement.master=Arcane Master -achievement.master.desc=Obtain a master wand -achievement.all_spells=Mage of All Trades -achievement.all_spells.desc=Cast every single spell in the game -achievement.wizard_trade=Magic Dealing -achievement.wizard_trade.desc=Purchase an item from a wizard -achievement.buy_master_spell=Knowledge is Power -achievement.buy_master_spell.wizardry:desc=Purchase a master spell from a wizard -achievement.freeze_blaze=Not So Hot Now -achievement.freeze_blaze.desc=Freeze a blaze solid -achievement.charge_creeper=It's Gonna Blow -achievement.charge_creeper.desc='Accidentally' charge a creeper -achievement.frankenstein=Frankenstein -achievement.frankenstein.desc=Turn a pig into a zombie pigman using the lightning bolt spell -achievement.special_upgrade=Arcane Tinkering -achievement.special_upgrade.desc=Apply a special upgrade to a wand -achievement.craft_flask=It's Magic, Bottled! -achievement.craft_flask.desc=Craft a mana flask -achievement.elemental=Elemental -achievement.elemental.desc=Obtain an elemental wand -achievement.armour_set=Now You're a Proper Wizard -achievement.armour_set.desc=Craft and equip a full set of wizard armour -achievement.legendary=Legendary -achievement.legendary.desc=Obtain a piece of legendary wizard armour -achievement.self_destruct=That Backfired -achievement.self_destruct.desc=Get killed by your own magic -achievement.pig_tornado=Not Again... -achievement.pig_tornado.desc=Ride a pig into a tornado -achievement.jam_wizard=Jamming Session -achievement.jam_wizard.desc=Use the arcane jammer spell on a wizard -achievement.slime_skeleton=Sticky Situation -achievement.slime_skeleton.desc=Engulf a skeleton in slime -achievement.anger_wizard=You'll Regret That -achievement.anger_wizard.desc=Make a wizard angry -achievement.defeat_evil_wizard=Righteousness -achievement.defeat_evil_wizard.desc=Defeat an evil wizard -achievement.max_out_wand=Fully Equipped -achievement.max_out_wand.desc=Apply the maximum number of upgrades to a master wand -achievement.element_master=Element Mastery -achievement.element_master.desc=Cast all the spells of any element -achievement.identify_spell=Arcane Appraisal -achievement.identify_spell.wizardry:desc=Use a scroll of identification to identify a spell book or scroll +achievement.Crystal=A Curious Crystal... +achievement.Crystal.desc=Mine a magic crystal +achievement.ArcaneInitiate=Arcane Initiate +achievement.ArcaneInitiate.desc=Craft a magic wand with a gold nugget, a stick and a magic crystal +achievement.Apprentice=Wizard's Apprentice +achievement.Apprentice.desc=Use a tome of arcana to upgrade your wand +achievement.Master=Arcane Master +achievement.Master.desc=Obtain a master wand +achievement.AllSpells=Mage of All Trades +achievement.AllSpells.desc=Cast every single spell in the game +achievement.WizardTrade=Magic Dealing +achievement.WizardTrade.desc=Purchase an item from a wizard +achievement.BuyMasterSpell=Knowledge is Power +achievement.BuyMasterSpell.desc=Purchase a master spell from a wizard +achievement.FreezeBlaze=Not So Hot Now +achievement.FreezeBlaze.desc=Freeze a blaze solid +achievement.ChargeCreeper=It's Gonna Blow +achievement.ChargeCreeper.desc='Accidentally' charge a creeper +achievement.Frankenstein=Frankenstein +achievement.Frankenstein.desc=Turn a pig into a zombie pigman using the lightning bolt spell +achievement.SpecialUpgrade=Arcane Tinkering +achievement.SpecialUpgrade.desc=Apply a special upgrade to a wand +achievement.CraftFlask=It's Magic, Bottled! +achievement.CraftFlask.desc=Craft a mana flask +achievement.Elemental=Elemental +achievement.Elemental.desc=Obtain an elemental wand +achievement.ArmourSet=Now You're a Proper Wizard +achievement.ArmourSet.desc=Craft and equip a full set of wizard armour +achievement.Legendary=Legendary +achievement.Legendary.desc=Obtain a piece of legendary wizard armour +achievement.SelfDestruct=That Backfired +achievement.SelfDestruct.desc=Get killed by your own magic +achievement.PigTornado=Not Again... +achievement.PigTornado.desc=Ride a pig into a tornado +achievement.JamWizard=Jamming Session +achievement.JamWizard.desc=Use the arcane jammer spell on a wizard +achievement.SlimeSkeleton=Sticky Situation +achievement.SlimeSkeleton.desc=Engulf a skeleton in slime +achievement.AngerWizard=You'll Regret That +achievement.AngerWizard.desc=Make a wizard angry +achievement.DefeatEvilWizard=Righteousness +achievement.DefeatEvilWizard.desc=Defeat an evil wizard +achievement.MaxOutWand=Fully Equipped +achievement.MaxOutWand.desc=Apply the maximum number of upgrades to a master wand +achievement.ElementMaster=Element Mastery +achievement.ElementMaster.desc=Cast all the spells of any element +achievement.IdentifySpell=Arcane Appraisal +achievement.IdentifySpell.desc=Use a scroll of identification to identify a spell book or scroll -tile.wizardry:transportation_stone.confirm=You will now be returned here upon casting %1$s -tile.wizardry:transportation_stone.invalid=You must make a circle with 8 stones of transportation first! +tile.transportationStone.confirm=You will now be returned here upon casting %1$s +tile.transportationStone.invalid=You must make a circle with 8 stones of transportation first! -container.wizardry:arcane_workbench=Arcane Workbench -container.wizardry:arcane_workbench.apply=Apply -container.wizardry:arcane_workbench.mana=Mana: -container.wizardry:arcane_workbench.upgrades=Applied Upgrades: +container.arcaneWorkbench=Arcane Workbench +container.arcaneWorkbench.apply=Apply +container.arcaneWorkbench.mana=Mana: +container.arcaneWorkbench.upgrades=Applied Upgrades: tier.basic=Novice tier.apprentice=Apprentice @@ -301,438 +300,471 @@ spell.disabled=%1$s has been disabled in the config spell.resist=%1$s resisted %2$s spell.discover=Discovered the spell %1$s! -spell.wizardry:agility=Agility -spell.wizardry:arc=Arc -spell.wizardry:arcane_jammer=Arcane Jammer -spell.wizardry:arrow_rain=Arrow Rain -spell.wizardry:banish=Banish -spell.wizardry:black_hole=Black Hole -spell.wizardry:blink=Blink -spell.wizardry:blizzard=Blizzard -spell.wizardry:bubble=Bubble -spell.wizardry:chain_lightning=Chain Lightning -spell.wizardry:clairvoyance=Clairvoyance -spell.wizardry:cobwebs=Cobwebs -spell.wizardry:conjure_armour=Conjure Armour -spell.wizardry:conjure_bow=Conjure Bow -spell.wizardry:conjure_pickaxe=Conjure Pickaxe -spell.wizardry:conjure_sword=Conjure Sword -spell.wizardry:cure_effects=Cure Effects -spell.wizardry:curse_of_soulbinding=Curse of Soulbinding -spell.wizardry:darkness_orb=Darkness Orb -spell.wizardry:darkvision=Darkvision -spell.wizardry:dart=Dart -spell.wizardry:decay=Decay -spell.wizardry:decoy=Decoy -spell.wizardry:detonate=Detonate -spell.wizardry:diamondflesh=Diamondflesh -spell.wizardry:earthquake=Earthquake -spell.wizardry:entrapment=Entrapment -spell.wizardry:fireball=Fireball -spell.wizardry:firebolt=Firebolt -spell.wizardry:firebomb=Firebomb -spell.wizardry:fire_resistance=Fire Resistance -spell.wizardry:fire_sigil=Fire Sigil -spell.wizardry:fireskin=Fireskin -spell.wizardry:firestorm=Firestorm -spell.wizardry:flame_ray=Flame Ray -spell.wizardry:flaming_axe=Flaming Axe -spell.wizardry:flaming_weapon=Flaming Weapon -spell.wizardry:flight=Flight -spell.wizardry:font_of_mana=Font of Mana -spell.wizardry:font_of_vitality=Font of Vitality -spell.wizardry:force_arrow=Force Arrow -spell.wizardry:forcefield=Forcefield -spell.wizardry:force_orb=Force Orb -spell.wizardry:forests_curse=Forest's Curse -spell.wizardry:freeze=Freeze -spell.wizardry:freezing_weapon=Freezing Weapon -spell.wizardry:frost_axe=Frost Axe -spell.wizardry:frost_ray=Frost Ray -spell.wizardry:frost_sigil=Frost Sigil -spell.wizardry:glide=Glide -spell.wizardry:greater_fireball=Greater Fireball -spell.wizardry:greater_heal=Greater Heal -spell.wizardry:group_heal=Group Heal -spell.wizardry:growth_aura=Growth Aura -spell.wizardry:hailstorm=Hailstorm -spell.wizardry:heal=Heal -spell.wizardry:heal_ally=Heal Ally -spell.wizardry:healing_aura=Healing Aura -spell.wizardry:homing_spark=Homing Spark -spell.wizardry:ice_age=Ice Age -spell.wizardry:ice_charge=Ice Charge -spell.wizardry:ice_lance=Ice Lance -spell.wizardry:ice_shard=Ice Shard -spell.wizardry:ice_shroud=Ice Shroud -spell.wizardry:ice_spikes=Ice Spikes -spell.wizardry:ice_statue=Ice Statue -spell.wizardry:ignite=Ignite -spell.wizardry:imbue_weapon=Imbue Weapon -spell.wizardry:intimidate=Intimidate -spell.wizardry:invigorating_presence=Invigorating Presence -spell.wizardry:invisibility=Invisibility -spell.wizardry:invoke_weather=Invoke Weather -spell.wizardry:ironflesh=Ironflesh -spell.wizardry:leap=Leap -spell.wizardry:levitation=Levitation -spell.wizardry:life_drain=Life Drain -spell.wizardry:light=Light -spell.wizardry:lightning_arrow=Lightning Arrow -spell.wizardry:lightning_bolt=Lightning Bolt -spell.wizardry:lightning_disc=Lightning Disc -spell.wizardry:lightning_hammer=Lightning Hammer -spell.wizardry:lightning_pulse=Lightning Pulse -spell.wizardry:lightning_ray=Lightning Ray -spell.wizardry:lightning_sigil=Lightning Sigil -spell.wizardry:lightning_web=Lightning Web -spell.wizardry:magic_missile=Magic Missile -spell.wizardry:metamorphosis=Metamorphosis -spell.wizardry:meteor=Meteor -spell.wizardry:mind_control=Mind Control -spell.wizardry:mind_trick=Mind Trick -spell.wizardry:none=[Empty Slot] -spell.wizardry:oakflesh=Oakflesh -spell.wizardry:petrify=Petrify -spell.wizardry:phase_step=Phase Step -spell.wizardry:plague_of_darkness=Plague of Darkness -spell.wizardry:pocket_furnace=Pocket Furnace -spell.wizardry:pocket_workbench=Pocket Workbench -spell.wizardry:poison=Poison -spell.wizardry:poison_bomb=Poison Bomb -spell.wizardry:replenish_hunger=Replenish Hunger -spell.wizardry:ring_of_fire=Ring of Fire -spell.wizardry:shadow_ward=Shadow Ward -spell.wizardry:shield=Shield -spell.wizardry:shockwave=Shockwave -spell.wizardry:silverfish_swarm=Silverfish Swarm -spell.wizardry:sixth_sense=Sixth Sense -spell.wizardry:slime=Slime -spell.wizardry:smoke_bomb=Smoke Bomb -spell.wizardry:snare=Snare -spell.wizardry:snowball=Snowball -spell.wizardry:spark_bomb=Spark Bomb -spell.wizardry:spectral_pathway=Spectral Pathway -spell.wizardry:spider_swarm=Spider Swarm -spell.wizardry:static_aura=Static Aura -spell.wizardry:summon_blaze=Summon Blaze -spell.wizardry:summon_ice_giant=Summon Ice Giant -spell.wizardry:summon_ice_wraith=Summon Ice Wraith -spell.wizardry:summon_iron_golem=Summon Iron Golem -spell.wizardry:summon_lightning_wraith=Summon Lightning Wraith -spell.wizardry:summon_phoenix=Summon Phoenix -spell.wizardry:summon_shadow_wraith=Summon Shadow Wraith -spell.wizardry:summon_skeleton=Summon Skeleton -spell.wizardry:summon_skeleton_legion=Summon Skeleton Legion -spell.wizardry:summon_snow_golem=Summon Snow Golem -spell.wizardry:summon_spirit_horse=Summon Spirit Horse -spell.wizardry:summon_spirit_wolf=Summon Spirit Wolf -spell.wizardry:summon_storm_elemental=Summon Storm Elemental -spell.wizardry:summon_wither_skeleton=Summon Wither Skeleton -spell.wizardry:summon_zombie=Summon Zombie -spell.wizardry:telekinesis=Telekinesis -spell.wizardry:thunderbolt=Thunderbolt -spell.wizardry:thunderstorm=Thunderstorm -spell.wizardry:tornado=Tornado -spell.wizardry:transience=Transience -spell.wizardry:transportation=Transportation -spell.wizardry:vanishing_box=Vanishing Box -spell.wizardry:wall_of_frost=Wall of Frost -spell.wizardry:water_breathing=Water Breathing -spell.wizardry:whirlwind=Whirlwind -spell.wizardry:wither=Wither -spell.wizardry:wither_skull=Wither Skull +spell.agility=Agility +spell.arc=Arc +spell.arcane_jammer=Arcane Jammer +spell.arrow_rain=Arrow Rain +spell.banish=Banish +spell.black_hole=Black Hole +spell.blink=Blink +spell.blizzard=Blizzard +spell.bubble=Bubble +spell.chain_lightning=Chain Lightning +spell.clairvoyance=Clairvoyance +spell.cobwebs=Cobwebs +spell.conjure_armour=Conjure Armour +spell.conjure_bow=Conjure Bow +spell.conjure_pickaxe=Conjure Pickaxe +spell.conjure_sword=Conjure Sword +spell.cure_effects=Cure Effects +spell.curse_of_soulbinding=Curse of Soulbinding +spell.darkness_orb=Darkness Orb +spell.darkvision=Darkvision +spell.dart=Dart +spell.decay=Decay +spell.decoy=Decoy +spell.detonate=Detonate +spell.diamondflesh=Diamondflesh +spell.earthquake=Earthquake +spell.entrapment=Entrapment +spell.fireball=Fireball +spell.firebolt=Firebolt +spell.firebomb=Firebomb +spell.fire_resistance=Fire Resistance +spell.fire_sigil=Fire Sigil +spell.fireskin=Fireskin +spell.firestorm=Firestorm +spell.flame_ray=Flame Ray +spell.flaming_axe=Flaming Axe +spell.flaming_weapon=Flaming Weapon +spell.flight=Flight +spell.font_of_mana=Font of Mana +spell.font_of_vitality=Font of Vitality +spell.force_arrow=Force Arrow +spell.forcefield=Forcefield +spell.force_orb=Force Orb +spell.forests_curse=Forest's Curse +spell.freeze=Freeze +spell.freezing_weapon=Freezing Weapon +spell.frost_axe=Frost Axe +spell.frost_ray=Frost Ray +spell.frost_sigil=Frost Sigil +spell.glide=Glide +spell.greater_fireball=Greater Fireball +spell.greater_heal=Greater Heal +spell.group_heal=Group Heal +spell.growth_aura=Growth Aura +spell.hailstorm=Hailstorm +spell.heal=Heal +spell.heal_ally=Heal Ally +spell.healing_aura=Healing Aura +spell.homing_spark=Homing Spark +spell.ice_age=Ice Age +spell.ice_charge=Ice Charge +spell.ice_lance=Ice Lance +spell.ice_shard=Ice Shard +spell.ice_shroud=Ice Shroud +spell.ice_spikes=Ice Spikes +spell.ice_statue=Ice Statue +spell.ignite=Ignite +spell.imbue_weapon=Imbue Weapon +spell.intimidate=Intimidate +spell.invigorating_presence=Invigorating Presence +spell.invisibility=Invisibility +spell.invoke_weather=Invoke Weather +spell.ironflesh=Ironflesh +spell.leap=Leap +spell.levitation=Levitation +spell.life_drain=Life Drain +spell.light=Light +spell.lightning_arrow=Lightning Arrow +spell.lightning_bolt=Lightning Bolt +spell.lightning_disc=Lightning Disc +spell.lightning_hammer=Lightning Hammer +spell.lightning_pulse=Lightning Pulse +spell.lightning_ray=Lightning Ray +spell.lightning_sigil=Lightning Sigil +spell.lightning_web=Lightning Web +spell.magic_missile=Magic Missile +spell.metamorphosis=Metamorphosis +spell.meteor=Meteor +spell.mind_control=Mind Control +spell.mind_trick=Mind Trick +spell.none=[Empty Slot] +spell.oakflesh=Oakflesh +spell.petrify=Petrify +spell.phase_step=Phase Step +spell.plague_of_darkness=Plague of Darkness +spell.pocket_furnace=Pocket Furnace +spell.pocket_workbench=Pocket Workbench +spell.poison=Poison +spell.poison_bomb=Poison Bomb +spell.replenish_hunger=Replenish Hunger +spell.ring_of_fire=Ring of Fire +spell.shadow_ward=Shadow Ward +spell.shield=Shield +spell.shockwave=Shockwave +spell.silverfish_swarm=Silverfish Swarm +spell.sixth_sense=Sixth Sense +spell.slime=Slime +spell.smoke_bomb=Smoke Bomb +spell.snare=Snare +spell.snowball=Snowball +spell.spark_bomb=Spark Bomb +spell.spectral_pathway=Spectral Pathway +spell.spider_swarm=Spider Swarm +spell.static_aura=Static Aura +spell.summon_blaze=Summon Blaze +spell.summon_ice_giant=Summon Ice Giant +spell.summon_ice_wraith=Summon Ice Wraith +spell.summon_iron_golem=Summon Iron Golem +spell.summon_lightning_wraith=Summon Lightning Wraith +spell.summon_phoenix=Summon Phoenix +spell.summon_shadow_wraith=Summon Shadow Wraith +spell.summon_skeleton=Summon Skeleton +spell.summon_skeleton_legion=Summon Skeleton Legion +spell.summon_snow_golem=Summon Snow Golem +spell.summon_spirit_horse=Summon Spirit Horse +spell.summon_spirit_wolf=Summon Spirit Wolf +spell.summon_storm_elemental=Summon Storm Elemental +spell.summon_wither_skeleton=Summon Wither Skeleton +spell.summon_zombie=Summon Zombie +spell.telekinesis=Telekinesis +spell.thunderbolt=Thunderbolt +spell.thunderstorm=Thunderstorm +spell.tornado=Tornado +spell.transience=Transience +spell.transportation=Transportation +spell.vanishing_box=Vanishing Box +spell.wall_of_frost=Wall of Frost +spell.water_breathing=Water Breathing +spell.whirlwind=Whirlwind +spell.wither=Wither +spell.wither_skull=Wither Skull -spell.wizardry:agility.desc=Grants the caster faster movement speed and greater jump height for 30 seconds. -spell.wizardry:arc.desc=Fires a spark of lightning at the target. -spell.wizardry:arcane_jammer.desc=Prevents the target from using magic for 15 seconds. -spell.wizardry:arrow_rain.desc="Archers, fire!" -spell.wizardry:banish.desc=Teleports the target against its will to a random location within a certain range. -spell.wizardry:black_hole.desc=Tear reality asunder. -spell.wizardry:blink.desc=Teleports the caster over a short distance to where they are pointing. -spell.wizardry:blizzard.desc=Creates a zone of swirling icy wind which slows and continually damages anything trapped inside. The caster is immune to the damage but is still slowed. -spell.wizardry:bubble.desc=Fires a jet of bubbles which causes anything it hits to float upwards helplessly. The target will fall after a certain time or if it is damaged. -spell.wizardry:chain_lightning.desc=Fires a spark of lightning at the target, which then chains to additional targets up to twice. -spell.wizardry:clairvoyance.desc=Reveals the path to a remembered location. With this spell selected, sneak-right-click on a block to set the location. Cast this spell normally to reveal the path. The path will fade after 90 seconds. -spell.wizardry:cobwebs.desc=Creates cobwebs where you are pointing, which greatly hamper the movement of any creatures caught amongst them. The cobwebs will vanish after 20 seconds or if broken. -spell.wizardry:conjure_armour.desc=Creates spectral armour around the caster which offers protection equal to that of iron armour. The armour lasts for 60 seconds. The caster must have an empty armour slot. -spell.wizardry:conjure_bow.desc=Creates a spectral bow with unlimited arrows that lasts for 30 seconds. -spell.wizardry:conjure_pickaxe.desc=Creates a spectral pickaxe of equal strength to an iron pickaxe that lasts for 30 seconds. -spell.wizardry:conjure_sword.desc=Creates a spectral sword of equal strength to an iron sword that lasts for 30 seconds. -spell.wizardry:cure_effects.desc=Removes all potion effects currently affecting the caster, good or bad. -spell.wizardry:curse_of_soulbinding.desc=Causes the target's soul to be inextricably bound to that of the caster, meaning all damage dealt to the caster is also dealt to the victim. Lasts until either the victim or the caster dies. -spell.wizardry:darkness_orb.desc=Fires a slow moving bolt of dark energy in the direction you are pointing, which withers whatever it hits. -spell.wizardry:darkvision.desc=Grants the caster night vision for 45 seconds. -spell.wizardry:dart.desc=Fires a dart in the direction you are pointing which damages and weakens its target. -spell.wizardry:decay.desc=Creates a patch of decay on the ground which infects any creature that touches it, causing lingering damage over time and spreading more decay wherever it walks. -spell.wizardry:decoy.desc=Creates an illusory clone of the caster which tricks mobs into attacking it instead. The decoy will vanish after 30 seconds. -spell.wizardry:detonate.desc=Causes an explosion where you are pointing, damaging all nearby creatures - including the caster, if they are too close. -spell.wizardry:diamondflesh.desc="Your arrows are no match for me!" -spell.wizardry:earthquake.desc=A true master of earth magic can move mountains. -spell.wizardry:entrapment.desc=Traps the target in a sphere of darkness which pulls it helplessly upwards and continually damages it. -spell.wizardry:fireball.desc=Launches a fireball in the direction you are pointing. -spell.wizardry:firebolt.desc=Shoots a jet of fire a short distance in front of you. -spell.wizardry:firebomb.desc=Lanches a firebomb in the direction you are pointing which explodes on impact, setting targets on fire. -spell.wizardry:fire_resistance.desc=Grants the caster fire resistance for 30 seconds. -spell.wizardry:fire_sigil.desc=Places a magical fire trap on the ground which damages and sets on fire the creature that triggers it. -spell.wizardry:fireskin.desc=Cloaks the caster in flames for 30 seconds, causing anything that attacks them to catch fire. -spell.wizardry:firestorm.desc="I am the dragon." -spell.wizardry:flame_ray.desc=Creates a stream of flames in the direction you are pointing which sets on fire and continually damages targets. -spell.wizardry:flaming_axe.desc=Creates a flaming axe which sets enemies on fire when hit. Lasts for 30 seconds. -spell.wizardry:flaming_weapon.desc=Temporarily imbues the first weapon on the caster's hotbar with the power of flame, causing it to set fire to its victims. The magic wears off after 45 seconds. -spell.wizardry:flight.desc=Soar like an eagle. -spell.wizardry:font_of_mana.desc="We were filled with an intense magical energy appearing to emanate from the centre of the..." - Extract from the journal of a forgotten mage; the rest of the page has been burnt away. -spell.wizardry:font_of_vitality.desc=It feels amazing. -spell.wizardry:force_arrow.desc=Shoots an arrow of force in the direction you are pointing. -spell.wizardry:forcefield.desc=Creates a forcefield around the caster which repels creatures and deflects projectiles. -spell.wizardry:force_orb.desc=Launches a sphere of force which damages and repels nearby creatures on impact. -spell.wizardry:forests_curse.desc="How dare you enter my forest!" -spell.wizardry:freeze.desc=Freezes the target for 10 seconds. Will also freeze water and create snow on the ground. -spell.wizardry:freezing_weapon.desc=Temporarily imbues the first weapon on the caster's hotbar with the power of frost, causing it to freeze its victims. The magic wears off after 45 seconds. -spell.wizardry:frost_axe.desc=Creates a frozen axe which freezes enemies when hit. Lasts for 30 seconds. -spell.wizardry:frost_ray.desc=Creates a stream of frost in the direction you are pointing which slows and continually damages targets. -spell.wizardry:frost_sigil.desc=Places a magical ice trap on the ground which damages and freezes the creature that triggers it. -spell.wizardry:glide.desc=Allows the caster to glide downwards while in the air and holding the use item button. -spell.wizardry:greater_fireball.desc=Launches a large fireball in the direction you are pointing which explodes on impact. -spell.wizardry:greater_heal.desc=Heals the caster by 4 hearts. -spell.wizardry:group_heal.desc=Heals the caster and all nearby allies and summoned creatures by 3 hearts. -spell.wizardry:growth_aura.desc=Grows all crops near the caster. Also grows tall grass and flowers on grass. -spell.wizardry:hailstorm.desc=It was during the great winter of the third age that the ice mages discovered their true power. -spell.wizardry:heal.desc=Heals the caster by 2 hearts. -spell.wizardry:heal_ally.desc=Heals the target by 2 and a half hearts. -spell.wizardry:healing_aura.desc=Creates a zone of healing energy which regenerates the health of any ally inside it. Any undead inside the healing aura will slowly take damage. -spell.wizardry:homing_spark.desc=Creates a floating spark which moves towards enemies. -spell.wizardry:ice_age.desc="You shall be frozen for an eternity!" -spell.wizardry:ice_charge.desc=Launches an ice charge which explodes on impact, freezing nearby creatures and releasing shards in all directions. -spell.wizardry:ice_lance.desc=Fires a great spear of ice in the direction you are pointing which overpenetrates targets, damaging and freezing them in the process. -spell.wizardry:ice_shard.desc=Fires a shard of ice in the direction you are pointing which damages and slows targets when hit. -spell.wizardry:ice_shroud.desc=Creates a shroud of cold around the caster for 30 seconds, causing anything that attacks them to be frozen. -spell.wizardry:ice_spikes.desc=Causes razor-sharp ice spikes to rise from the ground where you are pointing, skewering any creatures caught amongst them. -spell.wizardry:ice_statue.desc=Freezes the target solid for 20 seconds or until broken out. The target cannot move or do anything while frozen but is also impervious to all damage. -spell.wizardry:ignite.desc=Sets the target on fire for 10 seconds. Also works like a flint and steel. -spell.wizardry:imbue_weapon.desc=Temporarily imbues the first weapon on the caster's hotbar with magic, rendering it more effective. The magic wears off after 45 seconds. -spell.wizardry:intimidate.desc=Emits an intimidating growl which causes nearby creatures to run away in fear. Fear stricken creatures will recover after 30 seconds. -spell.wizardry:invigorating_presence.desc=Grants the caster and all nearby allies increased strength for 45 seconds. -spell.wizardry:invisibility.desc=Makes the caster invisible for 30 seconds. -spell.wizardry:invoke_weather.desc=Changes the weather in the world. -spell.wizardry:ironflesh.desc=Greatly improves the caster's damage resistance for 30 seconds. -spell.wizardry:leap.desc=Causes the caster to jump upwards several blocks and slightly forward. -spell.wizardry:levitation.desc=Raises the caster upwards while the use item button is held. Will also negate fall damage if used before hitting the ground. -spell.wizardry:life_drain.desc=Creates a stream of withering energy in the direction you are pointing which drains the life of the target and uses it to gradually regenerate your health. -spell.wizardry:light.desc=Creates a magical point of light which illuminates the surrounding area. Lasts for 30 seconds. -spell.wizardry:lightning_arrow.desc=Shoots an arrow of lightning in the direction you are pointing. -spell.wizardry:lightning_bolt.desc=Causes lightning to strike where you are pointing. -spell.wizardry:lightning_disc.desc=Sends a disc of lightning flying off in the direction you are pointing, which seeks targets. -spell.wizardry:lightning_hammer.desc="I smite you by the wrath of the heavens!" -spell.wizardry:lightning_pulse.desc=Charges the ground around the caster with lightning, damaging and repelling nearby creatures. -spell.wizardry:lightning_ray.desc=Creates a stream of lightning in the direction you are pointing which continually damages targets. -spell.wizardry:lightning_sigil.desc=Places a magical lightning trap on the ground which damages the creature that triggers it and chains lightning to other nearby creatures. -spell.wizardry:lightning_web.desc="Focus. Channel the storm in your mind through your wand and unleash its fury." -spell.wizardry:magic_missile.desc=Fires a bolt of magical energy in the direction you are pointing. -spell.wizardry:metamorphosis.desc=Changes the target into another form. Only works on some creatures. -spell.wizardry:meteor.desc=Some wizards just want to see the world burn... -spell.wizardry:mind_control.desc=Takes control of the target's mind for 30 seconds, causing it switch sides and fight for the caster instead. Will not work on creatures that are too strong-willed. -spell.wizardry:mind_trick.desc=Confuses and disorients the target for 15 seconds, rendering it unable to attack effectively. The effect will be dispelled if the target takes damage. -spell.wizardry:none.desc=To get a spell book with the /give command, use metadata: /give [player] wizardry:spell_book 1 [spell id] (if you found this book in a chest, some other mod has messed things up). -spell.wizardry:oakflesh.desc=Improves the caster's damage resistance for 30 seconds. -spell.wizardry:petrify.desc=Turns the target to stone until broken out, with a chance for it to break out when it is dark. The target cannot move or do anything while petrified but is also impervious to all damage. -spell.wizardry:phase_step.desc=Teleports the caster through a 1 block thick wall in front of them. Range upgrades will increase the thickness you can teleport through. -spell.wizardry:plague_of_darkness.desc=The darkness will consume them all... -spell.wizardry:pocket_furnace.desc=Smelts up to 5 smeltable items in the caster's inventory. Items on the hotbar will be smelted first. -spell.wizardry:pocket_workbench.desc=Allows the caster to craft items as if they were at a crafting table. -spell.wizardry:poison.desc=Fires poison in the direction you are pointing. -spell.wizardry:poison_bomb.desc=Lanches a poison bomb in the direction you are pointing which explodes on impact, poisoning nearby creatures. -spell.wizardry:replenish_hunger.desc=Replenishes the caster's food level by 6 hunger points. -spell.wizardry:ring_of_fire.desc=Creates a ring of fire around the caster, damaging all nearby enemies and setting them on fire. -spell.wizardry:shadow_ward.desc=Creates a wall of darkness in front of the caster which causes half of all incoming damage to be inflicted upon the attacker instead. -spell.wizardry:shield.desc=Creates a protective barrier of force that blocks projectiles and magic. Also grants the caster a weak resistance effect. -spell.wizardry:shockwave.desc=Boom. -spell.wizardry:silverfish_swarm.desc="Ahhhh! They're MULTIPLYING!" -spell.wizardry:sixth_sense.desc=Allows the caster to sense the locations of nearby creatures, even through walls, for 20 seconds. -spell.wizardry:slime.desc=Engulfs the target in slime which slows and continually damages it. The slime bursts after 10 seconds. -spell.wizardry:smoke_bomb.desc=Launches a smoke bomb in the direction you are pointing which explodes on impact, releasing smoke and blinding nearby creatures for a short time. -spell.wizardry:snare.desc=Sets a trap on the ground which damages and briefly slows the creature that triggers it. -spell.wizardry:snowball.desc=Launches a snowball in the direction you are pointing. -spell.wizardry:spark_bomb.desc=Launches a shock charge in the direction you are pointing which releases sparks at nearby enemies on impact. -spell.wizardry:spectral_pathway.desc=Creates an indestructible magical bridge in front of you which extends for 15 blocks. The bridge vanishes after 60 seconds. -spell.wizardry:spider_swarm.desc=Summons a swarm of venomous spiders to fight for you. The spiders will disappear after 30 seconds or if they are killed. -spell.wizardry:static_aura.desc=Surrounds the caster with lightning for 30 seconds, firing a spark of lightning at anything that hits them. -spell.wizardry:summon_blaze.desc=Summons a blaze to fight for you. The blaze will disappear after 30 seconds or if it is killed. -spell.wizardry:summon_ice_giant.desc="Smash them!" -spell.wizardry:summon_ice_wraith.desc=Summons an ice wraith to fight for you. The ice wraith will disappear after 30 seconds or if it is killed. -spell.wizardry:summon_iron_golem.desc=Automatic automated autonomous automaton. -spell.wizardry:summon_lightning_wraith.desc=Summons a lightning wraith to fight for you. The lightning wraith will disappear after 30 seconds or if it is killed. -spell.wizardry:summon_phoenix.desc=From the ashes... -spell.wizardry:summon_shadow_wraith.desc=Summons a shadow wraith to fight for you. -spell.wizardry:summon_skeleton.desc=Summons a skeleton to fight for you. The skeleton will disappear after 30 seconds or if it is killed. -spell.wizardry:summon_skeleton_legion.desc="Rise, undead army!" -spell.wizardry:summon_snow_golem.desc=Creates a snow golem to fight for you. Lasts until the snow golem dies. -spell.wizardry:summon_spirit_horse.desc=Summons a spirit horse for you to ride. The spirit horse will vanish a short while after it is dismounted, or you can dismiss it by shift-right-clicking on it with any wand. -spell.wizardry:summon_spirit_wolf.desc=Summons a spirit wolf companion to fight for you. The spirit wolf will only disappear if it is killed, or you can dismiss it by shift-right-clicking on it with any wand. -spell.wizardry:summon_storm_elemental.desc="Storm Elemental: An ancient manifestation of the elements, it can hardly contain the raw power churning within it." - The Wizard's Guide to Arcane Beings, Volume I_i -spell.wizardry:summon_wither_skeleton.desc=Summons a wither skeleton to fight for you. The wither skeleton will disappear after 30 seconds or if it is killed. -spell.wizardry:summon_zombie.desc=Summons a zombie to fight for you. The zombie will disappear after 30 seconds or if it is killed. -spell.wizardry:telekinesis.desc=Moves an item or other small object towards you, or right-clicks the block you are looking at. Can also be used to disarm players. -spell.wizardry:thunderbolt.desc=Shoots a bolt of thunder which knocks back targets. -spell.wizardry:thunderstorm.desc="Mwahahahahahaha!" -spell.wizardry:tornado.desc=Unleashes a tornado in the direction you are pointing which hurls anything in its path skywards. -spell.wizardry:transience.desc=Makes the caster transient for 20 seconds. The caster is immune to all damage while transient but cannot break or place blocks or cause any damage. -spell.wizardry:transportation.desc=Transports the caster to their remembered stone circle. To use this spell, make a circle of stones of transportation, then right click it with a wand. -spell.wizardry:vanishing_box.desc=Grants the caster access to their ender chest storage. -spell.wizardry:wall_of_frost.desc=Winter at your fingertips. -spell.wizardry:water_breathing.desc=Allows the caster to breathe underwater for 60 seconds. -spell.wizardry:whirlwind.desc=Causes the target to be blown upwards and away from you at speed. -spell.wizardry:wither.desc=Fires a ray of darkness which withers anything it touches. -spell.wizardry:wither_skull.desc=Launches a wither skull in the direction you are pointing. +spell.agility.desc=Grants the caster faster movement speed and greater jump height for 30 seconds. +spell.arc.desc=Fires a spark of lightning at the target. +spell.arcane_jammer.desc=Prevents the target from using magic for 15 seconds. +spell.arrow_rain.desc="Archers, fire!" +spell.banish.desc=Teleports the target against its will to a random location within a certain range. +spell.black_hole.desc=Tear reality asunder. +spell.blink.desc=Teleports the caster over a short distance to where they are pointing. +spell.blizzard.desc=Creates a zone of swirling icy wind which slows and continually damages anything trapped inside. The caster is immune to the damage but is still slowed. +spell.bubble.desc=Fires a jet of bubbles which causes anything it hits to float upwards helplessly. The target will fall after a certain time or if it is damaged. +spell.chain_lightning.desc=Fires a spark of lightning at the target, which then chains to additional targets up to twice. +spell.clairvoyance.desc=Reveals the path to a remembered location. With this spell selected, sneak-right-click on a block to set the location. Cast this spell normally to reveal the path. The path will fade after 90 seconds. +spell.cobwebs.desc=Creates cobwebs where you are pointing, which greatly hamper the movement of any creatures caught amongst them. The cobwebs will vanish after 20 seconds or if broken. +spell.conjure_armour.desc=Creates spectral armour around the caster which offers protection equal to that of iron armour. The armour lasts for 60 seconds. The caster must have an empty armour slot. +spell.conjure_bow.desc=Creates a spectral bow with unlimited arrows that lasts for 30 seconds. +spell.conjure_pickaxe.desc=Creates a spectral pickaxe of equal strength to an iron pickaxe that lasts for 30 seconds. +spell.conjure_sword.desc=Creates a spectral sword of equal strength to an iron sword that lasts for 30 seconds. +spell.cure_effects.desc=Removes all potion effects currently affecting the caster, good or bad. +spell.curse_of_soulbinding.desc=Causes the target's soul to be inextricably bound to that of the caster, meaning all damage dealt to the caster is also dealt to the victim. Lasts until either the victim or the caster dies. +spell.darkness_orb.desc=Fires a slow moving bolt of dark energy in the direction you are pointing, which withers whatever it hits. +spell.darkvision.desc=Grants the caster night vision for 45 seconds. +spell.dart.desc=Fires a dart in the direction you are pointing which damages and weakens its target. +spell.decay.desc=Creates a patch of decay on the ground which infects any creature that touches it, causing lingering damage over time and spreading more decay wherever it walks. +spell.decoy.desc=Creates an illusory clone of the caster which tricks mobs into attacking it instead. The decoy will vanish after 30 seconds. +spell.detonate.desc=Causes an explosion where you are pointing, damaging all nearby creatures - including the caster, if they are too close. +spell.diamondflesh.desc="Your arrows are no match for me!" +spell.earthquake.desc=A true master of earth magic can move mountains. +spell.entrapment.desc=Traps the target in a sphere of darkness which pulls it helplessly upwards and continually damages it. +spell.fireball.desc=Launches a fireball in the direction you are pointing. +spell.firebolt.desc=Shoots a jet of fire a short distance in front of you. +spell.firebomb.desc=Lanches a firebomb in the direction you are pointing which explodes on impact, setting targets on fire. +spell.fire_resistance.desc=Grants the caster fire resistance for 30 seconds. +spell.fire_sigil.desc=Places a magical fire trap on the ground which damages and sets on fire the creature that triggers it. +spell.fireskin.desc=Cloaks the caster in flames for 30 seconds, causing anything that attacks them to catch fire. +spell.firestorm.desc="I am the dragon." +spell.flame_ray.desc=Creates a stream of flames in the direction you are pointing which sets on fire and continually damages targets. +spell.flaming_axe.desc=Creates a flaming axe which sets enemies on fire when hit. Lasts for 30 seconds. +spell.flaming_weapon.desc=Temporarily imbues the first weapon on the caster's hotbar with the power of flame, causing it to set fire to its victims. The magic wears off after 45 seconds. +spell.flight.desc=Soar like an eagle. +spell.font_of_mana.desc="We were filled with an intense magical energy appearing to emanate from the centre of the..." - Extract from the journal of a forgotten mage; the rest of the page has been burnt away. +spell.font_of_vitality.desc=It feels amazing. +spell.force_arrow.desc=Shoots an arrow of force in the direction you are pointing. +spell.forcefield.desc=Creates a forcefield around the caster which repels creatures and deflects projectiles. +spell.force_orb.desc=Launches a sphere of force which damages and repels nearby creatures on impact. +spell.forests_curse.desc="How dare you enter my forest!" +spell.freeze.desc=Freezes the target for 10 seconds. Will also freeze water and create snow on the ground. +spell.freezing_weapon.desc=Temporarily imbues the first weapon on the caster's hotbar with the power of frost, causing it to freeze its victims. The magic wears off after 45 seconds. +spell.frost_axe.desc=Creates a frozen axe which freezes enemies when hit. Lasts for 30 seconds. +spell.frost_ray.desc=Creates a stream of frost in the direction you are pointing which slows and continually damages targets. +spell.frost_sigil.desc=Places a magical ice trap on the ground which damages and freezes the creature that triggers it. +spell.glide.desc=Allows the caster to glide downwards while in the air and holding the use item button. +spell.greater_fireball.desc=Launches a large fireball in the direction you are pointing which explodes on impact. +spell.greater_heal.desc=Heals the caster by 4 hearts. +spell.group_heal.desc=Heals the caster and all nearby allies and summoned creatures by 3 hearts. +spell.growth_aura.desc=Grows all crops near the caster. Also grows tall grass and flowers on grass. +spell.hailstorm.desc=It was during the great winter of the third age that the ice mages discovered their true power. +spell.heal.desc=Heals the caster by 2 hearts. +spell.heal_ally.desc=Heals the target by 2 and a half hearts. +spell.healing_aura.desc=Creates a zone of healing energy which regenerates the health of any ally inside it. Any undead inside the healing aura will slowly take damage. +spell.homing_spark.desc=Creates a floating spark which moves towards enemies. +spell.ice_age.desc="You shall be frozen for an eternity!" +spell.ice_charge.desc=Launches an ice charge which explodes on impact, freezing nearby creatures and releasing shards in all directions. +spell.ice_lance.desc=Fires a great spear of ice in the direction you are pointing which overpenetrates targets, damaging and freezing them in the process. +spell.ice_shard.desc=Fires a shard of ice in the direction you are pointing which damages and slows targets when hit. +spell.ice_shroud.desc=Creates a shroud of cold around the caster for 30 seconds, causing anything that attacks them to be frozen. +spell.ice_spikes.desc=Causes razor-sharp ice spikes to rise from the ground where you are pointing, skewering any creatures caught amongst them. +spell.ice_statue.desc=Freezes the target solid for 20 seconds or until broken out. The target cannot move or do anything while frozen but is also impervious to all damage. +spell.ignite.desc=Sets the target on fire for 10 seconds. Also works like a flint and steel. +spell.imbue_weapon.desc=Temporarily imbues the first weapon on the caster's hotbar with magic, rendering it more effective. The magic wears off after 45 seconds. +spell.intimidate.desc=Emits an intimidating growl which causes nearby creatures to run away in fear. Fear stricken creatures will recover after 30 seconds. +spell.invigorating_presence.desc=Grants the caster and all nearby allies increased strength for 45 seconds. +spell.invisibility.desc=Makes the caster invisible for 30 seconds. +spell.invoke_weather.desc=Changes the weather in the world. +spell.ironflesh.desc=Greatly improves the caster's damage resistance for 30 seconds. +spell.leap.desc=Causes the caster to jump upwards several blocks and slightly forward. +spell.levitation.desc=Raises the caster upwards while the use item button is held. Will also negate fall damage if used before hitting the ground. +spell.life_drain.desc=Creates a stream of withering energy in the direction you are pointing which drains the life of the target and uses it to gradually regenerate your health. +spell.light.desc=Creates a magical point of light which illuminates the surrounding area. Lasts for 30 seconds. +spell.lightning_arrow.desc=Shoots an arrow of lightning in the direction you are pointing. +spell.lightning_bolt.desc=Causes lightning to strike where you are pointing. +spell.lightning_disc.desc=Sends a disc of lightning flying off in the direction you are pointing, which seeks targets. +spell.lightning_hammer.desc="I smite you by the wrath of the heavens!" +spell.lightning_pulse.desc=Charges the ground around the caster with lightning, damaging and repelling nearby creatures. +spell.lightning_ray.desc=Creates a stream of lightning in the direction you are pointing which continually damages targets. +spell.lightning_sigil.desc=Places a magical lightning trap on the ground which damages the creature that triggers it and chains lightning to other nearby creatures. +spell.lightning_web.desc="Focus. Channel the storm in your mind through your wand and unleash its fury." +spell.magic_missile.desc=Fires a bolt of magical energy in the direction you are pointing. +spell.metamorphosis.desc=Changes the target into another form. Only works on some creatures. +spell.meteor.desc=Some wizards just want to see the world burn... +spell.mind_control.desc=Takes control of the target's mind for 30 seconds, causing it switch sides and fight for the caster instead. Will not work on creatures that are too strong-willed. +spell.mind_trick.desc=Confuses and disorients the target for 15 seconds, rendering it unable to attack effectively. The effect will be dispelled if the target takes damage. +spell.none.desc=To get a spell book with the /give command, use metadata: /give [player] wizardry:spell_book 1 [spell id] (if you found this book in a chest, some other mod has messed things up). +spell.oakflesh.desc=Improves the caster's damage resistance for 30 seconds. +spell.petrify.desc=Turns the target to stone until broken out, with a chance for it to break out when it is dark. The target cannot move or do anything while petrified but is also impervious to all damage. +spell.phase_step.desc=Teleports the caster through a 1 block thick wall in front of them. Range upgrades will increase the thickness you can teleport through. +spell.plague_of_darkness.desc=The darkness will consume them all... +spell.pocket_furnace.desc=Smelts up to 5 smeltable items in the caster's inventory. Items on the hotbar will be smelted first. +spell.pocket_workbench.desc=Allows the caster to craft items as if they were at a crafting table. +spell.poison.desc=Fires poison in the direction you are pointing. +spell.poison_bomb.desc=Lanches a poison bomb in the direction you are pointing which explodes on impact, poisoning nearby creatures. +spell.replenish_hunger.desc=Replenishes the caster's food level by 6 hunger points. +spell.ring_of_fire.desc=Creates a ring of fire around the caster, damaging all nearby enemies and setting them on fire. +spell.shadow_ward.desc=Creates a wall of darkness in front of the caster which causes half of all incoming damage to be inflicted upon the attacker instead. +spell.shield.desc=Creates a protective barrier of force that blocks projectiles and magic. Also grants the caster a weak resistance effect. +spell.shockwave.desc=Boom. +spell.silverfish_swarm.desc="Ahhhh! They're MULTIPLYING!" +spell.sixth_sense.desc=Allows the caster to sense the locations of nearby creatures, even through walls, for 20 seconds. +spell.slime.desc=Engulfs the target in slime which slows and continually damages it. The slime bursts after 10 seconds. +spell.smoke_bomb.desc=Launches a smoke bomb in the direction you are pointing which explodes on impact, releasing smoke and blinding nearby creatures for a short time. +spell.snare.desc=Sets a trap on the ground which damages and briefly slows the creature that triggers it. +spell.snowball.desc=Launches a snowball in the direction you are pointing. +spell.spark_bomb.desc=Launches a shock charge in the direction you are pointing which releases sparks at nearby enemies on impact. +spell.spectral_pathway.desc=Creates an indestructible magical bridge in front of you which extends for 15 blocks. The bridge vanishes after 60 seconds. +spell.spider_swarm.desc=Summons a swarm of venomous spiders to fight for you. The spiders will disappear after 30 seconds or if they are killed. +spell.static_aura.desc=Surrounds the caster with lightning for 30 seconds, firing a spark of lightning at anything that hits them. +spell.summon_blaze.desc=Summons a blaze to fight for you. The blaze will disappear after 30 seconds or if it is killed. +spell.summon_ice_giant.desc="Smash them!" +spell.summon_ice_wraith.desc=Summons an ice wraith to fight for you. The ice wraith will disappear after 30 seconds or if it is killed. +spell.summon_iron_golem.desc=Automatic automated autonomous automaton. +spell.summon_lightning_wraith.desc=Summons a lightning wraith to fight for you. The lightning wraith will disappear after 30 seconds or if it is killed. +spell.summon_phoenix.desc=From the ashes... +spell.summon_shadow_wraith.desc=Summons a shadow wraith to fight for you. +spell.summon_skeleton.desc=Summons a skeleton to fight for you. The skeleton will disappear after 30 seconds or if it is killed. +spell.summon_skeleton_legion.desc="Rise, undead army!" +spell.summon_snow_golem.desc=Creates a snow golem to fight for you. Lasts until the snow golem dies. +spell.summon_spirit_horse.desc=Summons a spirit horse for you to ride. The spirit horse will vanish a short while after it is dismounted, or you can dismiss it by shift-right-clicking on it with any wand. +spell.summon_spirit_wolf.desc=Summons a spirit wolf companion to fight for you. The spirit wolf will only disappear if it is killed, or you can dismiss it by shift-right-clicking on it with any wand. +spell.summon_storm_elemental.desc="Storm Elemental: An ancient manifestation of the elements, it can hardly contain the raw power churning within it." - The Wizard's Guide to Arcane Beings, Volume II +spell.summon_wither_skeleton.desc=Summons a wither skeleton to fight for you. The wither skeleton will disappear after 30 seconds or if it is killed. +spell.summon_zombie.desc=Summons a zombie to fight for you. The zombie will disappear after 30 seconds or if it is killed. +spell.telekinesis.desc=Moves an item or other small object towards you, or right-clicks the block you are looking at. Can also be used to disarm players. +spell.thunderbolt.desc=Shoots a bolt of thunder which knocks back targets. +spell.thunderstorm.desc="Mwahahahahahaha!" +spell.tornado.desc=Unleashes a tornado in the direction you are pointing which hurls anything in its path skywards. +spell.transience.desc=Makes the caster transient for 20 seconds. The caster is immune to all damage while transient but cannot break or place blocks or cause any damage. +spell.transportation.desc=Transports the caster to their remembered stone circle. To use this spell, make a circle of stones of transportation, then right click it with a wand. +spell.vanishing_box.desc=Grants the caster access to their ender chest storage. +spell.wall_of_frost.desc=Winter at your fingertips. +spell.water_breathing.desc=Allows the caster to breathe underwater for 60 seconds. +spell.whirlwind.desc=Causes the target to be blown upwards and away from you at speed. +spell.wither.desc=Fires a ray of darkness which withers anything it touches. +spell.wither_skull.desc=Launches a wither skull in the direction you are pointing. -spell.wizardry:invoke_weather.sun=The rain begins to stop... -spell.wizardry:invoke_weather.rain=The heavens open... -spell.wizardry:transportation.missing=Your remembered stone circle is missing or obstructed... -spell.wizardry:transportation.undefined=You must remember the location of a stone circle first! -spell.wizardry:transportation.wrongdimension=Your remembered stone circle is in another dimension... -spell.wizardry:clairvoyance.searching=Searching... -spell.wizardry:clairvoyance.confirm=The path revealed upon casting %1$s will now lead back to this point -spell.wizardry:clairvoyance.outofrange=Your remembered location is too far away or inaccessible... -spell.wizardry:clairvoyance.undefined=You must remember a location first! -spell.wizardry:clairvoyance.wrongdimension=Your remembered location is in another dimension... +spell.invoke_weather.sun=The rain begins to stop... +spell.invoke_weather.rain=The heavens open... +spell.transportation.missing=Your remembered stone circle is missing or obstructed... +spell.transportation.undefined=You must remember the location of a stone circle first! +spell.transportation.wrongdimension=Your remembered stone circle is in another dimension... +spell.clairvoyance.searching=Searching... +spell.clairvoyance.confirm=The path revealed upon casting %1$s will now lead back to this point +spell.clairvoyance.outofrange=Your remembered location is too far away or inaccessible... +spell.clairvoyance.undefined=You must remember a location first! +spell.clairvoyance.wrongdimension=Your remembered location is in another dimension... -potion.wizardry:frost=Frostbite -potion.wizardry:fireskin=Fireskin -potion.wizardry:ice_shroud=Ice Shroud -potion.wizardry:static_aura=Static Aura -potion.wizardry:transience=Transience -potion.wizardry:decay=Decay -potion.wizardry:sixth_sense=Sixth Sense -potion.wizardry:arcane_jammer=Arcane Jammer -potion.wizardry:mind_trick=Mind Trick -potion.wizardry:mind_control=Mind Control -potion.wizardry:font_of_mana=Font of Mana -potion.wizardry:fear=Fear +potion.frost=Frostbite +potion.fireskin=Fireskin +potion.ice_shroud=Ice Shroud +potion.static_aura=Static Aura +potion.transience=Transience +potion.decay=Decay +potion.sixth_sense=Sixth Sense +potion.arcane_jammer=Arcane Jammer +potion.mind_trick=Mind Trick +potion.mind_control=Mind Control +potion.font_of_mana=Font of Mana +potion.fear=Fear -enchantment.wizardry:magic_sword=Imbuement -enchantment.wizardry:magic_bow=Imbuement -enchantment.wizardry:flaming_weapon=Fire Imbuement -enchantment.wizardry:freezing_weapon=Frost Imbuement +enchantment.magic_sword=Imbuement +enchantment.magic_bow=Imbuement +enchantment.flaming_weapon=Fire Imbuement +enchantment.freezing_weapon=Frost Imbuement key.categories.wizardry=Wizardry -key.wizardry.next_spell=Next Spell -key.wizardry.previous_spell=Previous Spell +key.next_spell=Next Spell +key.previous_spell=Previous Spell -death.attack.wizardry_magic=%1$s was killed by %2$s using magic -death.attack.indirect_wizardry_magic=%1$s was killed by %2$s using magic +death.attack.wizardryMagic=%1$s was killed by %2$s using magic +death.attack.indirectWizardryMagic=%1$s was killed by %2$s using magic -commands.wizardry:cast.usage=/%1$s [player] [damage multiplier] [range multiplier] [duration multiplier] [blast multiplier] -commands.wizardry:cast.success=Successfully cast %1$s -commands.wizardry:cast.success_continuous=Successfully cast %1$s; repeat the command to stop -commands.wizardry:cast.success_remote=Successfully cast %1$s as %2$s -commands.wizardry:cast.success_remote_continuous=Successfully cast %1$s as %2$s; repeat the command to stop -commands.wizardry:cast.fail=Unable to cast %1$s -commands.wizardry:cast.not_found=There is no such spell with ID %1$s -commands.wizardry:cast.tag_error=Data tag parsing failed: %s +commands.cast.usage=/%1$s [player] [damage multiplier] [range multiplier] [duration multiplier] [blast multiplier] +commands.cast.success=Successfully cast %1$s +commands.cast.success_continuous=Successfully cast %1$s; repeat the command to stop +commands.cast.success_remote=Successfully cast %1$s as %2$s +commands.cast.success_remote_continuous=Successfully cast %1$s as %2$s; repeat the command to stop +commands.cast.fail=Unable to cast %1$s +commands.cast.not_found=There is no such spell with ID %1$s -commands.wizardry:ally.usage=/%1$s [player] -commands.wizardry:ally.addally=%1$s has been added to %2$s's list of allies -commands.wizardry:ally.removeally=%1$s has been removed from %2$s's list of allies -commands.wizardry:ally.self=Players cannot be an ally of themselves! -commands.wizardry:ally.permission=You do not have permission to change other players' allies +commands.ally.usage=/%1$s [player] +commands.ally.addally=%1$s has been added to %2$s's list of allies +commands.ally.removeally=%1$s has been removed from %2$s's list of allies +commands.ally.self=Players cannot be an ally of themselves! +commands.ally.permission=You do not have permission to change other players' allies -commands.wizardry:allies.usage=/%1$s [player] -commands.wizardry:allies.list=Players allied to you: %1$s -commands.wizardry:allies.list_other=Players allied to %1$s: %2$s -commands.wizardry:allies.permission=You do not have permission to view other players' allies -commands.wizardry:allies.none=None +commands.allies.usage=/%1$s [player] +commands.allies.list=Players allied to you: %1$s +commands.allies.list_other=Players allied to %1$s: %2$s +commands.allies.permission=You do not have permission to view other players' allies +commands.allies.none=None -commands.wizardry:discoverspell.usage=/%1$s [player] -commands.wizardry:discoverspell.not_found=There is no such spell with ID %1$s -commands.wizardry:discoverspell.clear=Cleared all spell discovery data for %1$s -commands.wizardry:discoverspell.all=Added all spells to %1$s's spell discovery data -commands.wizardry:discoverspell.addspell=Added %1$s to %2$s's spell discovery data -commands.wizardry:discoverspell.removespell=Removed %1$s from %2$s's spell discovery data +commands.discoverspell.usage=/%1$s [player] +commands.discoverspell.not_found=There is no such spell with ID %1$s +commands.discoverspell.clear=Cleared all spell discovery data for %1$s +commands.discoverspell.all=Added all spells to %1$s's spell discovery data +commands.discoverspell.addspell=Added %1$s to %2$s's spell discovery data +commands.discoverspell.removespell=Removed %1$s from %2$s's spell discovery data -config.wizardry.title.general=Mod Options +config.title.general=Mod Options -config.wizardry.category.spells=Configure Spells -config.wizardry.category.spells.tooltip=Select which spells are enabled -config.wizardry.title.spells=Spell Configuration -config.wizardry.subtitle.spells=Set a spell to false to disable it. +config.category.spells=Configure Spells +config.category.spells.tooltip=Select which spells are enabled +config.title.spells=Spell Configuration +config.subtitle.spells=Set a spell to false to disable it. -config.wizardry.category.resistances=Configure Resistances -config.wizardry.category.resistances.tooltip=Configure which mobs are immune to different types of magic -config.wizardry.title.resistances=Resistance Configuration -config.wizardry.subtitle.resistances=See descriptions of individual options for more details. +config.category.resistances=Configure Resistances +config.category.resistances.tooltip=Configure which mobs are immune to different types of magic +config.title.resistances=Resistance Configuration +config.subtitle.resistances=See descriptions of individual options for more details. -config.wizardry.category.ids=Configure IDs -config.wizardry.category.ids.tooltip=Change the IDs used by wizardry -config.wizardry.title.ids=ID Configuration -config.wizardry.subtitle.ids=Change these IDs if they conflict with another mod. +config.category.ids=Configure IDs +config.category.ids.tooltip=Change the IDs used by wizardry +config.title.ids=ID Configuration +config.subtitle.ids=Change these IDs if they conflict with another mod. -config.wizardry.tower_rarity=Tower Rarity -config.wizardry.ore_dimensions=Ore Dimensions -config.wizardry.flower_dimensions=Flower Dimensions -config.wizardry.tower_dimensions=Tower Dimensions -config.wizardry.spell_book_drop_chance=Spell Book Drop Chance -config.wizardry.generate_loot=Generate Loot -config.wizardry.firebomb_is_craftable=Firebomb Is Craftable -config.wizardry.poison_bomb_is_craftable=Poison Bomb Is Craftable -config.wizardry.smoke_bomb_is_craftable=Smoke Bomb Is Craftable -config.wizardry.use_alternate_scroll_recipe=Use Alternate Scroll Recipe -config.wizardry.teleport_through_unbreakable_blocks=Teleport Through Unbreakable Blocks -config.wizardry.show_summoned_creature_names=Show Summoned Creature Names -config.wizardry.friendly_fire=Friendly Fire -config.wizardry.telekinetic_disarmament=Telekinetic Disarmament -config.wizardry.discovery_mode=Discovery Mode -config.wizardry.enable_shift_scrolling=Enable Shift-_scrolling -config.wizardry.minion_revenge_targeting=Minion Revenge Targeting -config.wizardry.player_damage_scaling=Player Damage Scaling Factor -config.wizardry.npc_damage_scaling=NPC Damage Scaling Factor -config.wizardry.cast_command_multiplier_limit=Cast Command Multiplier Limit -config.wizardry.summoned_creature_targets_whitelist=Summoned Creature Target Whitelist -config.wizardry.summoned_creature_targets_blacklist=Summoned Creature Target Blacklist -config.wizardry.spell_hud_position=Spell HUD Position -config.wizardry.cast_command_name=Cast Spell Command Name -config.wizardry.discoverspell_command_name=Discover Spell Command Name -config.wizardry.ally_command_name=Set Ally Command Name -config.wizardry.allies_command_name=View Allies Command Name +config.tower_rarity=Tower Rarity +config.ore_dimensions=Ore Dimensions +config.flower_dimensions=Flower Dimensions +config.tower_dimensions=Tower Dimensions +config.spell_book_drop_chance=Spell Book Drop Chance +config.generate_loot=Generate Loot +config.firebomb_is_craftable=Firebomb Is Craftable +config.poison_bomb_is_craftable=Poison Bomb Is Craftable +config.smoke_bomb_is_craftable=Smoke Bomb Is Craftable +config.use_alternate_scroll_recipe=Use Alternate Scroll Recipe +config.teleport_through_unbreakable_blocks=Teleport Through Unbreakable Blocks +config.show_summoned_creature_names=Show Summoned Creature Names +config.friendly_fire=Friendly Fire +config.telekinetic_disarmament=Telekinetic Disarmament +config.discovery_mode=Discovery Mode +config.enable_shift_scrolling=Enable Shift-Scrolling +config.minion_revenge_targeting=Minion Revenge Targeting +config.player_damage_scaling=Player Damage Scaling Factor +config.npc_damage_scaling=NPC Damage Scaling Factor +config.cast_command_multiplier_limit=Cast Command Multiplier Limit +config.summoned_creature_targets_whitelist=Summoned Creature Target Whitelist +config.summoned_creature_targets_blacklist=Summoned Creature Target Blacklist +config.spell_hud_position=Spell HUD Position +config.cast_command_name=Cast Spell Command Name +config.discoverspell_command_name=Discover Spell Command Name +config.ally_command_name=Set Ally Command Name +config.allies_command_name=View Allies Command Name -config.wizardry.mobs_immune_to_fire=Mobs Immune To Fire -config.wizardry.mobs_immune_to_ice=Mobs Immune To Ice -config.wizardry.mobs_immune_to_lightning=Mobs Immune To Lightning -config.wizardry.mobs_immune_to_wither=Mobs Immune To Wither -config.wizardry.mobs_immune_to_poison=Mobs Immune To Poison +config.mobs_immune_to_fire=Mobs Immune To Fire +config.mobs_immune_to_ice=Mobs Immune To Ice +config.mobs_immune_to_lightning=Mobs Immune To Lightning +config.mobs_immune_to_wither=Mobs Immune To Wither +config.mobs_immune_to_poison=Mobs Immune To Poison -config.wizardry.tower_rarity.tooltip=Rarity of wizard towers. Higher numbers are rarer. Set to 0 to disable wizard towers completely. -config.wizardry.ore_dimensions.tooltip=List of dimension ids in which crystal ore will generate. Note that removing the overworld (id 0) from this list will make the mod VERY difficult to play! -config.wizardry.flower_dimensions.tooltip=List of dimension ids in which crystal flowers will generate. -config.wizardry.tower_dimensions.tooltip=List of dimension ids in which wizard towers will generate. -config.wizardry.spell_book_drop_chance.tooltip=The chance for mobs to drop a spell book when killed. The greater this number, the more often they will drop. Set to 0 to disable spell book drops. Set to 200 for guaranteed drops. -config.wizardry.generate_loot.tooltip=Whether to generate wizardry loot in dungeon chests. -config.wizardry.firebomb_is_craftable.tooltip=Whether firebombs can be crafted or not. -config.wizardry.poison_bomb_is_craftable.tooltip=Whether poison bombs can be crafted or not. -config.wizardry.smoke_bomb_is_craftable.tooltip=Whether smoke bombs can be crafted or not. -config.wizardry.use_alternate_scroll_recipe.tooltip=Whether to require a magic crystal in the shapeless crafting recipe for blank scrolls. Set to true if another mod adds a conflicting recipe. -config.wizardry.teleport_through_unbreakable_blocks.tooltip=Whether players are allowed to teleport through unbreakable blocks (e.g. bedrock) using the phase step spell. -config.wizardry.show_summoned_creature_names.tooltip=Whether to show summoned creatures' names and owners above their heads. -config.wizardry.friendly_fire.tooltip=Whether to allow players to damage their designated allies using magic. -config.wizardry.telekinetic_disarmament.tooltip=Whether to allow players to disarm other players using the telekinesis spell.wizardry: Set to false to prevent stealing of items. -config.wizardry.discovery_mode.tooltip=For those who like a sense of mystery! When set to true, spells you haven't cast yet will be unreadable until you cast them (on a per-world basis). Has no effect when in creative mode. Spells of identification will be unobtainable in survival mode if this is false. -config.wizardry.enable_shift_scrolling.tooltip=Whether you can switch between spells on a wand by scrolling with the mouse wheel while sneaking. Note that this will only affect you; other players connected to the same server obey their own settings. -config.wizardry.minion_revenge_targeting.tooltip=Whether summoned creatures can revenge attack their owner if their owner attacks them. -config.wizardry.player_damage_scaling.tooltip=Global damage scaling factor for the damage dealt by players casting spells, relative to 1. -config.wizardry.npc_damage_scaling.tooltip=Global damage scaling factor for the damage dealt by NPCs casting spells, relative to 1. -config.wizardry.cast_command_multiplier_limit.tooltip=Upper limit for the multipliers passed into the /cast command. This is here to stop players from accidentally breaking a world/server. Large blast mutipliers can cause extreme lag - you have been warned! -config.wizardry.summoned_creature_targets_whitelist.tooltip=List of names of entities which summoned creatures and wizards are allowed to attack, in addition to the defaults. Add mod creatures to this list if you want summoned creatures to attack them and they aren't already doing so. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry.wizard). -config.wizardry.summoned_creature_targets_blacklist.tooltip=List of names of entities which summoned creatures and wizards are specifically not allowed to attack, overriding the defaults and the whitelist. Add creatures to this list if allowing them to be attacked causes problems or is too destructive (removing creepers from this list is done at your own risk!). Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry.wizard). -config.wizardry.spell_hud_position.tooltip=The position of the spell HUD. -config.wizardry.cast_command_name.tooltip=The name of the /cast command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /cast you would type /magic instead. -config.wizardry.discoverspell_command_name.tooltip=The name of the /discoverspell command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /discoverspell you would type /magic instead. -config.wizardry.ally_command_name.tooltip=The name of the /ally command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /ally you would type /magic instead. -config.wizardry.allies_command_name.tooltip=The name of the /allies command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /allies you would type /magic instead. +config.frost_potion_id=Frost Potion ID +config.transience_potion_id=Transience Potion ID +config.fireskin_potion_id=Fireskin Potion ID +config.ice_shroud_potion_id=Ice Shroud Potion ID +config.static_aura_potion_id=Static Aura Potion ID +config.decay_potion_id=Decay Potion ID +config.sixth_sense_potion_id=Sixth Sense Potion ID +config.arcane_jammer_potion_id=Arcane Jammer Potion ID +config.mind_trick_potion_id=Mind Trick Potion ID +config.mind_control_potion_id=Mind Control Potion ID +config.font_of_mana_potion_id=Font of Mana Potion ID +config.fear_potion_id=Fear Potion ID +config.magic_sword_enchantment_id=Magic Sword Enchantment ID +config.magic_bow_enchantment_id=Magic Bow Enchantment ID +config.flaming_weapon_enchantment_id=Flaming Weapon Enchantment ID +config.freezing_weapon_enchantment_id=Freezing Weapon Enchantment ID -config.wizardry.mobs_immune_to_fire.tooltip=List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry.wizard). -config.wizardry.mobs_immune_to_ice.tooltip=List of names of entities that are immune to ice, in addition to the defaults. Add mod creatures to this list if you want them to be immune to ice magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry.wizard). -config.wizardry.mobs_immune_to_lightning.tooltip=List of names of entities that are immune to lightning, in addition to the defaults. Add mod creatures to this list if you want them to be immune to lightning magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry.wizard). -config.wizardry.mobs_immune_to_wither.tooltip=List of names of entities that are immune to wither effects, in addition to the defaults. Add mod creatures to this list if you want them to be immune to withering magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry.wizard). -config.wizardry.mobs_immune_to_poison.tooltip=List of names of entities that are immune to poison, in addition to the defaults. Add mod creatures to this list if you want them to be immune to poison magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry.wizard). +config.tower_rarity.tooltip=Rarity of wizard towers. Higher numbers are rarer. Set to 0 to disable wizard towers completely. +config.ore_dimensions.tooltip=List of dimension ids in which crystal ore will generate. Note that removing the overworld (id 0) from this list will make the mod VERY difficult to play! +config.flower_dimensions.tooltip=List of dimension ids in which crystal flowers will generate. +config.tower_dimensions.tooltip=List of dimension ids in which wizard towers will generate. +config.spell_book_drop_chance.tooltip=The chance for mobs to drop a spell book when killed. The greater this number, the more often they will drop. Set to 0 to disable spell book drops. Set to 200 for guaranteed drops. +config.generate_loot.tooltip=Whether to generate wizardry loot in dungeon chests. +config.firebomb_is_craftable.tooltip=Whether firebombs can be crafted or not. +config.poison_bomb_is_craftable.tooltip=Whether poison bombs can be crafted or not. +config.smoke_bomb_is_craftable.tooltip=Whether smoke bombs can be crafted or not. +config.use_alternate_scroll_recipe.tooltip=Whether to require a magic crystal in the shapeless crafting recipe for blank scrolls. Set to true if another mod adds a conflicting recipe. +config.teleport_through_unbreakable_blocks.tooltip=Whether players are allowed to teleport through unbreakable blocks (e.g. bedrock) using the phase step spell. +config.show_summoned_creature_names.tooltip=Whether to show summoned creatures' names and owners above their heads. +config.friendly_fire.tooltip=Whether to allow players to damage their designated allies using magic. +config.telekinetic_disarmament.tooltip=Whether to allow players to disarm other players using the telekinesis spell. Set to false to prevent stealing of items. +config.discovery_mode.tooltip=For those who like a sense of mystery! When set to true, spells you haven't cast yet will be unreadable until you cast them (on a per-world basis). Has no effect when in creative mode. Spells of identification will be unobtainable in survival mode if this is false. +config.enable_shift_scrolling.tooltip=Whether you can switch between spells on a wand by scrolling with the mouse wheel while sneaking. Note that this will only affect you; other players connected to the same server obey their own settings. +config.minion_revenge_targeting.tooltip=Whether summoned creatures can revenge attack their owner if their owner attacks them. +config.player_damage_scaling.tooltip=Global damage scaling factor for the damage dealt by players casting spells, relative to 1. +config.npc_damage_scaling.tooltip=Global damage scaling factor for the damage dealt by NPCs casting spells, relative to 1. +config.cast_command_multiplier_limit.tooltip=Upper limit for the multipliers passed into the /cast command. This is here to stop players from accidentally breaking a world/server. Large blast mutipliers can cause extreme lag - you have been warned! +config.summoned_creature_targets_whitelist.tooltip=List of names of entities which summoned creatures and wizards are allowed to attack, in addition to the defaults. Add mod creatures to this list if you want summoned creatures to attack them and they aren't already doing so. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard). +config.summoned_creature_targets_blacklist.tooltip=List of names of entities which summoned creatures and wizards are specifically not allowed to attack, overriding the defaults and the whitelist. Add creatures to this list if allowing them to be attacked causes problems or is too destructive (removing creepers from this list is done at your own risk!). Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard). +config.spell_hud_position.tooltip=The position of the spell HUD. +config.cast_command_name.tooltip=The name of the /cast command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /cast you would type /magic instead. +config.discoverspell_command_name.tooltip=The name of the /discoverspell command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /discoverspell you would type /magic instead. +config.ally_command_name.tooltip=The name of the /ally command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /ally you would type /magic instead. +config.allies_command_name.tooltip=The name of the /allies command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /allies you would type /magic instead. + +config.mobs_immune_to_fire.tooltip=List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard). +config.mobs_immune_to_ice.tooltip=List of names of entities that are immune to ice, in addition to the defaults. Add mod creatures to this list if you want them to be immune to ice magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard). +config.mobs_immune_to_lightning.tooltip=List of names of entities that are immune to lightning, in addition to the defaults. Add mod creatures to this list if you want them to be immune to lightning magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard). +config.mobs_immune_to_wither.tooltip=List of names of entities that are immune to wither effects, in addition to the defaults. Add mod creatures to this list if you want them to be immune to withering magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard). +config.mobs_immune_to_poison.tooltip=List of names of entities that are immune to poison, in addition to the defaults. Add mod creatures to this list if you want them to be immune to poison magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard). + +config.frost_potion_id.tooltip=The ID of the frost potion effect. Change if this conflicts with another mod. +config.transience_potion_id.tooltip=The ID of the transience potion effect. Change if this conflicts with another mod. +config.fireskin_potion_id.tooltip=The ID of the fireskin potion effect. Change if this conflicts with another mod. +config.ice_shroud_potion_id.tooltip=The ID of the ice shroud potion effect. Change if this conflicts with another mod. +config.static_aura_potion_id.tooltip=The ID of the static aura potion effect. Change if this conflicts with another mod. +config.decay_potion_id.tooltip=The ID of the decay potion effect. Change if this conflicts with another mod. +config.sixth_sense_potion_id.tooltip=The ID of the sixth sense potion effect. Change if this conflicts with another mod. +config.arcane_jammer_potion_id.tooltip=The ID of the arcane jammer potion effect. Change if this conflicts with another mod. +config.mind_trick_potion_id.tooltip=The ID of the mind trick potion effect. Change if this conflicts with another mod. +config.mind_control_potion_id.tooltip=The ID of the mind control potion effect. Change if this conflicts with another mod. +config.font_of_mana_potion_id.tooltip=The ID of the font of mana potion effect. Change if this conflicts with another mod. +config.fear_potion_id.tooltip=The ID of the fear potion effect. Change if this conflicts with another mod. +config.magic_sword_enchantment_id.tooltip=The ID of the magic sword enchantment. Change if this conflicts with another mod. +config.magic_bow_enchantment_id.tooltip=The ID of the magic bow enchantment. Change if this conflicts with another mod. +config.flaming_weapon_enchantment_id.tooltip=The ID of the flaming weapon enchantment. Change if this conflicts with another mod. +config.freezing_weapon_enchantment_id.tooltip=The ID of the freezing weapon enchantment. Change if this conflicts with another mod. wizard.debug=%1$s, %2$s, %3$s \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/lang/en_US.lang b/src/main/resources/assets/wizardry/lang/en_US.lang index 286ae49a..cff0d0cd 100644 --- a/src/main/resources/assets/wizardry/lang/en_US.lang +++ b/src/main/resources/assets/wizardry/lang/en_US.lang @@ -1,273 +1,272 @@ -tile.wizardry:arcane_workbench.name=Arcane Workbench -tile.wizardry:crystal_ore.name=Crystal Ore -tile.wizardry:petrified_stone.name=Petrified Stone -tile.wizardry:ice_statue.name=Ice Statue -tile.wizardry:crystal_flower.name=Crystal Flower -tile.wizardry:snare.name=Snare -tile.wizardry:transportation_stone.name=Stone of Transportation -tile.wizardry:spectral_block.name=Spectral Block -tile.wizardry:crystal_block.name=Block of Crystal +tile.arcaneWorkbench.name=Arcane Workbench +tile.crystalOre.name=Crystal Ore +tile.petrifiedStone.name=Petrified Stone +tile.iceStatue.name=Ice Statue +tile.crystalFlower.name=Crystal Flower +tile.snare.name=Snare +tile.transportationStone.name=Stone of Transportation +tile.spectralBlock.name=Spectral Block +tile.crystalBlock.name=Block of Crystal -item.wizardry:magic_crystal.name=Magic Crystal -item.wizardry:magic_wand.name=Magic Wand -item.wizardry:apprentice_wand.name=Apprentice Wand -item.wizardry:advanced_wand.name=Advanced Wand -item.wizardry:master_wand.name=Master Wand -item.wizardry:spell_book.name=Spell Book +item.magicCrystal.name=Magic Crystal +item.magicWand.name=Magic Wand +item.apprenticeWand.name=Apprentice Wand +item.advancedWand.name=Advanced Wand +item.masterWand.name=Master Wand +item.spellBook.name=Spell Book -item.wizardry:arcane_tome.name=Tome of Arcana -item.wizardry:arcane_tome.desc1=Upgrades any %1$s -item.wizardry:arcane_tome.desc2=wand to %1$s tier +item.arcaneTome.name=Tome of Arcana +item.arcaneTome.desc1=Upgrades any %1$s +item.arcaneTome.desc2=wand to %1$s tier -item.wizardry:wizard_handbook.name=The Wizard's Handbook -item.wizardry:wizard_handbook.desc=by %1$s +item.wizardHandbook.name=The Wizard's Handbook +item.wizardHandbook.desc=by %1$s -item.wizardry:wand.buff=+%1$s %2$s potency -item.wizardry:wand.spell=Current Spell: %1$s -item.wizardry:wand.mana=Mana: %1$s/%2$s +item.wand.buff=+%1$s %2$s potency +item.wand.spell=Current Spell: %1$s +item.wand.mana=Mana: %1$s/%2$s -item.wizardry:wand.addally=%1$s has been added to your list of allies -item.wizardry:wand.removeally=%1$s has been removed from your list of allies +item.wand.addally=%1$s has been added to your list of allies +item.wand.removeally=%1$s has been removed from your list of allies -item.wizardry:basic_fire_wand.name=Wand of Embers -item.wizardry:basic_ice_wand.name=Wand of Frost -item.wizardry:basic_lightning_wand.name=Wand of Sparks -item.wizardry:basic_necromancy_wand.name=Wand of Shadows -item.wizardry:basic_earth_wand.name=Wand of the Forest -item.wizardry:basic_sorcery_wand.name=Wand of Mystery -item.wizardry:basic_healing_wand.name=Wand of Healing +item.basicFireWand.name=Wand of Embers +item.basicIceWand.name=Wand of Frost +item.basicLightningWand.name=Wand of Sparks +item.basicNecromancyWand.name=Wand of Shadows +item.basicEarthWand.name=Wand of the Forest +item.basicSorceryWand.name=Wand of Mystery +item.basicHealingWand.name=Wand of Healing -item.wizardry:apprentice_fire_wand.name=Apprentice Pyromancer Wand -item.wizardry:apprentice_ice_wand.name=Apprentice Ice Mage Wand -item.wizardry:apprentice_lightning_wand.name=Apprentice Storm Mage Wand -item.wizardry:apprentice_necromancy_wand.name=Apprentice Necromancer Wand -item.wizardry:apprentice_earth_wand.name=Apprentice Earth Mage Wand -item.wizardry:apprentice_sorcery_wand.name=Apprentice Sorcerer Wand -item.wizardry:apprentice_healing_wand.name=Apprentice Healer Wand +item.apprenticeFireWand.name=Apprentice Pyromancer Wand +item.apprenticeIceWand.name=Apprentice Ice Mage Wand +item.apprenticeLightningWand.name=Apprentice Storm Mage Wand +item.apprenticeNecromancyWand.name=Apprentice Necromancer Wand +item.apprenticeEarthWand.name=Apprentice Earth Mage Wand +item.apprenticeSorceryWand.name=Apprentice Sorcerer Wand +item.apprenticeHealingWand.name=Apprentice Healer Wand -item.wizardry:advanced_fire_wand.name=Wand of the Pyromancer -item.wizardry:advanced_ice_wand.name=Wand of the Ice Mage -item.wizardry:advanced_lightning_wand.name=Wand of the Storm Mage -item.wizardry:advanced_necromancy_wand.name=Wand of the Necromancer -item.wizardry:advanced_earth_wand.name=Wand of the Earth Mage -item.wizardry:advanced_sorcery_wand.name=Wand of the Sorcerer -item.wizardry:advanced_healing_wand.name=Wand of the Healer +item.advancedFireWand.name=Wand of the Pyromancer +item.advancedIceWand.name=Wand of the Ice Mage +item.advancedLightningWand.name=Wand of the Storm Mage +item.advancedNecromancyWand.name=Wand of the Necromancer +item.advancedEarthWand.name=Wand of the Earth Mage +item.advancedSorceryWand.name=Wand of the Sorcerer +item.advancedHealingWand.name=Wand of the Healer -item.wizardry:master_fire_wand.name=Master Pyromancer Wand -item.wizardry:master_ice_wand.name=Master Ice Mage Wand -item.wizardry:master_lightning_wand.name=Master Storm Mage Wand -item.wizardry:master_necromancy_wand.name=Master Necromancer Wand -item.wizardry:master_earth_wand.name=Master Earth Mage Wand -item.wizardry:master_sorcery_wand.name=Master Sorcerer Wand -item.wizardry:master_healing_wand.name=Master Healer Wand +item.masterFireWand.name=Master Pyromancer Wand +item.masterIceWand.name=Master Ice Mage Wand +item.masterLightningWand.name=Master Storm Mage Wand +item.masterNecromancyWand.name=Master Necromancer Wand +item.masterEarthWand.name=Master Earth Mage Wand +item.masterSorceryWand.name=Master Sorcerer Wand +item.masterHealingWand.name=Master Healer Wand -item.wizardry:spectral_sword.name=Spectral Sword -item.wizardry:spectral_pickaxe.name=Spectral Pickaxe -item.wizardry:spectral_bow.name=Spectral Bow +item.spectralSword.name=Spectral Sword +item.spectralPickaxe.name=Spectral Pickaxe +item.spectralBow.name=Spectral Bow -item.wizardry:mana_flask.name=Mana Flask -item.wizardry:storage_upgrade.name=Wand Storage Upgrade -item.wizardry:siphon_upgrade.name=Wand Siphon Upgrade -item.wizardry:condenser_upgrade.name=Wand Condenser Upgrade -item.wizardry:range_upgrade.name=Wand Range Upgrade -item.wizardry:duration_upgrade.name=Wand Duration Upgrade -item.wizardry:cooldown_upgrade.name=Wand Cooldown Upgrade -item.wizardry:blast_upgrade.name=Wand Blast Upgrade -item.wizardry:attunement_upgrade.name=Wand Attunement Upgrade +item.manaFlask.name=Mana Flask +item.storageUpgrade.name=Wand Storage Upgrade +item.siphonUpgrade.name=Wand Siphon Upgrade +item.condenserUpgrade.name=Wand Condenser Upgrade +item.rangeUpgrade.name=Wand Range Upgrade +item.durationUpgrade.name=Wand Duration Upgrade +item.cooldownUpgrade.name=Wand Cooldown Upgrade +item.blastUpgrade.name=Wand Blast Upgrade +item.attunementUpgrade.name=Wand Attunement Upgrade -item.wizardry:flaming_axe.name=Flaming Axe -item.wizardry:frost_axe.name=Frost Axe +item.flamingAxe.name=Flaming Axe +item.frostAxe.name=Frost Axe -item.wizardry:firebomb.name=Firebomb -item.wizardry:poison_bomb.name=Poison Bomb -item.wizardry:smoke_bomb.name=Smoke Bomb +item.firebomb.name=Firebomb +item.poisonBomb.name=Poison Bomb +item.smoke_bomb.name=Smoke Bomb -item.wizardry:blank_scroll.name=Blank Scroll -item.wizardry:scroll.name=Scroll of %1$s -item.wizardry:scroll.undiscovered.name=Scroll "%1$s" -item.wizardry:identification_scroll.name=Scroll of Identification -item.wizardry:identification_scroll.desc1=%1$sIdentifies an unknown -item.wizardry:identification_scroll.desc2=%1$sspell book or scroll -item.wizardry:identification_scroll.nothing_to_identify=Nothing to identify! +item.blankScroll.name=Blank Scroll +item.scroll.name=Scroll of %1$s +item.scroll.undiscovered.name=Scroll "%1$s" +item.identification_scroll.name=Scroll of Identification +item.identification_scroll.desc1=%1$sIdentifies an unknown +item.identification_scroll.desc2=%1$sspell book or scroll +item.identification_scroll.nothing_to_identify=Nothing to identify! -item.wizardry:armour_upgrade.name=Arcane Seal of Protection -item.wizardry:armour_upgrade.desc1=%1$sUpgrades any wizard armour -item.wizardry:armour_upgrade.desc2=%1$sto make it %2$slegendary +item.armourUpgrade.name=Arcane Seal of Protection +item.armourUpgrade.desc1=%1$sUpgrades any wizard armour +item.armourUpgrade.desc2=%1$sto make it %2$slegendary -item.wizardry:magic_silk.name=Magical Silk +item.magicSilk.name=Magical Silk -item.wizardry:wizard_armour.legendary=Legendary -item.wizardry:wizard_armour.buff=-%1$s %2$s cost -item.wizardry:wizard_armour.mana=Mana: %1$s/%2$s +item.wizardArmour.legendary=Legendary +item.wizardArmour.buff=-%1$s %2$s cost +item.wizardArmour.mana=Mana: %1$s/%2$s -item.wizardry:wizard_hat.name=Wizard Hat -item.wizardry:wizard_robe.name=Wizard Robes -item.wizardry:wizard_leggings.name=Wizard Leggings -item.wizardry:wizard_boots.name=Wizard Boots +item.wizard_hat.name=Wizard Hat +item.wizard_robe.name=Wizard Robes +item.wizard_leggings.name=Wizard Leggings +item.wizard_boots.name=Wizard Boots -item.wizardry:wizard_hat_fire.name=Pyromancer Hat -item.wizardry:wizard_robe_fire.name=Pyromancer Robes -item.wizardry:wizard_leggings_fire.name=Pyromancer Leggings -item.wizardry:wizard_boots_fire.name=Pyromancer Boots +item.wizard_hat_fire.name=Pyromancer Hat +item.wizard_robe_fire.name=Pyromancer Robes +item.wizard_leggings_fire.name=Pyromancer Leggings +item.wizard_boots_fire.name=Pyromancer Boots -item.wizardry:wizard_hat_ice.name=Ice Mage Hat -item.wizardry:wizard_robe_ice.name=Ice Mage Robes -item.wizardry:wizard_leggings_ice.name=Ice Mage Leggings -item.wizardry:wizard_boots_ice.name=Ice Mage Boots +item.wizard_hat_ice.name=Ice Mage Hat +item.wizard_robe_ice.name=Ice Mage Robes +item.wizard_leggings_ice.name=Ice Mage Leggings +item.wizard_boots_ice.name=Ice Mage Boots -item.wizardry:wizard_hat_lightning.name=Storm Mage Hat -item.wizardry:wizard_robe_lightning.name=Storm Mage Robes -item.wizardry:wizard_leggings_lightning.name=Storm Mage Leggings -item.wizardry:wizard_boots_lightning.name=Storm Mage Boots +item.wizard_hat_lightning.name=Storm Mage Hat +item.wizard_robe_lightning.name=Storm Mage Robes +item.wizard_leggings_lightning.name=Storm Mage Leggings +item.wizard_boots_lightning.name=Storm Mage Boots -item.wizardry:wizard_hat_necromancy.name=Necromancer Hat -item.wizardry:wizard_robe_necromancy.name=Necromancer Robes -item.wizardry:wizard_leggings_necromancy.name=Necromancer Leggings -item.wizardry:wizard_boots_necromancy.name=Necromancer Boots +item.wizard_hat_necromancy.name=Necromancer Hat +item.wizard_robe_necromancy.name=Necromancer Robes +item.wizard_leggings_necromancy.name=Necromancer Leggings +item.wizard_boots_necromancy.name=Necromancer Boots -item.wizardry:wizard_hat_earth.name=Earth Mage Hat -item.wizardry:wizard_robe_earth.name=Earth Mage Robes -item.wizardry:wizard_leggings_earth.name=Earth Mage Leggings -item.wizardry:wizard_boots_earth.name=Earth Mage Boots +item.wizard_hat_earth.name=Earth Mage Hat +item.wizard_robe_earth.name=Earth Mage Robes +item.wizard_leggings_earth.name=Earth Mage Leggings +item.wizard_boots_earth.name=Earth Mage Boots -item.wizardry:wizard_hat_sorcery.name=Sorcerer Hat -item.wizardry:wizard_robe_sorcery.name=Sorcerer Robes -item.wizardry:wizard_leggings_sorcery.name=Sorcerer Leggings -item.wizardry:wizard_boots_sorcery.name=Sorcerer Boots +item.wizard_hat_sorcery.name=Sorcerer Hat +item.wizard_robe_sorcery.name=Sorcerer Robes +item.wizard_leggings_sorcery.name=Sorcerer Leggings +item.wizard_boots_sorcery.name=Sorcerer Boots -item.wizardry:wizard_hat_healing.name=Healer Hat -item.wizardry:wizard_robe_healing.name=Healer Robes -item.wizardry:wizard_leggings_healing.name=Healer Leggings -item.wizardry:wizard_boots_healing.name=Healer Boots +item.wizard_hat_healing.name=Healer Hat +item.wizard_robe_healing.name=Healer Robes +item.wizard_leggings_healing.name=Healer Leggings +item.wizard_boots_healing.name=Healer Boots -item.wizardry:spawn_wizard.name=Spawn Wizard -item.wizardry:spawn_evil_wizard.name=Spawn Evil Wizard +item.spawn_wizard.name=Spawn Wizard +item.spawn_evil_wizard.name=Spawn Evil Wizard -item.wizardry:spectral_helmet.name=Spectral Helmet -item.wizardry:spectral_chestplate.name=Spectral Chestplate -item.wizardry:spectral_leggings.name=Spectral Leggings -item.wizardry:spectral_boots.name=Spectral Boots +item.spectral_helmet.name=Spectral Helmet +item.spectral_chestplate.name=Spectral Chestplate +item.spectral_leggings.name=Spectral Leggings +item.spectral_boots.name=Spectral Boots entity.wizardry.summonedcreature.nameplate=%1$s's %2$s -entity.wizardry.summonedcreature.nameplate_fallback=Someone's %1$s -entity.wizardry.zombie_minion.name=Zombie -entity.wizardry.skeleton_minion.name=Skeleton -entity.wizardry.spider_minion.name=Spider -entity.wizardry.blaze_minion.name=Blaze -entity.wizardry.ice_wraith.name=Ice Wraith -entity.wizardry.lightning_wraith.name=Lightning Wraith -entity.wizardry.shadow_wraith.name=Shadow Wraith -entity.wizardry.spirit_wolf.name=Spirit Wolf -entity.wizardry.spirit_horse.name=Spirit Horse -entity.wizardry.ice_giant.name=Ice Giant -entity.wizardry.phoenix.name=Phoenix -entity.wizardry.wizard.name=Wizard -entity.wizardry.magic_slime.name=Magical Slime -entity.wizardry.silverfish_minion.name=Silverfish -entity.wizardry.storm_elemental.name=Storm Elemental -entity.wizardry.evil_wizard.name=Wizard -entity.wizardry.decoy.name=Decoy +entity.wizardry.Zombie Minion.name=Zombie +entity.wizardry.Skeleton Minion.name=Skeleton +entity.wizardry.Spider Minion.name=Spider +entity.wizardry.Blaze Minion.name=Blaze +entity.wizardry.Ice Wraith.name=Ice Wraith +entity.wizardry.Lightning Wraith.name=Lightning Wraith +entity.wizardry.Shadow Wraith.name=Shadow Wraith +entity.wizardry.Spirit Wolf.name=Spirit Wolf +entity.wizardry.Spirit Horse.name=Spirit Horse +entity.wizardry.Ice Giant.name=Ice Giant +entity.wizardry.Phoenix.name=Phoenix +entity.wizardry.Wizard.name=Wizard +entity.wizardry.Magic Slime.name=Magical Slime +entity.wizardry.Silverfish Minion.name=Silverfish +entity.wizardry.Storm Elemental.name=Storm Elemental +entity.wizardry.Evil Wizard.name=Wizard +entity.wizardry.Decoy.name=Decoy -entity.wizardry.magic_missile.name=Magic -entity.wizardry.arc.name=Magic -entity.wizardry.spark_bomb.name=Magic -entity.wizardry.ice_shard.name=Magic -entity.wizardry.firebomb.name=Magic -entity.wizardry.poison_bomb.name=Magic -entity.wizardry.force_orb.name=Magic -entity.wizardry.spark.name=Magic -entity.wizardry.darkness_orb.name=Magic -entity.wizardry.fire_sigil.name=Magic -entity.wizardry.frost_sigil.name=Magic -entity.wizardry.lightning_sigil.name=Magic -entity.wizardry.lightning_arrow.name=Magic -entity.wizardry.firebolt.name=Magic -entity.wizardry.ice_charge.name=Magic -entity.wizardry.force_arrow.name=Magic -entity.wizardry.dart.name=Magic -entity.wizardry.lightning_disc.name=Magic -entity.wizardry.thunderbolt.name=Magic -entity.wizardry.decay.name=Magic -entity.wizardry.ice_lance.name=Magic -entity.wizardry.smoke_bomb.name=Magic -entity.wizardry.ice_spike.name=Magic +entity.wizardry.Magic Missile.name=Magic +entity.wizardry.Arc.name=Magic +entity.wizardry.Spark Bomb.name=Magic +entity.wizardry.Ice Shard.name=Magic +entity.wizardry.Firebomb.name=Magic +entity.wizardry.Poison Bomb.name=Magic +entity.wizardry.Force Orb.name=Magic +entity.wizardry.Spark.name=Magic +entity.wizardry.Darkness Orb.name=Magic +entity.wizardry.Fire Sigil.name=Magic +entity.wizardry.Frost Sigil.name=Magic +entity.wizardry.Lightning Sigil.name=Magic +entity.wizardry.Lightning Arrow.name=Magic +entity.wizardry.Firebolt.name=Magic +entity.wizardry.Ice Charge.name=Magic +entity.wizardry.Force Arrow.name=Magic +entity.wizardry.Dart.name=Magic +entity.wizardry.Lightning Disc.name=Magic +entity.wizardry.Thunderbolt.name=Magic +entity.wizardry.Decay.name=Magic +entity.wizardry.Ice Lance.name=Magic +entity.wizardry.Smoke Bomb.name=Magic +entity.wizardry.Ice Spike.name=Magic -entity.wizardry.black_hole.name=Black Hole -entity.wizardry.shield.name=Shield -entity.wizardry.meteor.name=Meteor -entity.wizardry.blizzard.name=Blizzard -entity.wizardry.bubble.name=Bubble -entity.wizardry.tornado.name=Tornado -entity.wizardry.lightning_hammer.name=Lightning Hammer -entity.wizardry.arrow_rain.name=Arrow Rain -entity.wizardry.healing_aura.name=Healing Aura -entity.wizardry.forcefield.name=Forcefield -entity.wizardry.ring_of_fire.name=Ring of Fire -entity.wizardry.earthquake.name=Earthquake -entity.wizardry.falling_grass.name=Falling Grass -entity.wizardry.hailstorm.name=Hailstorm -entity.wizardry.lightning_pulse.name=Lightning Pulse +entity.wizardry.Black Hole.name=Black Hole +entity.wizardry.Shield.name=Shield +entity.wizardry.Meteor.name=Meteor +entity.wizardry.Blizzard.name=Blizzard +entity.wizardry.Bubble.name=Bubble +entity.wizardry.Tornado.name=Tornado +entity.wizardry.Lightning Hammer.name=Lightning Hammer +entity.wizardry.Arrow Rain.name=Arrow Rain +entity.wizardry.Healing Aura.name=Healing Aura +entity.wizardry.Forcefield.name=Forcefield +entity.wizardry.Ring of Fire.name=Ring of Fire +entity.wizardry.Earthquake.name=Earthquake +entity.wizardry.Falling Grass.name=Falling Grass +entity.wizardry.Hailstorm.name=Hailstorm +entity.wizardry.Lightning Pulse.name=Lightning Pulse itemGroup.wizardry=Wizardry -itemGroup.wizardryspells=Spells +itemGroup.wizardryspells=Wizardry Spells -achievement.crystal=A Curious Crystal... -achievement.crystal.desc=Mine a magic crystal -achievement.arcane_initiate=Arcane Initiate -achievement.arcane_initiate.desc=Craft a magic wand with a gold nugget, a stick and a magic crystal -achievement.apprentice=Wizard's Apprentice -achievement.apprentice.desc=Use a tome of arcana to upgrade your wand -achievement.master=Arcane Master -achievement.master.desc=Obtain a master wand -achievement.all_spells=Mage of All Trades -achievement.all_spells.desc=Cast every single spell in the game -achievement.wizard_trade=Magic Dealing -achievement.wizard_trade.desc=Purchase an item from a wizard -achievement.buy_master_spell=Knowledge is Power -achievement.buy_master_spell.wizardry:desc=Purchase a master spell from a wizard -achievement.freeze_blaze=Not So Hot Now -achievement.freeze_blaze.desc=Freeze a blaze solid -achievement.charge_creeper=It's Gonna Blow -achievement.charge_creeper.desc='Accidentally' charge a creeper -achievement.frankenstein=Frankenstein -achievement.frankenstein.desc=Turn a pig into a zombie pigman using the lightning bolt spell -achievement.special_upgrade=Arcane Tinkering -achievement.special_upgrade.desc=Apply a special upgrade to a wand -achievement.craft_flask=It's Magic, Bottled! -achievement.craft_flask.desc=Craft a mana flask -achievement.elemental=Elemental -achievement.elemental.desc=Obtain an elemental wand -achievement.armour_set=Now You're a Proper Wizard -achievement.armour_set.desc=Craft and equip a full set of wizard armor -achievement.legendary=Legendary -achievement.legendary.desc=Obtain a piece of legendary wizard armor -achievement.self_destruct=That Backfired -achievement.self_destruct.desc=Get killed by your own magic -achievement.pig_tornado=Not Again... -achievement.pig_tornado.desc=Ride a pig into a tornado -achievement.jam_wizard=Jamming Session -achievement.jam_wizard.desc=Use the arcane jammer spell on a wizard -achievement.slime_skeleton=Sticky Situation -achievement.slime_skeleton.desc=Engulf a skeleton in slime -achievement.anger_wizard=You'll Regret That -achievement.anger_wizard.desc=Make a wizard angry -achievement.defeat_evil_wizard=Righteousness -achievement.defeat_evil_wizard.desc=Defeat an evil wizard -achievement.max_out_wand=Fully Equipped -achievement.max_out_wand.desc=Apply the maximum number of upgrades to a master wand -achievement.element_master=Element Mastery -achievement.element_master.desc=Cast all the spells of any element -achievement.identify_spell=Arcane Appraisal -achievement.identify_spell.wizardry:desc=Use a scroll of identification to identify a spell book or scroll +achievement.Crystal=A Curious Crystal... +achievement.Crystal.desc=Mine a magic crystal +achievement.ArcaneInitiate=Arcane Initiate +achievement.ArcaneInitiate.desc=Craft a magic wand with a gold nugget, a stick and a magic crystal +achievement.Apprentice=Wizard's Apprentice +achievement.Apprentice.desc=Use a tome of arcana to upgrade your wand +achievement.Master=Arcane Master +achievement.Master.desc=Obtain a master wand +achievement.AllSpells=Mage of All Trades +achievement.AllSpells.desc=Cast every single spell in the game +achievement.WizardTrade=Magic Dealing +achievement.WizardTrade.desc=Purchase an item from a wizard +achievement.BuyMasterSpell=Knowledge is Power +achievement.BuyMasterSpell.desc=Purchase a master spell from a wizard +achievement.FreezeBlaze=Not So Hot Now +achievement.FreezeBlaze.desc=Freeze a blaze solid +achievement.ChargeCreeper=It's Gonna Blow +achievement.ChargeCreeper.desc='Accidentally' charge a creeper +achievement.Frankenstein=Frankenstein +achievement.Frankenstein.desc=Turn a pig into a zombie pigman using the lightning bolt spell +achievement.SpecialUpgrade=Arcane Tinkering +achievement.SpecialUpgrade.desc=Apply a special upgrade to a wand +achievement.CraftFlask=It's Magic, Bottled! +achievement.CraftFlask.desc=Craft a mana flask +achievement.Elemental=Elemental +achievement.Elemental.desc=Obtain an elemental wand +achievement.ArmourSet=Now You're a Proper Wizard +achievement.ArmourSet.desc=Craft and equip a full set of wizard armor +achievement.Legendary=Legendary +achievement.Legendary.desc=Obtain a piece of legendary wizard armor +achievement.SelfDestruct=That Backfired +achievement.SelfDestruct.desc=Get killed by your own magic +achievement.PigTornado=Not Again... +achievement.PigTornado.desc=Ride a pig into a tornado +achievement.JamWizard=Jamming Session +achievement.JamWizard.desc=Use the arcane jammer spell on a wizard +achievement.SlimeSkeleton=Sticky Situation +achievement.SlimeSkeleton.desc=Engulf a skeleton in slime +achievement.AngerWizard=You'll Regret That +achievement.AngerWizard.desc=Make a wizard angry +achievement.DefeatEvilWizard=Righteousness +achievement.DefeatEvilWizard.desc=Defeat an evil wizard +achievement.MaxOutWand=Fully Equipped +achievement.MaxOutWand.desc=Apply the maximum number of upgrades to a master wand +achievement.ElementMaster=Element Mastery +achievement.ElementMaster.desc=Cast all the spells of any element +achievement.IdentifySpell=Arcane Appraisal +achievement.IdentifySpell.desc=Use a scroll of identification to identify a spell book or scroll -tile.wizardry:transportation_stone.confirm=You will now be returned here upon casting %1$s -tile.wizardry:transportation_stone.invalid=You must make a circle with 8 stones of transportation first! +tile.transportationStone.confirm=You will now be returned here upon casting %1$s +tile.transportationStone.invalid=You must make a circle with 8 stones of transportation first! -container.wizardry:arcane_workbench=Arcane Workbench -container.wizardry:arcane_workbench.apply=Apply -container.wizardry:arcane_workbench.mana=Mana: -container.wizardry:arcane_workbench.upgrades=Applied Upgrades: +container.arcaneWorkbench=Arcane Workbench +container.arcaneWorkbench.apply=Apply +container.arcaneWorkbench.mana=Mana: +container.arcaneWorkbench.upgrades=Applied Upgrades: tier.basic=Novice tier.apprentice=Apprentice @@ -301,438 +300,471 @@ spell.disabled=%1$s has been disabled in the config spell.resist=%1$s resisted %2$s spell.discover=Discovered the spell %1$s! -spell.wizardry:agility=Agility -spell.wizardry:arc=Arc -spell.wizardry:arcane_jammer=Arcane Jammer -spell.wizardry:arrow_rain=Arrow Rain -spell.wizardry:banish=Banish -spell.wizardry:black_hole=Black Hole -spell.wizardry:blink=Blink -spell.wizardry:blizzard=Blizzard -spell.wizardry:bubble=Bubble -spell.wizardry:chain_lightning=Chain Lightning -spell.wizardry:clairvoyance=Clairvoyance -spell.wizardry:cobwebs=Cobwebs -spell.wizardry:conjure_armour=Conjure Armor -spell.wizardry:conjure_bow=Conjure Bow -spell.wizardry:conjure_pickaxe=Conjure Pickaxe -spell.wizardry:conjure_sword=Conjure Sword -spell.wizardry:cure_effects=Cure Effects -spell.wizardry:curse_of_soulbinding=Curse of Soulbinding -spell.wizardry:darkness_orb=Darkness Orb -spell.wizardry:darkvision=Darkvision -spell.wizardry:dart=Dart -spell.wizardry:decay=Decay -spell.wizardry:decoy=Decoy -spell.wizardry:detonate=Detonate -spell.wizardry:diamondflesh=Diamondflesh -spell.wizardry:earthquake=Earthquake -spell.wizardry:entrapment=Entrapment -spell.wizardry:fireball=Fireball -spell.wizardry:firebolt=Firebolt -spell.wizardry:firebomb=Firebomb -spell.wizardry:fire_resistance=Fire Resistance -spell.wizardry:fire_sigil=Fire Sigil -spell.wizardry:fireskin=Fireskin -spell.wizardry:firestorm=Firestorm -spell.wizardry:flame_ray=Flame Ray -spell.wizardry:flaming_axe=Flaming Axe -spell.wizardry:flaming_weapon=Flaming Weapon -spell.wizardry:flight=Flight -spell.wizardry:font_of_mana=Font of Mana -spell.wizardry:font_of_vitality=Font of Vitality -spell.wizardry:force_arrow=Force Arrow -spell.wizardry:forcefield=Forcefield -spell.wizardry:force_orb=Force Orb -spell.wizardry:forests_curse=Forest's Curse -spell.wizardry:freeze=Freeze -spell.wizardry:freezing_weapon=Freezing Weapon -spell.wizardry:frost_axe=Frost Axe -spell.wizardry:frost_ray=Frost Ray -spell.wizardry:frost_sigil=Frost Sigil -spell.wizardry:glide=Glide -spell.wizardry:greater_fireball=Greater Fireball -spell.wizardry:greater_heal=Greater Heal -spell.wizardry:group_heal=Group Heal -spell.wizardry:growth_aura=Growth Aura -spell.wizardry:hailstorm=Hailstorm -spell.wizardry:heal=Heal -spell.wizardry:heal_ally=Heal Ally -spell.wizardry:healing_aura=Healing Aura -spell.wizardry:homing_spark=Homing Spark -spell.wizardry:ice_age=Ice Age -spell.wizardry:ice_charge=Ice Charge -spell.wizardry:ice_lance=Ice Lance -spell.wizardry:ice_shard=Ice Shard -spell.wizardry:ice_shroud=Ice Shroud -spell.wizardry:ice_spikes=Ice Spikes -spell.wizardry:ice_statue=Ice Statue -spell.wizardry:ignite=Ignite -spell.wizardry:imbue_weapon=Imbue Weapon -spell.wizardry:intimidate=Intimidate -spell.wizardry:invigorating_presence=Invigorating Presence -spell.wizardry:invisibility=Invisibility -spell.wizardry:invoke_weather=Invoke Weather -spell.wizardry:ironflesh=Ironflesh -spell.wizardry:leap=Leap -spell.wizardry:levitation=Levitation -spell.wizardry:life_drain=Life Drain -spell.wizardry:light=Light -spell.wizardry:lightning_arrow=Lightning Arrow -spell.wizardry:lightning_bolt=Lightning Bolt -spell.wizardry:lightning_disc=Lightning Disk -spell.wizardry:lightning_hammer=Lightning Hammer -spell.wizardry:lightning_pulse=Lightning Pulse -spell.wizardry:lightning_ray=Lightning Ray -spell.wizardry:lightning_sigil=Lightning Sigil -spell.wizardry:lightning_web=Lightning Web -spell.wizardry:magic_missile=Magic Missile -spell.wizardry:metamorphosis=Metamorphosis -spell.wizardry:meteor=Meteor -spell.wizardry:mind_control=Mind Control -spell.wizardry:mind_trick=Mind Trick -spell.wizardry:none=[Empty Slot] -spell.wizardry:oakflesh=Oakflesh -spell.wizardry:petrify=Petrify -spell.wizardry:phase_step=Phase Step -spell.wizardry:plague_of_darkness=Plague of Darkness -spell.wizardry:pocket_furnace=Pocket Furnace -spell.wizardry:pocket_workbench=Pocket Workbench -spell.wizardry:poison=Poison -spell.wizardry:poison_bomb=Poison Bomb -spell.wizardry:replenish_hunger=Replenish Hunger -spell.wizardry:ring_of_fire=Ring of Fire -spell.wizardry:shadow_ward=Shadow Ward -spell.wizardry:shield=Shield -spell.wizardry:shockwave=Shockwave -spell.wizardry:silverfish_swarm=Silverfish Swarm -spell.wizardry:sixth_sense=Sixth Sense -spell.wizardry:slime=Slime -spell.wizardry:smoke_bomb=Smoke Bomb -spell.wizardry:snare=Snare -spell.wizardry:snowball=Snowball -spell.wizardry:spark_bomb=Spark Bomb -spell.wizardry:spectral_pathway=Spectral Pathway -spell.wizardry:spider_swarm=Spider Swarm -spell.wizardry:static_aura=Static Aura -spell.wizardry:summon_blaze=Summon Blaze -spell.wizardry:summon_ice_giant=Summon Ice Giant -spell.wizardry:summon_ice_wraith=Summon Ice Wraith -spell.wizardry:summon_iron_golem=Summon Iron Golem -spell.wizardry:summon_lightning_wraith=Summon Lightning Wraith -spell.wizardry:summon_phoenix=Summon Phoenix -spell.wizardry:summon_shadow_wraith=Summon Shadow Wraith -spell.wizardry:summon_skeleton=Summon Skeleton -spell.wizardry:summon_skeleton_legion=Summon Skeleton Legion -spell.wizardry:summon_snow_golem=Summon Snow Golem -spell.wizardry:summon_spirit_horse=Summon Spirit Horse -spell.wizardry:summon_spirit_wolf=Summon Spirit Wolf -spell.wizardry:summon_storm_elemental=Summon Storm Elemental -spell.wizardry:summon_wither_skeleton=Summon Wither Skeleton -spell.wizardry:summon_zombie=Summon Zombie -spell.wizardry:telekinesis=Telekinesis -spell.wizardry:thunderbolt=Thunderbolt -spell.wizardry:thunderstorm=Thunderstorm -spell.wizardry:tornado=Tornado -spell.wizardry:transience=Transience -spell.wizardry:transportation=Transportation -spell.wizardry:vanishing_box=Vanishing Box -spell.wizardry:wall_of_frost=Wall of Frost -spell.wizardry:water_breathing=Water Breathing -spell.wizardry:whirlwind=Whirlwind -spell.wizardry:wither=Wither -spell.wizardry:wither_skull=Wither Skull +spell.agility=Agility +spell.arc=Arc +spell.arcane_jammer=Arcane Jammer +spell.arrow_rain=Arrow Rain +spell.banish=Banish +spell.black_hole=Black Hole +spell.blink=Blink +spell.blizzard=Blizzard +spell.bubble=Bubble +spell.chain_lightning=Chain Lightning +spell.clairvoyance=Clairvoyance +spell.cobwebs=Cobwebs +spell.conjure_armour=Conjure Armor +spell.conjure_bow=Conjure Bow +spell.conjure_pickaxe=Conjure Pickaxe +spell.conjure_sword=Conjure Sword +spell.cure_effects=Cure Effects +spell.curse_of_soulbinding=Curse of Soulbinding +spell.darkness_orb=Darkness Orb +spell.darkvision=Darkvision +spell.dart=Dart +spell.decay=Decay +spell.decoy=Decoy +spell.detonate=Detonate +spell.diamondflesh=Diamondflesh +spell.earthquake=Earthquake +spell.entrapment=Entrapment +spell.fireball=Fireball +spell.firebolt=Firebolt +spell.firebomb=Firebomb +spell.fire_resistance=Fire Resistance +spell.fire_sigil=Fire Sigil +spell.fireskin=Fireskin +spell.firestorm=Firestorm +spell.flame_ray=Flame Ray +spell.flaming_axe=Flaming Axe +spell.flaming_weapon=Flaming Weapon +spell.flight=Flight +spell.font_of_mana=Font of Mana +spell.font_of_vitality=Font of Vitality +spell.force_arrow=Force Arrow +spell.forcefield=Forcefield +spell.force_orb=Force Orb +spell.forests_curse=Forest's Curse +spell.freeze=Freeze +spell.freezing_weapon=Freezing Weapon +spell.frost_axe=Frost Axe +spell.frost_ray=Frost Ray +spell.frost_sigil=Frost Sigil +spell.glide=Glide +spell.greater_fireball=Greater Fireball +spell.greater_heal=Greater Heal +spell.group_heal=Group Heal +spell.growth_aura=Growth Aura +spell.hailstorm=Hailstorm +spell.heal=Heal +spell.heal_ally=Heal Ally +spell.healing_aura=Healing Aura +spell.homing_spark=Homing Spark +spell.ice_age=Ice Age +spell.ice_charge=Ice Charge +spell.ice_lance=Ice Lance +spell.ice_shard=Ice Shard +spell.ice_shroud=Ice Shroud +spell.ice_spikes=Ice Spikes +spell.ice_statue=Ice Statue +spell.ignite=Ignite +spell.imbue_weapon=Imbue Weapon +spell.intimidate=Intimidate +spell.invigorating_presence=Invigorating Presence +spell.invisibility=Invisibility +spell.invoke_weather=Invoke Weather +spell.ironflesh=Ironflesh +spell.leap=Leap +spell.levitation=Levitation +spell.life_drain=Life Drain +spell.light=Light +spell.lightning_arrow=Lightning Arrow +spell.lightning_bolt=Lightning Bolt +spell.lightning_disc=Lightning Disk +spell.lightning_hammer=Lightning Hammer +spell.lightning_pulse=Lightning Pulse +spell.lightning_ray=Lightning Ray +spell.lightning_sigil=Lightning Sigil +spell.lightning_web=Lightning Web +spell.magic_missile=Magic Missile +spell.metamorphosis=Metamorphosis +spell.meteor=Meteor +spell.mind_control=Mind Control +spell.mind_trick=Mind Trick +spell.none=[Empty Slot] +spell.oakflesh=Oakflesh +spell.petrify=Petrify +spell.phase_step=Phase Step +spell.plague_of_darkness=Plague of Darkness +spell.pocket_furnace=Pocket Furnace +spell.pocket_workbench=Pocket Workbench +spell.poison=Poison +spell.poison_bomb=Poison Bomb +spell.replenish_hunger=Replenish Hunger +spell.ring_of_fire=Ring of Fire +spell.shadow_ward=Shadow Ward +spell.shield=Shield +spell.shockwave=Shockwave +spell.silverfish_swarm=Silverfish Swarm +spell.sixth_sense=Sixth Sense +spell.slime=Slime +spell.smoke_bomb=Smoke Bomb +spell.snare=Snare +spell.snowball=Snowball +spell.spark_bomb=Spark Bomb +spell.spectral_pathway=Spectral Pathway +spell.spider_swarm=Spider Swarm +spell.static_aura=Static Aura +spell.summon_blaze=Summon Blaze +spell.summon_ice_giant=Summon Ice Giant +spell.summon_ice_wraith=Summon Ice Wraith +spell.summon_iron_golem=Summon Iron Golem +spell.summon_lightning_wraith=Summon Lightning Wraith +spell.summon_phoenix=Summon Phoenix +spell.summon_shadow_wraith=Summon Shadow Wraith +spell.summon_skeleton=Summon Skeleton +spell.summon_skeleton_legion=Summon Skeleton Legion +spell.summon_snow_golem=Summon Snow Golem +spell.summon_spirit_horse=Summon Spirit Horse +spell.summon_spirit_wolf=Summon Spirit Wolf +spell.summon_storm_elemental=Summon Storm Elemental +spell.summon_wither_skeleton=Summon Wither Skeleton +spell.summon_zombie=Summon Zombie +spell.telekinesis=Telekinesis +spell.thunderbolt=Thunderbolt +spell.thunderstorm=Thunderstorm +spell.tornado=Tornado +spell.transience=Transience +spell.transportation=Transportation +spell.vanishing_box=Vanishing Box +spell.wall_of_frost=Wall of Frost +spell.water_breathing=Water Breathing +spell.whirlwind=Whirlwind +spell.wither=Wither +spell.wither_skull=Wither Skull -spell.wizardry:agility.desc=Grants the caster faster movement speed and greater jump height for 30 seconds. -spell.wizardry:arc.desc=Fires a spark of lightning at the target. -spell.wizardry:arcane_jammer.desc=Prevents the target from using magic for 15 seconds. -spell.wizardry:arrow_rain.desc="Archers, fire!" -spell.wizardry:banish.desc=Teleports the target against its will to a random location within a certain range. -spell.wizardry:black_hole.desc=Tear reality asunder. -spell.wizardry:blink.desc=Teleports the caster over a short distance to where they are pointing. -spell.wizardry:blizzard.desc=Creates a zone of swirling icy wind which slows and continually damages anything trapped inside. The caster is immune to the damage but is still slowed. -spell.wizardry:bubble.desc=Fires a jet of bubbles which causes anything it hits to float upwards helplessly. The target will fall after a certain time or if it is damaged. -spell.wizardry:chain_lightning.desc=Fires a spark of lightning at the target, which then chains to additional targets up to twice. -spell.wizardry:clairvoyance.desc=Reveals the path to a remembered location. With this spell selected, sneak-right-click on a block to set the location. Cast this spell normally to reveal the path. The path will fade after 90 seconds. -spell.wizardry:cobwebs.desc=Creates cobwebs where you are pointing, which greatly hamper the movement of any creatures caught amongst them. The cobwebs will vanish after 20 seconds or if broken. -spell.wizardry:conjure_armour.desc=Creates spectral armor around the caster which offers protection equal to that of iron armor. The armor lasts for 60 seconds. The caster must have an empty armor slot. -spell.wizardry:conjure_bow.desc=Creates a spectral bow with unlimited arrows that lasts for 30 seconds. -spell.wizardry:conjure_pickaxe.desc=Creates a spectral pickaxe of equal strength to an iron pickaxe that lasts for 30 seconds. -spell.wizardry:conjure_sword.desc=Creates a spectral sword of equal strength to an iron sword that lasts for 30 seconds. -spell.wizardry:cure_effects.desc=Removes all potion effects currently affecting the caster, good or bad. -spell.wizardry:curse_of_soulbinding.desc=Causes the target's soul to be inextricably bound to that of the caster, meaning all damage dealt to the caster is also dealt to the victim. Lasts until either the victim or the caster dies. -spell.wizardry:darkness_orb.desc=Fires a slow moving bolt of dark energy in the direction you are pointing, which withers whatever it hits. -spell.wizardry:darkvision.desc=Grants the caster night vision for 45 seconds. -spell.wizardry:dart.desc=Fires a dart in the direction you are pointing which damages and weakens its target. -spell.wizardry:decay.desc=Creates a patch of decay on the ground which infects any creature that touches it, causing lingering damage over time and spreading more decay wherever it walks. -spell.wizardry:decoy.desc=Creates an illusory clone of the caster which tricks mobs into attacking it instead. The decoy will vanish after 30 seconds. -spell.wizardry:detonate.desc=Causes an explosion where you are pointing, damaging all nearby creatures - including the caster, if they are too close. -spell.wizardry:diamondflesh.desc="Your arrows are no match for me!" -spell.wizardry:earthquake.desc=A true master of earth magic can move mountains. -spell.wizardry:entrapment.desc=Traps the target in a sphere of darkness which pulls it helplessly upwards and continually damages it. -spell.wizardry:fireball.desc=Launches a fireball in the direction you are pointing. -spell.wizardry:firebolt.desc=Shoots a jet of fire a short distance in front of you. -spell.wizardry:firebomb.desc=Lanches a firebomb in the direction you are pointing which explodes on impact, setting targets on fire. -spell.wizardry:fire_resistance.desc=Grants the caster fire resistance for 30 seconds. -spell.wizardry:fire_sigil.desc=Places a magical fire trap on the ground which damages and sets on fire the creature that triggers it. -spell.wizardry:fireskin.desc=Cloaks the caster in flames for 30 seconds, causing anything that attacks them to catch fire. -spell.wizardry:firestorm.desc="I am the dragon." -spell.wizardry:flame_ray.desc=Creates a stream of flames in the direction you are pointing which sets on fire and continually damages targets. -spell.wizardry:flaming_axe.desc=Creates a flaming axe which sets enemies on fire when hit. Lasts for 30 seconds. -spell.wizardry:flaming_weapon.desc=Temporarily imbues the first weapon on the caster's hotbar with the power of flame, causing it to set fire to its victims. The magic wears off after 45 seconds. -spell.wizardry:flight.desc=Soar like an eagle. -spell.wizardry:font_of_mana.desc="We were filled with an intense magical energy appearing to emanate from the centre of the..." - Extract from the journal of a forgotten mage; the rest of the page has been burnt away. -spell.wizardry:font_of_vitality.desc=It feels amazing. -spell.wizardry:force_arrow.desc=Shoots an arrow of force in the direction you are pointing. -spell.wizardry:forcefield.desc=Creates a forcefield around the caster which repels creatures and deflects projectiles. -spell.wizardry:force_orb.desc=Launches a sphere of force which damages and repels nearby creatures on impact. -spell.wizardry:forests_curse.desc="How dare you enter my forest!" -spell.wizardry:freeze.desc=Freezes the target for 10 seconds. Will also freeze water and create snow on the ground. -spell.wizardry:freezing_weapon.desc=Temporarily imbues the first weapon on the caster's hotbar with the power of frost, causing it to freeze its victims. The magic wears off after 45 seconds. -spell.wizardry:frost_axe.desc=Creates a frozen axe which freezes enemies when hit. Lasts for 30 seconds. -spell.wizardry:frost_ray.desc=Creates a stream of frost in the direction you are pointing which slows and continually damages targets. -spell.wizardry:frost_sigil.desc=Places a magical ice trap on the ground which damages and freezes the creature that triggers it. -spell.wizardry:glide.desc=Allows the caster to glide downwards while in the air and holding the use item button. -spell.wizardry:greater_fireball.desc=Launches a large fireball in the direction you are pointing which explodes on impact. -spell.wizardry:greater_heal.desc=Heals the caster by 4 hearts. -spell.wizardry:group_heal.desc=Heals the caster and all nearby allies and summoned creatures by 3 hearts. -spell.wizardry:growth_aura.desc=Grows all crops near the caster. Also grows tall grass and flowers on grass. -spell.wizardry:hailstorm.desc=It was during the great winter of the third age that the ice mages discovered their true power. -spell.wizardry:heal.desc=Heals the caster by 2 hearts. -spell.wizardry:heal_ally.desc=Heals the target by 2 and a half hearts. -spell.wizardry:healing_aura.desc=Creates a zone of healing energy which regenerates the health of any ally inside it. Any undead inside the healing aura will slowly take damage. -spell.wizardry:homing_spark.desc=Creates a floating spark which moves towards enemies. -spell.wizardry:ice_age.desc="You shall be frozen for an eternity!" -spell.wizardry:ice_charge.desc=Launches an ice charge which explodes on impact, freezing nearby creatures and releasing shards in all directions. -spell.wizardry:ice_lance.desc=Fires a great spear of ice in the direction you are pointing which overpenetrates targets, damaging and freezing them in the process. -spell.wizardry:ice_shard.desc=Fires a shard of ice in the direction you are pointing which damages and slows targets when hit. -spell.wizardry:ice_shroud.desc=Creates a shroud of cold around the caster for 30 seconds, causing anything that attacks them to be frozen. -spell.wizardry:ice_spikes.desc=Causes razor-sharp ice spikes to rise from the ground where you are pointing, skewering any creatures caught amongst them. -spell.wizardry:ice_statue.desc=Freezes the target solid for 20 seconds or until broken out. The target cannot move or do anything while frozen but is also impervious to all damage. -spell.wizardry:ignite.desc=Sets the target on fire for 10 seconds. Also works like a flint and steel. -spell.wizardry:imbue_weapon.desc=Temporarily imbues the first weapon on the caster's hotbar with magic, rendering it more effective. The magic wears off after 45 seconds. -spell.wizardry:intimidate.desc=Emits an intimidating growl which causes nearby creatures to run away in fear. Fear stricken creatures will recover after 30 seconds. -spell.wizardry:invigorating_presence.desc=Grants the caster and all nearby allies increased strength for 45 seconds. -spell.wizardry:invisibility.desc=Makes the caster invisible for 30 seconds. -spell.wizardry:invoke_weather.desc=Changes the weather in the world. -spell.wizardry:ironflesh.desc=Greatly improves the caster's damage resistance for 30 seconds. -spell.wizardry:leap.desc=Causes the caster to jump upwards several blocks and slightly forward. -spell.wizardry:levitation.desc=Raises the caster upwards while the use item button is held. Will also negate fall damage if used before hitting the ground. -spell.wizardry:life_drain.desc=Creates a stream of withering energy in the direction you are pointing which drains the life of the target and uses it to gradually regenerate your health. -spell.wizardry:light.desc=Creates a magical point of light which illuminates the surrounding area. Lasts for 30 seconds. -spell.wizardry:lightning_arrow.desc=Shoots an arrow of lightning in the direction you are pointing. -spell.wizardry:lightning_bolt.desc=Causes lightning to strike where you are pointing. -spell.wizardry:lightning_disc.desc=Sends a disk of lightning flying off in the direction you are pointing, which seeks targets. -spell.wizardry:lightning_hammer.desc="I smite you by the wrath of the heavens!" -spell.wizardry:lightning_pulse.desc=Charges the ground around the caster with lightning, damaging and repelling nearby creatures. -spell.wizardry:lightning_ray.desc=Creates a stream of lightning in the direction you are pointing which continually damages targets. -spell.wizardry:lightning_sigil.desc=Places a magical lightning trap on the ground which damages the creature that triggers it and chains lightning to other nearby creatures. -spell.wizardry:lightning_web.desc="Focus. Channel the storm in your mind through your wand and unleash its fury." -spell.wizardry:magic_missile.desc=Fires a bolt of magical energy in the direction you are pointing. -spell.wizardry:metamorphosis.desc=Changes the target into another form. Only works on some creatures. -spell.wizardry:meteor.desc=Some wizards just want to see the world burn... -spell.wizardry:mind_control.desc=Takes control of the target's mind for 30 seconds, causing it switch sides and fight for the caster instead. Will not work on creatures that are too strong-willed. -spell.wizardry:mind_trick.desc=Confuses and disorients the target for 15 seconds, rendering it unable to attack effectively. The effect will be dispelled if the target takes damage. -spell.wizardry:none.desc=To get a spell book with the /give command, use metadata: /give [player] wizardry:spell_book 1 [spell id] (if you found this book in a chest, some other mod has messed things up). -spell.wizardry:oakflesh.desc=Improves the caster's damage resistance for 30 seconds. -spell.wizardry:petrify.desc=Turns the target to stone until broken out, with a chance for it to break out when it is dark. The target cannot move or do anything while petrified but is also impervious to all damage. -spell.wizardry:phase_step.desc=Teleports the caster through a 1 block thick wall in front of them. Range upgrades will increase the thickness you can teleport through. -spell.wizardry:plague_of_darkness.desc=The darkness will consume them all... -spell.wizardry:pocket_furnace.desc=Smelts up to 5 smeltable items in the caster's inventory. Items on the hotbar will be smelted first. -spell.wizardry:pocket_workbench.desc=Allows the caster to craft items as if they were at a crafting table. -spell.wizardry:poison.desc=Fires poison in the direction you are pointing. -spell.wizardry:poison_bomb.desc=Lanches a poison bomb in the direction you are pointing which explodes on impact, poisoning nearby creatures. -spell.wizardry:replenish_hunger.desc=Replenishes the caster's food level by 6 hunger points. -spell.wizardry:ring_of_fire.desc=Creates a ring of fire around the caster, damaging all nearby enemies and setting them on fire. -spell.wizardry:shadow_ward.desc=Creates a wall of darkness in front of the caster which causes half of all incoming damage to be inflicted upon the attacker instead. -spell.wizardry:shield.desc=Creates a protective barrier of force that blocks projectiles and magic. Also grants the caster a weak resistance effect. -spell.wizardry:shockwave.desc=Boom. -spell.wizardry:silverfish_swarm.desc="Ahhhh! They're MULTIPLYING!" -spell.wizardry:sixth_sense.desc=Allows the caster to sense the locations of nearby creatures, even through walls, for 20 seconds. -spell.wizardry:slime.desc=Engulfs the target in slime which slows and continually damages it. The slime bursts after 10 seconds. -spell.wizardry:smoke_bomb.desc=Launches a smoke bomb in the direction you are pointing which explodes on impact, releasing smoke and blinding nearby creatures for a short time. -spell.wizardry:snare.desc=Sets a trap on the ground which damages and briefly slows the creature that triggers it. -spell.wizardry:snowball.desc=Launches a snowball in the direction you are pointing. -spell.wizardry:spark_bomb.desc=Launches a shock charge in the direction you are pointing which releases sparks at nearby enemies on impact. -spell.wizardry:spectral_pathway.desc=Creates an indestructible magical bridge in front of you which extends for 15 blocks. The bridge vanishes after 60 seconds. -spell.wizardry:spider_swarm.desc=Summons a swarm of venomous spiders to fight for you. The spiders will disappear after 30 seconds or if they are killed. -spell.wizardry:static_aura.desc=Surrounds the caster with lightning for 30 seconds, firing a spark of lightning at anything that hits them. -spell.wizardry:summon_blaze.desc=Summons a blaze to fight for you. The blaze will disappear after 30 seconds or if it is killed. -spell.wizardry:summon_ice_giant.desc="Smash them!" -spell.wizardry:summon_ice_wraith.desc=Summons an ice wraith to fight for you. The ice wraith will disappear after 30 seconds or if it is killed. -spell.wizardry:summon_iron_golem.desc=Automatic automated autonomous automaton. -spell.wizardry:summon_lightning_wraith.desc=Summons a lightning wraith to fight for you. The lightning wraith will disappear after 30 seconds or if it is killed. -spell.wizardry:summon_phoenix.desc=From the ashes... -spell.wizardry:summon_shadow_wraith.desc=Summons a shadow wraith to fight for you. -spell.wizardry:summon_skeleton.desc=Summons a skeleton to fight for you. The skeleton will disappear after 30 seconds or if it is killed. -spell.wizardry:summon_skeleton_legion.desc="Rise, undead army!" -spell.wizardry:summon_snow_golem.desc=Creates a snow golem to fight for you. Lasts until the snow golem dies. -spell.wizardry:summon_spirit_horse.desc=Summons a spirit horse for you to ride. The spirit horse will vanish a short while after it is dismounted, or you can dismiss it by shift-right-clicking on it with any wand. -spell.wizardry:summon_spirit_wolf.desc=Summons a spirit wolf companion to fight for you. The spirit wolf will only disappear if it is killed, or you can dismiss it by shift-right-clicking on it with any wand. -spell.wizardry:summon_storm_elemental.desc="Storm Elemental: An ancient manifestation of the elements, it can hardly contain the raw power churning within it." - The Wizard's Guide to Arcane Beings, Volume I_i -spell.wizardry:summon_wither_skeleton.desc=Summons a wither skeleton to fight for you. The wither skeleton will disappear after 30 seconds or if it is killed. -spell.wizardry:summon_zombie.desc=Summons a zombie to fight for you. The zombie will disappear after 30 seconds or if it is killed. -spell.wizardry:telekinesis.desc=Moves an item or other small object towards you, or right-clicks the block you are looking at. Can also be used to disarm players. -spell.wizardry:thunderbolt.desc=Shoots a bolt of thunder which knocks back targets. -spell.wizardry:thunderstorm.desc="Mwahahahahahaha!" -spell.wizardry:tornado.desc=Unleashes a tornado in the direction you are pointing which hurls anything in its path skywards. -spell.wizardry:transience.desc=Makes the caster transient for 20 seconds. The caster is immune to all damage while transient but cannot break or place blocks or cause any damage. -spell.wizardry:transportation.desc=Transports the caster to their remembered stone circle. To use this spell, make a circle of stones of transportation, then right click it with a wand. -spell.wizardry:vanishing_box.desc=Grants the caster access to their ender chest storage. -spell.wizardry:wall_of_frost.desc=Winter at your fingertips. -spell.wizardry:water_breathing.desc=Allows the caster to breathe underwater for 60 seconds. -spell.wizardry:whirlwind.desc=Causes the target to be blown upwards and away from you at speed. -spell.wizardry:wither.desc=Fires a ray of darkness which withers anything it touches. -spell.wizardry:wither_skull.desc=Launches a wither skull in the direction you are pointing. +spell.agility.desc=Grants the caster faster movement speed and greater jump height for 30 seconds. +spell.arc.desc=Fires a spark of lightning at the target. +spell.arcane_jammer.desc=Prevents the target from using magic for 15 seconds. +spell.arrow_rain.desc="Archers, fire!" +spell.banish.desc=Teleports the target against its will to a random location within a certain range. +spell.black_hole.desc=Tear reality asunder. +spell.blink.desc=Teleports the caster over a short distance to where they are pointing. +spell.blizzard.desc=Creates a zone of swirling icy wind which slows and continually damages anything trapped inside. The caster is immune to the damage but is still slowed. +spell.bubble.desc=Fires a jet of bubbles which causes anything it hits to float upwards helplessly. The target will fall after a certain time or if it is damaged. +spell.chain_lightning.desc=Fires a spark of lightning at the target, which then chains to additional targets up to twice. +spell.clairvoyance.desc=Reveals the path to a remembered location. With this spell selected, sneak-right-click on a block to set the location. Cast this spell normally to reveal the path. The path will fade after 90 seconds. +spell.cobwebs.desc=Creates cobwebs where you are pointing, which greatly hamper the movement of any creatures caught amongst them. The cobwebs will vanish after 20 seconds or if broken. +spell.conjure_armour.desc=Creates spectral armor around the caster which offers protection equal to that of iron armor. The armor lasts for 60 seconds. The caster must have an empty armor slot. +spell.conjure_bow.desc=Creates a spectral bow with unlimited arrows that lasts for 30 seconds. +spell.conjure_pickaxe.desc=Creates a spectral pickaxe of equal strength to an iron pickaxe that lasts for 30 seconds. +spell.conjure_sword.desc=Creates a spectral sword of equal strength to an iron sword that lasts for 30 seconds. +spell.cure_effects.desc=Removes all potion effects currently affecting the caster, good or bad. +spell.curse_of_soulbinding.desc=Causes the target's soul to be inextricably bound to that of the caster, meaning all damage dealt to the caster is also dealt to the victim. Lasts until either the victim or the caster dies. +spell.darkness_orb.desc=Fires a slow moving bolt of dark energy in the direction you are pointing, which withers whatever it hits. +spell.darkvision.desc=Grants the caster night vision for 45 seconds. +spell.dart.desc=Fires a dart in the direction you are pointing which damages and weakens its target. +spell.decay.desc=Creates a patch of decay on the ground which infects any creature that touches it, causing lingering damage over time and spreading more decay wherever it walks. +spell.decoy.desc=Creates an illusory clone of the caster which tricks mobs into attacking it instead. The decoy will vanish after 30 seconds. +spell.detonate.desc=Causes an explosion where you are pointing, damaging all nearby creatures - including the caster, if they are too close. +spell.diamondflesh.desc="Your arrows are no match for me!" +spell.earthquake.desc=A true master of earth magic can move mountains. +spell.entrapment.desc=Traps the target in a sphere of darkness which pulls it helplessly upwards and continually damages it. +spell.fireball.desc=Launches a fireball in the direction you are pointing. +spell.firebolt.desc=Shoots a jet of fire a short distance in front of you. +spell.firebomb.desc=Lanches a firebomb in the direction you are pointing which explodes on impact, setting targets on fire. +spell.fire_resistance.desc=Grants the caster fire resistance for 30 seconds. +spell.fire_sigil.desc=Places a magical fire trap on the ground which damages and sets on fire the creature that triggers it. +spell.fireskin.desc=Cloaks the caster in flames for 30 seconds, causing anything that attacks them to catch fire. +spell.firestorm.desc="I am the dragon." +spell.flame_ray.desc=Creates a stream of flames in the direction you are pointing which sets on fire and continually damages targets. +spell.flaming_axe.desc=Creates a flaming axe which sets enemies on fire when hit. Lasts for 30 seconds. +spell.flaming_weapon.desc=Temporarily imbues the first weapon on the caster's hotbar with the power of flame, causing it to set fire to its victims. The magic wears off after 45 seconds. +spell.flight.desc=Soar like an eagle. +spell.font_of_mana.desc="We were filled with an intense magical energy appearing to emanate from the centre of the..." - Extract from the journal of a forgotten mage; the rest of the page has been burnt away. +spell.font_of_vitality.desc=It feels amazing. +spell.force_arrow.desc=Shoots an arrow of force in the direction you are pointing. +spell.forcefield.desc=Creates a forcefield around the caster which repels creatures and deflects projectiles. +spell.force_orb.desc=Launches a sphere of force which damages and repels nearby creatures on impact. +spell.forests_curse.desc="How dare you enter my forest!" +spell.freeze.desc=Freezes the target for 10 seconds. Will also freeze water and create snow on the ground. +spell.freezing_weapon.desc=Temporarily imbues the first weapon on the caster's hotbar with the power of frost, causing it to freeze its victims. The magic wears off after 45 seconds. +spell.frost_axe.desc=Creates a frozen axe which freezes enemies when hit. Lasts for 30 seconds. +spell.frost_ray.desc=Creates a stream of frost in the direction you are pointing which slows and continually damages targets. +spell.frost_sigil.desc=Places a magical ice trap on the ground which damages and freezes the creature that triggers it. +spell.glide.desc=Allows the caster to glide downwards while in the air and holding the use item button. +spell.greater_fireball.desc=Launches a large fireball in the direction you are pointing which explodes on impact. +spell.greater_heal.desc=Heals the caster by 4 hearts. +spell.group_heal.desc=Heals the caster and all nearby allies and summoned creatures by 3 hearts. +spell.growth_aura.desc=Grows all crops near the caster. Also grows tall grass and flowers on grass. +spell.hailstorm.desc=It was during the great winter of the third age that the ice mages discovered their true power. +spell.heal.desc=Heals the caster by 2 hearts. +spell.heal_ally.desc=Heals the target by 2 and a half hearts. +spell.healing_aura.desc=Creates a zone of healing energy which regenerates the health of any ally inside it. Any undead inside the healing aura will slowly take damage. +spell.homing_spark.desc=Creates a floating spark which moves towards enemies. +spell.ice_age.desc="You shall be frozen for an eternity!" +spell.ice_charge.desc=Launches an ice charge which explodes on impact, freezing nearby creatures and releasing shards in all directions. +spell.ice_lance.desc=Fires a great spear of ice in the direction you are pointing which overpenetrates targets, damaging and freezing them in the process. +spell.ice_shard.desc=Fires a shard of ice in the direction you are pointing which damages and slows targets when hit. +spell.ice_shroud.desc=Creates a shroud of cold around the caster for 30 seconds, causing anything that attacks them to be frozen. +spell.ice_spikes.desc=Causes razor-sharp ice spikes to rise from the ground where you are pointing, skewering any creatures caught amongst them. +spell.ice_statue.desc=Freezes the target solid for 20 seconds or until broken out. The target cannot move or do anything while frozen but is also impervious to all damage. +spell.ignite.desc=Sets the target on fire for 10 seconds. Also works like a flint and steel. +spell.imbue_weapon.desc=Temporarily imbues the first weapon on the caster's hotbar with magic, rendering it more effective. The magic wears off after 45 seconds. +spell.intimidate.desc=Emits an intimidating growl which causes nearby creatures to run away in fear. Fear stricken creatures will recover after 30 seconds. +spell.invigorating_presence.desc=Grants the caster and all nearby allies increased strength for 45 seconds. +spell.invisibility.desc=Makes the caster invisible for 30 seconds. +spell.invoke_weather.desc=Changes the weather in the world. +spell.ironflesh.desc=Greatly improves the caster's damage resistance for 30 seconds. +spell.leap.desc=Causes the caster to jump upwards several blocks and slightly forward. +spell.levitation.desc=Raises the caster upwards while the use item button is held. Will also negate fall damage if used before hitting the ground. +spell.life_drain.desc=Creates a stream of withering energy in the direction you are pointing which drains the life of the target and uses it to gradually regenerate your health. +spell.light.desc=Creates a magical point of light which illuminates the surrounding area. Lasts for 30 seconds. +spell.lightning_arrow.desc=Shoots an arrow of lightning in the direction you are pointing. +spell.lightning_bolt.desc=Causes lightning to strike where you are pointing. +spell.lightning_disc.desc=Sends a disk of lightning flying off in the direction you are pointing, which seeks targets. +spell.lightning_hammer.desc="I smite you by the wrath of the heavens!" +spell.lightning_pulse.desc=Charges the ground around the caster with lightning, damaging and repelling nearby creatures. +spell.lightning_ray.desc=Creates a stream of lightning in the direction you are pointing which continually damages targets. +spell.lightning_sigil.desc=Places a magical lightning trap on the ground which damages the creature that triggers it and chains lightning to other nearby creatures. +spell.lightning_web.desc="Focus. Channel the storm in your mind through your wand and unleash its fury." +spell.magic_missile.desc=Fires a bolt of magical energy in the direction you are pointing. +spell.metamorphosis.desc=Changes the target into another form. Only works on some creatures. +spell.meteor.desc=Some wizards just want to see the world burn... +spell.mind_control.desc=Takes control of the target's mind for 30 seconds, causing it switch sides and fight for the caster instead. Will not work on creatures that are too strong-willed. +spell.mind_trick.desc=Confuses and disorients the target for 15 seconds, rendering it unable to attack effectively. The effect will be dispelled if the target takes damage. +spell.none.desc=To get a spell book with the /give command, use metadata: /give [player] wizardry:spell_book 1 [spell id] (if you found this book in a chest, some other mod has messed things up). +spell.oakflesh.desc=Improves the caster's damage resistance for 30 seconds. +spell.petrify.desc=Turns the target to stone until broken out, with a chance for it to break out when it is dark. The target cannot move or do anything while petrified but is also impervious to all damage. +spell.phase_step.desc=Teleports the caster through a 1 block thick wall in front of them. Range upgrades will increase the thickness you can teleport through. +spell.plague_of_darkness.desc=The darkness will consume them all... +spell.pocket_furnace.desc=Smelts up to 5 smeltable items in the caster's inventory. Items on the hotbar will be smelted first. +spell.pocket_workbench.desc=Allows the caster to craft items as if they were at a crafting table. +spell.poison.desc=Fires poison in the direction you are pointing. +spell.poison_bomb.desc=Lanches a poison bomb in the direction you are pointing which explodes on impact, poisoning nearby creatures. +spell.replenish_hunger.desc=Replenishes the caster's food level by 6 hunger points. +spell.ring_of_fire.desc=Creates a ring of fire around the caster, damaging all nearby enemies and setting them on fire. +spell.shadow_ward.desc=Creates a wall of darkness in front of the caster which causes half of all incoming damage to be inflicted upon the attacker instead. +spell.shield.desc=Creates a protective barrier of force that blocks projectiles and magic. Also grants the caster a weak resistance effect. +spell.shockwave.desc=Boom. +spell.silverfish_swarm.desc="Ahhhh! They're MULTIPLYING!" +spell.sixth_sense.desc=Allows the caster to sense the locations of nearby creatures, even through walls, for 20 seconds. +spell.slime.desc=Engulfs the target in slime which slows and continually damages it. The slime bursts after 10 seconds. +spell.smoke_bomb.desc=Launches a smoke bomb in the direction you are pointing which explodes on impact, releasing smoke and blinding nearby creatures for a short time. +spell.snare.desc=Sets a trap on the ground which damages and briefly slows the creature that triggers it. +spell.snowball.desc=Launches a snowball in the direction you are pointing. +spell.spark_bomb.desc=Launches a shock charge in the direction you are pointing which releases sparks at nearby enemies on impact. +spell.spectral_pathway.desc=Creates an indestructible magical bridge in front of you which extends for 15 blocks. The bridge vanishes after 60 seconds. +spell.spider_swarm.desc=Summons a swarm of venomous spiders to fight for you. The spiders will disappear after 30 seconds or if they are killed. +spell.static_aura.desc=Surrounds the caster with lightning for 30 seconds, firing a spark of lightning at anything that hits them. +spell.summon_blaze.desc=Summons a blaze to fight for you. The blaze will disappear after 30 seconds or if it is killed. +spell.summon_ice_giant.desc="Smash them!" +spell.summon_ice_wraith.desc=Summons an ice wraith to fight for you. The ice wraith will disappear after 30 seconds or if it is killed. +spell.summon_iron_golem.desc=Automatic automated autonomous automaton. +spell.summon_lightning_wraith.desc=Summons a lightning wraith to fight for you. The lightning wraith will disappear after 30 seconds or if it is killed. +spell.summon_phoenix.desc=From the ashes... +spell.summon_shadow_wraith.desc=Summons a shadow wraith to fight for you. +spell.summon_skeleton.desc=Summons a skeleton to fight for you. The skeleton will disappear after 30 seconds or if it is killed. +spell.summon_skeleton_legion.desc="Rise, undead army!" +spell.summon_snow_golem.desc=Creates a snow golem to fight for you. Lasts until the snow golem dies. +spell.summon_spirit_horse.desc=Summons a spirit horse for you to ride. The spirit horse will vanish a short while after it is dismounted, or you can dismiss it by shift-right-clicking on it with any wand. +spell.summon_spirit_wolf.desc=Summons a spirit wolf companion to fight for you. The spirit wolf will only disappear if it is killed, or you can dismiss it by shift-right-clicking on it with any wand. +spell.summon_storm_elemental.desc="Storm Elemental: An ancient manifestation of the elements, it can hardly contain the raw power churning within it." - The Wizard's Guide to Arcane Beings, Volume II +spell.summon_wither_skeleton.desc=Summons a wither skeleton to fight for you. The wither skeleton will disappear after 30 seconds or if it is killed. +spell.summon_zombie.desc=Summons a zombie to fight for you. The zombie will disappear after 30 seconds or if it is killed. +spell.telekinesis.desc=Moves an item or other small object towards you, or right-clicks the block you are looking at. Can also be used to disarm players. +spell.thunderbolt.desc=Shoots a bolt of thunder which knocks back targets. +spell.thunderstorm.desc="Mwahahahahahaha!" +spell.tornado.desc=Unleashes a tornado in the direction you are pointing which hurls anything in its path skywards. +spell.transience.desc=Makes the caster transient for 20 seconds. The caster is immune to all damage while transient but cannot break or place blocks or cause any damage. +spell.transportation.desc=Transports the caster to their remembered stone circle. To use this spell, make a circle of stones of transportation, then right click it with a wand. +spell.vanishing_box.desc=Grants the caster access to their ender chest storage. +spell.wall_of_frost.desc=Winter at your fingertips. +spell.water_breathing.desc=Allows the caster to breathe underwater for 60 seconds. +spell.whirlwind.desc=Causes the target to be blown upwards and away from you at speed. +spell.wither.desc=Fires a ray of darkness which withers anything it touches. +spell.wither_skull.desc=Launches a wither skull in the direction you are pointing. -spell.wizardry:invoke_weather.sun=The rain begins to stop... -spell.wizardry:invoke_weather.rain=The heavens open... -spell.wizardry:transportation.missing=Your remembered stone circle is missing or obstructed... -spell.wizardry:transportation.undefined=You must remember the location of a stone circle first! -spell.wizardry:transportation.wrongdimension=Your remembered stone circle is in another dimension... -spell.wizardry:clairvoyance.searching=Searching... -spell.wizardry:clairvoyance.confirm=The path revealed upon casting %1$s will now lead back to this point -spell.wizardry:clairvoyance.outofrange=Your remembered location is too far away or inaccessible... -spell.wizardry:clairvoyance.undefined=You must remember a location first! -spell.wizardry:clairvoyance.wrongdimension=Your remembered location is in another dimension... +spell.invoke_weather.sun=The rain begins to stop... +spell.invoke_weather.rain=The heavens open... +spell.transportation.missing=Your remembered stone circle is missing or obstructed... +spell.transportation.undefined=You must remember the location of a stone circle first! +spell.transportation.wrongdimension=Your remembered stone circle is in another dimension... +spell.clairvoyance.searching=Searching... +spell.clairvoyance.confirm=The path revealed upon casting %1$s will now lead back to this point +spell.clairvoyance.outofrange=Your remembered location is too far away or inaccessible... +spell.clairvoyance.undefined=You must remember a location first! +spell.clairvoyance.wrongdimension=Your remembered location is in another dimension... -potion.wizardry:frost=Frostbite -potion.wizardry:fireskin=Fireskin -potion.wizardry:ice_shroud=Ice Shroud -potion.wizardry:static_aura=Static Aura -potion.wizardry:transience=Transience -potion.wizardry:decay=Decay -potion.wizardry:sixth_sense=Sixth Sense -potion.wizardry:arcane_jammer=Arcane Jammer -potion.wizardry:mind_trick=Mind Trick -potion.wizardry:mind_control=Mind Control -potion.wizardry:font_of_mana=Font of Mana -potion.wizardry:fear=Fear +potion.frost=Frostbite +potion.fireskin=Fireskin +potion.ice_shroud=Ice Shroud +potion.static_aura=Static Aura +potion.transience=Transience +potion.decay=Decay +potion.sixth_sense=Sixth Sense +potion.arcane_jammer=Arcane Jammer +potion.mind_trick=Mind Trick +potion.mind_control=Mind Control +potion.font_of_mana=Font of Mana +potion.fear=Fear -enchantment.wizardry:magic_sword=Imbuement -enchantment.wizardry:magic_bow=Imbuement -enchantment.wizardry:flaming_weapon=Fire Imbuement -enchantment.wizardry:freezing_weapon=Frost Imbuement +enchantment.magic_sword=Imbuement +enchantment.magic_bow=Imbuement +enchantment.flaming_weapon=Fire Imbuement +enchantment.freezing_weapon=Frost Imbuement key.categories.wizardry=Wizardry -key.wizardry.next_spell=Next Spell -key.wizardry.previous_spell=Previous Spell +key.next_spell=Next Spell +key.previous_spell=Previous Spell -death.attack.wizardry_magic=%1$s was killed by %2$s using magic -death.attack.indirect_wizardry_magic=%1$s was killed by %2$s using magic +death.attack.wizardryMagic=%1$s was killed by %2$s using magic +death.attack.indirectWizardryMagic=%1$s was killed by %2$s using magic -commands.wizardry:cast.usage=/%1$s [player] [damage multiplier] [range multiplier] [duration multiplier] [blast multiplier] -commands.wizardry:cast.success=Successfully cast %1$s -commands.wizardry:cast.success_continuous=Successfully cast %1$s; repeat the command to stop -commands.wizardry:cast.success_remote=Successfully cast %1$s as %2$s -commands.wizardry:cast.success_remote_continuous=Successfully cast %1$s as %2$s; repeat the command to stop -commands.wizardry:cast.fail=Unable to cast %1$s -commands.wizardry:cast.not_found=There is no such spell with ID %1$s -commands.wizardry:cast.tag_error=Data tag parsing failed: %s +commands.cast.usage=/%1$s [player] [damage multiplier] [range multiplier] [duration multiplier] [blast multiplier] +commands.cast.success=Successfully cast %1$s +commands.cast.success_continuous=Successfully cast %1$s; repeat the command to stop +commands.cast.success_remote=Successfully cast %1$s as %2$s +commands.cast.success_remote_continuous=Successfully cast %1$s as %2$s; repeat the command to stop +commands.cast.fail=Unable to cast %1$s +commands.cast.not_found=There is no such spell with ID %1$s -commands.wizardry:ally.usage=/%1$s [player] -commands.wizardry:ally.addally=%1$s has been added to %2$s's list of allies -commands.wizardry:ally.removeally=%1$s has been removed from %2$s's list of allies -commands.wizardry:ally.self=Players cannot be an ally of themselves! -commands.wizardry:ally.permission=You do not have permission to change other players' allies +commands.ally.usage=/%1$s [player] +commands.ally.addally=%1$s has been added to %2$s's list of allies +commands.ally.removeally=%1$s has been removed from %2$s's list of allies +commands.ally.self=Players cannot be an ally of themselves! +commands.ally.permission=You do not have permission to change other players' allies -commands.wizardry:allies.usage=/%1$s [player] -commands.wizardry:allies.list=Players allied to you: %1$s -commands.wizardry:allies.list_other=Players allied to %1$s: %2$s -commands.wizardry:allies.permission=You do not have permission to view other players' allies -commands.wizardry:allies.none=None +commands.allies.usage=/%1$s [player] +commands.allies.list=Players allied to you: %1$s +commands.allies.list_other=Players allied to %1$s: %2$s +commands.allies.permission=You do not have permission to view other players' allies +commands.allies.none=None -commands.wizardry:discoverspell.usage=/%1$s [player] -commands.wizardry:discoverspell.not_found=There is no such spell with ID %1$s -commands.wizardry:discoverspell.clear=Cleared all spell discovery data for %1$s -commands.wizardry:discoverspell.all=Added all spells to %1$s's spell discovery data -commands.wizardry:discoverspell.addspell=Added %1$s to %2$s's spell discovery data -commands.wizardry:discoverspell.removespell=Removed %1$s from %2$s's spell discovery data +commands.discoverspell.usage=/%1$s [player] +commands.discoverspell.not_found=There is no such spell with ID %1$s +commands.discoverspell.clear=Cleared all spell discovery data for %1$s +commands.discoverspell.all=Added all spells to %1$s's spell discovery data +commands.discoverspell.addspell=Added %1$s to %2$s's spell discovery data +commands.discoverspell.removespell=Removed %1$s from %2$s's spell discovery data -config.wizardry.title.general=Mod Options +config.title.general=Mod Options -config.wizardry.category.spells=Configure Spells -config.wizardry.category.spells.tooltip=Select which spells are enabled -config.wizardry.title.spells=Spell Configuration -config.wizardry.subtitle.spells=Set a spell to false to disable it. +config.category.spells=Configure Spells +config.category.spells.tooltip=Select which spells are enabled +config.title.spells=Spell Configuration +config.subtitle.spells=Set a spell to false to disable it. -config.wizardry.category.resistances=Configure Resistances -config.wizardry.category.resistances.tooltip=Configure which mobs are immune to different types of magic -config.wizardry.title.resistances=Resistance Configuration -config.wizardry.subtitle.resistances=See descriptions of individual options for more details. +config.category.resistances=Configure Resistances +config.category.resistances.tooltip=Configure which mobs are immune to different types of magic +config.title.resistances=Resistance Configuration +config.subtitle.resistances=See descriptions of individual options for more details. -config.wizardry.category.ids=Configure IDs -config.wizardry.category.ids.tooltip=Change the IDs used by wizardry -config.wizardry.title.ids=ID Configuration -config.wizardry.subtitle.ids=Change these IDs if they conflict with another mod. +config.category.ids=Configure IDs +config.category.ids.tooltip=Change the IDs used by wizardry +config.title.ids=ID Configuration +config.subtitle.ids=Change these IDs if they conflict with another mod. -config.wizardry.tower_rarity=Tower Rarity -config.wizardry.ore_dimensions=Ore Dimensions -config.wizardry.flower_dimensions=Flower Dimensions -config.wizardry.tower_dimensions=Tower Dimensions -config.wizardry.spell_book_drop_chance=Spell Book Drop Chance -config.wizardry.generate_loot=Generate Loot -config.wizardry.firebomb_is_craftable=Firebomb Is Craftable -config.wizardry.poison_bomb_is_craftable=Poison Bomb Is Craftable -config.wizardry.smoke_bomb_is_craftable=Smoke Bomb Is Craftable -config.wizardry.use_alternate_scroll_recipe=Use Alternate Scroll Recipe -config.wizardry.teleport_through_unbreakable_blocks=Teleport Through Unbreakable Blocks -config.wizardry.show_summoned_creature_names=Show Summoned Creature Names -config.wizardry.friendly_fire=Friendly Fire -config.wizardry.telekinetic_disarmament=Telekinetic Disarmament -config.wizardry.discovery_mode=Discovery Mode -config.wizardry.enable_shift_scrolling=Enable Shift-_scrolling -config.wizardry.minion_revenge_targeting=Minion Revenge Targeting -config.wizardry.player_damage_scaling=Player Damage Scaling Factor -config.wizardry.npc_damage_scaling=NPC Damage Scaling Factor -config.wizardry.cast_command_multiplier_limit=Cast Command Multiplier Limit -config.wizardry.summoned_creature_targets_whitelist=Summoned Creature Target Whitelist -config.wizardry.summoned_creature_targets_blacklist=Summoned Creature Target Blacklist -config.wizardry.spell_hud_position=Spell HUD Position -config.wizardry.cast_command_name=Cast Spell Command Name -config.wizardry.discoverspell_command_name=Discover Spell Command Name -config.wizardry.ally_command_name=Set Ally Command Name -config.wizardry.allies_command_name=View Allies Command Name +config.tower_rarity=Tower Rarity +config.ore_dimensions=Ore Dimensions +config.flower_dimensions=Flower Dimensions +config.tower_dimensions=Tower Dimensions +config.spell_book_drop_chance=Spell Book Drop Chance +config.generate_loot=Generate Loot +config.firebomb_is_craftable=Firebomb Is Craftable +config.poison_bomb_is_craftable=Poison Bomb Is Craftable +config.smoke_bomb_is_craftable=Smoke Bomb Is Craftable +config.use_alternate_scroll_recipe=Use Alternate Scroll Recipe +config.teleport_through_unbreakable_blocks=Teleport Through Unbreakable Blocks +config.show_summoned_creature_names=Show Summoned Creature Names +config.friendly_fire=Friendly Fire +config.telekinetic_disarmament=Telekinetic Disarmament +config.discovery_mode=Discovery Mode +config.enable_shift_scrolling=Enable Shift-Scrolling +config.minion_revenge_targeting=Minion Revenge Targeting +config.player_damage_scaling=Player Damage Scaling Factor +config.npc_damage_scaling=NPC Damage Scaling Factor +config.cast_command_multiplier_limit=Cast Command Multiplier Limit +config.summoned_creature_targets_whitelist=Summoned Creature Target Whitelist +config.summoned_creature_targets_blacklist=Summoned Creature Target Blacklist +config.spell_hud_position=Spell HUD Position +config.cast_command_name=Cast Spell Command Name +config.discoverspell_command_name=Discover Spell Command Name +config.ally_command_name=Set Ally Command Name +config.allies_command_name=View Allies Command Name -config.wizardry.mobs_immune_to_fire=Mobs Immune To Fire -config.wizardry.mobs_immune_to_ice=Mobs Immune To Ice -config.wizardry.mobs_immune_to_lightning=Mobs Immune To Lightning -config.wizardry.mobs_immune_to_wither=Mobs Immune To Wither -config.wizardry.mobs_immune_to_poison=Mobs Immune To Poison +config.mobs_immune_to_fire=Mobs Immune To Fire +config.mobs_immune_to_ice=Mobs Immune To Ice +config.mobs_immune_to_lightning=Mobs Immune To Lightning +config.mobs_immune_to_wither=Mobs Immune To Wither +config.mobs_immune_to_poison=Mobs Immune To Poison -config.wizardry.tower_rarity.tooltip=Rarity of wizard towers. Higher numbers are rarer. Set to 0 to disable wizard towers completely. -config.wizardry.ore_dimensions.tooltip=List of dimension ids in which crystal ore will generate. Note that removing the overworld (id 0) from this list will make the mod VERY difficult to play! -config.wizardry.flower_dimensions.tooltip=List of dimension ids in which crystal flowers will generate. -config.wizardry.tower_dimensions.tooltip=List of dimension ids in which wizard towers will generate. -config.wizardry.spell_book_drop_chance.tooltip=The chance for mobs to drop a spell book when killed. The greater this number, the more often they will drop. Set to 0 to disable spell book drops. Set to 200 for guaranteed drops. -config.wizardry.generate_loot.tooltip=Whether to generate wizardry loot in dungeon chests. -config.wizardry.firebomb_is_craftable.tooltip=Whether firebombs can be crafted or not. -config.wizardry.poison_bomb_is_craftable.tooltip=Whether poison bombs can be crafted or not. -config.wizardry.smoke_bomb_is_craftable.tooltip=Whether smoke bombs can be crafted or not. -config.wizardry.use_alternate_scroll_recipe.tooltip=Whether to require a magic crystal in the shapeless crafting recipe for blank scrolls. Set to true if another mod adds a conflicting recipe. -config.wizardry.teleport_through_unbreakable_blocks.tooltip=Whether players are allowed to teleport through unbreakable blocks (e.g. bedrock) using the phase step spell. -config.wizardry.show_summoned_creature_names.tooltip=Whether to show summoned creatures' names and owners above their heads. -config.wizardry.friendly_fire.tooltip=Whether to allow players to damage their designated allies using magic. -config.wizardry.telekinetic_disarmament.tooltip=Whether to allow players to disarm other players using the telekinesis spell.wizardry: Set to false to prevent stealing of items. -config.wizardry.discovery_mode.tooltip=For those who like a sense of mystery! When set to true, spells you haven't cast yet will be unreadable until you cast them (on a per-world basis). Has no effect when in creative mode. Spells of identification will be unobtainable in survival mode if this is false. -config.wizardry.enable_shift_scrolling.tooltip=Whether you can switch between spells on a wand by scrolling with the mouse wheel while sneaking. Note that this will only affect you; other players connected to the same server obey their own settings. -config.wizardry.minion_revenge_targeting.tooltip=Whether summoned creatures can revenge attack their owner if their owner attacks them. -config.wizardry.player_damage_scaling.tooltip=Global damage scaling factor for the damage dealt by players casting spells, relative to 1. -config.wizardry.npc_damage_scaling.tooltip=Global damage scaling factor for the damage dealt by NPCs casting spells, relative to 1. -config.wizardry.cast_command_multiplier_limit.tooltip=Upper limit for the multipliers passed into the /cast command. This is here to stop players from accidentally breaking a world/server. Large blast mutipliers can cause extreme lag - you have been warned! -config.wizardry.summoned_creature_targets_whitelist.tooltip=List of names of entities which summoned creatures and wizards are allowed to attack, in addition to the defaults. Add mod creatures to this list if you want summoned creatures to attack them and they aren't already doing so. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry.wizard). -config.wizardry.summoned_creature_targets_blacklist.tooltip=List of names of entities which summoned creatures and wizards are specifically not allowed to attack, overriding the defaults and the whitelist. Add creatures to this list if allowing them to be attacked causes problems or is too destructive (removing creepers from this list is done at your own risk!). Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry.wizard). -config.wizardry.spell_hud_position.tooltip=The position of the spell HUD. -config.wizardry.cast_command_name.tooltip=The name of the /cast command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /cast you would type /magic instead. -config.wizardry.discoverspell_command_name.tooltip=The name of the /discoverspell command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /discoverspell you would type /magic instead. -config.wizardry.ally_command_name.tooltip=The name of the /ally command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /ally you would type /magic instead. -config.wizardry.allies_command_name.tooltip=The name of the /allies command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /allies you would type /magic instead. +config.frost_potion_id=Frost Potion ID +config.transience_potion_id=Transience Potion ID +config.fireskin_potion_id=Fireskin Potion ID +config.ice_shroud_potion_id=Ice Shroud Potion ID +config.static_aura_potion_id=Static Aura Potion ID +config.decay_potion_id=Decay Potion ID +config.sixth_sense_potion_id=Sixth Sense Potion ID +config.arcane_jammer_potion_id=Arcane Jammer Potion ID +config.mind_trick_potion_id=Mind Trick Potion ID +config.mind_control_potion_id=Mind Control Potion ID +config.font_of_mana_potion_id=Font of Mana Potion ID +config.fear_potion_id=Fear Potion ID +config.magic_sword_enchantment_id=Magic Sword Enchantment ID +config.magic_bow_enchantment_id=Magic Bow Enchantment ID +config.flaming_weapon_enchantment_id=Flaming Weapon Enchantment ID +config.freezing_weapon_enchantment_id=Freezing Weapon Enchantment ID -config.wizardry.mobs_immune_to_fire.tooltip=List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry.wizard). -config.wizardry.mobs_immune_to_ice.tooltip=List of names of entities that are immune to ice, in addition to the defaults. Add mod creatures to this list if you want them to be immune to ice magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry.wizard). -config.wizardry.mobs_immune_to_lightning.tooltip=List of names of entities that are immune to lightning, in addition to the defaults. Add mod creatures to this list if you want them to be immune to lightning magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry.wizard). -config.wizardry.mobs_immune_to_wither.tooltip=List of names of entities that are immune to wither effects, in addition to the defaults. Add mod creatures to this list if you want them to be immune to withering magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry.wizard). -config.wizardry.mobs_immune_to_poison.tooltip=List of names of entities that are immune to poison, in addition to the defaults. Add mod creatures to this list if you want them to be immune to poison magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry.wizard). +config.tower_rarity.tooltip=Rarity of wizard towers. Higher numbers are rarer. Set to 0 to disable wizard towers completely. +config.ore_dimensions.tooltip=List of dimension ids in which crystal ore will generate. Note that removing the overworld (id 0) from this list will make the mod VERY difficult to play! +config.flower_dimensions.tooltip=List of dimension ids in which crystal flowers will generate. +config.tower_dimensions.tooltip=List of dimension ids in which wizard towers will generate. +config.spell_book_drop_chance.tooltip=The chance for mobs to drop a spell book when killed. The greater this number, the more often they will drop. Set to 0 to disable spell book drops. Set to 200 for guaranteed drops. +config.generate_loot.tooltip=Whether to generate wizardry loot in dungeon chests. +config.firebomb_is_craftable.tooltip=Whether firebombs can be crafted or not. +config.poison_bomb_is_craftable.tooltip=Whether poison bombs can be crafted or not. +config.smoke_bomb_is_craftable.tooltip=Whether smoke bombs can be crafted or not. +config.use_alternate_scroll_recipe.tooltip=Whether to require a magic crystal in the shapeless crafting recipe for blank scrolls. Set to true if another mod adds a conflicting recipe. +config.teleport_through_unbreakable_blocks.tooltip=Whether players are allowed to teleport through unbreakable blocks (e.g. bedrock) using the phase step spell. +config.show_summoned_creature_names.tooltip=Whether to show summoned creatures' names and owners above their heads. +config.friendly_fire.tooltip=Whether to allow players to damage their designated allies using magic. +config.telekinetic_disarmament.tooltip=Whether to allow players to disarm other players using the telekinesis spell. Set to false to prevent stealing of items. +config.discovery_mode.tooltip=For those who like a sense of mystery! When set to true, spells you haven't cast yet will be unreadable until you cast them (on a per-world basis). Has no effect when in creative mode. Spells of identification will be unobtainable in survival mode if this is false. +config.enable_shift_scrolling.tooltip=Whether you can switch between spells on a wand by scrolling with the mouse wheel while sneaking. Note that this will only affect you; other players connected to the same server obey their own settings. +config.minion_revenge_targeting.tooltip=Whether summoned creatures can revenge attack their owner if their owner attacks them. +config.player_damage_scaling.tooltip=Global damage scaling factor for the damage dealt by players casting spells, relative to 1. +config.npc_damage_scaling.tooltip=Global damage scaling factor for the damage dealt by NPCs casting spells, relative to 1. +config.cast_command_multiplier_limit.tooltip=Upper limit for the multipliers passed into the /cast command. This is here to stop players from accidentally breaking a world/server. Large blast mutipliers can cause extreme lag - you have been warned! +config.summoned_creature_targets_whitelist.tooltip=List of names of entities which summoned creatures and wizards are allowed to attack, in addition to the defaults. Add mod creatures to this list if you want summoned creatures to attack them and they aren't already doing so. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard). +config.summoned_creature_targets_blacklist.tooltip=List of names of entities which summoned creatures and wizards are specifically not allowed to attack, overriding the defaults and the whitelist. Add creatures to this list if allowing them to be attacked causes problems or is too destructive (removing creepers from this list is done at your own risk!). Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard). +config.spell_hud_position.tooltip=The position of the spell HUD. +config.cast_command_name.tooltip=The name of the /cast command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /cast you would type /magic instead. +config.discoverspell_command_name.tooltip=The name of the /discoverspell command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /discoverspell you would type /magic instead. +config.ally_command_name.tooltip=The name of the /ally command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /ally you would type /magic instead. +config.allies_command_name.tooltip=The name of the /allies command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /allies you would type /magic instead. + +config.mobs_immune_to_fire.tooltip=List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard). +config.mobs_immune_to_ice.tooltip=List of names of entities that are immune to ice, in addition to the defaults. Add mod creatures to this list if you want them to be immune to ice magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard). +config.mobs_immune_to_lightning.tooltip=List of names of entities that are immune to lightning, in addition to the defaults. Add mod creatures to this list if you want them to be immune to lightning magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard). +config.mobs_immune_to_wither.tooltip=List of names of entities that are immune to wither effects, in addition to the defaults. Add mod creatures to this list if you want them to be immune to withering magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard). +config.mobs_immune_to_poison.tooltip=List of names of entities that are immune to poison, in addition to the defaults. Add mod creatures to this list if you want them to be immune to poison magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard). + +config.frost_potion_id.tooltip=The ID of the frost potion effect. Change if this conflicts with another mod. +config.transience_potion_id.tooltip=The ID of the transience potion effect. Change if this conflicts with another mod. +config.fireskin_potion_id.tooltip=The ID of the fireskin potion effect. Change if this conflicts with another mod. +config.ice_shroud_potion_id.tooltip=The ID of the ice shroud potion effect. Change if this conflicts with another mod. +config.static_aura_potion_id.tooltip=The ID of the static aura potion effect. Change if this conflicts with another mod. +config.decay_potion_id.tooltip=The ID of the decay potion effect. Change if this conflicts with another mod. +config.sixth_sense_potion_id.tooltip=The ID of the sixth sense potion effect. Change if this conflicts with another mod. +config.arcane_jammer_potion_id.tooltip=The ID of the arcane jammer potion effect. Change if this conflicts with another mod. +config.mind_trick_potion_id.tooltip=The ID of the mind trick potion effect. Change if this conflicts with another mod. +config.mind_control_potion_id.tooltip=The ID of the mind control potion effect. Change if this conflicts with another mod. +config.font_of_mana_potion_id.tooltip=The ID of the font of mana potion effect. Change if this conflicts with another mod. +config.fear_potion_id.tooltip=The ID of the fear potion effect. Change if this conflicts with another mod. +config.magic_sword_enchantment_id.tooltip=The ID of the magic sword enchantment. Change if this conflicts with another mod. +config.magic_bow_enchantment_id.tooltip=The ID of the magic bow enchantment. Change if this conflicts with another mod. +config.flaming_weapon_enchantment_id.tooltip=The ID of the flaming weapon enchantment. Change if this conflicts with another mod. +config.freezing_weapon_enchantment_id.tooltip=The ID of the freezing weapon enchantment. Change if this conflicts with another mod. wizard.debug=%1$s, %2$s, %3$s \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/lang/es_ES.lang b/src/main/resources/assets/wizardry/lang/es_ES.lang index 38ffd4fc..fefdc2b2 100644 --- a/src/main/resources/assets/wizardry/lang/es_ES.lang +++ b/src/main/resources/assets/wizardry/lang/es_ES.lang @@ -1,272 +1,272 @@ -tile.wizardry:arcane_workbench.name=Mesa de Trabajo Arcana -tile.wizardry:crystal_ore.name=Mena de Cristal Magico -tile.wizardry:petrified_stone.name=Piedra Petrificada -tile.wizardry:ice_statue.name=Estatua de Hielo -tile.wizardry:crystal_flower.name=Flor de Cristal Magico -tile.wizardry:snare.name=Trampa -tile.wizardry:transportation_stone.name=Piedra de Transportacion -tile.wizardry:spectral_block.name=Bloque Espectral -tile.wizardry:crystal_block.name=Bloque de Cristal Magico +tile.arcaneWorkbench.name=Mesa de Trabajo Arcana +tile.crystalOre.name=Mena de Cristal Magico +tile.petrifiedStone.name=Piedra Petrificada +tile.iceStatue.name=Estatua de Hielo +tile.crystalFlower.name=Flor de Cristal Magico +tile.snare.name=Trampa +tile.transportationStone.name=Piedra de Transportacion +tile.spectralBlock.name=Bloque Espectral +tile.crystalBlock.name=Bloque de Cristal Magico -item.wizardry:magic_crystal.name=Cristal Magico -item.wizardry:magic_wand.name=Varita Magica -item.wizardry:apprentice_wand.name=Varita de Aprendiz -item.wizardry:advanced_wand.name=Varita Avanzada -item.wizardry:master_wand.name=Varita de Maestro -item.wizardry:spell_book.name=Libro de Hechizo +item.magicCrystal.name=Cristal Magico +item.magicWand.name=Varita Magica +item.apprenticeWand.name=Varita de Aprendiz +item.advancedWand.name=Varita Avanzada +item.masterWand.name=Varita de Maestro +item.spellBook.name=Libro de Hechizo -item.wizardry:arcane_tome.name=Tomo de lo Arcano -item.wizardry:arcane_tome.desc1=Mejora cualquier %1$s -item.wizardry:arcane_tome.desc2=varita a nivel %1$s +item.arcaneTome.name=Tomo de lo Arcano +item.arcaneTome.desc1=Mejora cualquier %1$s +item.arcaneTome.desc2=varita a nivel %1$s -item.wizardry:wizard_handbook.name=El Manual del Hechizero -item.wizardry:wizard_handbook.desc=por %1$s +item.wizardHandbook.name=El Manual del Hechizero +item.wizardHandbook.desc=por %1$s -item.wizardry:wand.buff=+%1$s %2$s de potencia -item.wizardry:wand.spell=Hechizo actual: %1$s -item.wizardry:wand.mana=Mana: %1$s/%2$s +item.wand.buff=+%1$s %2$s de potencia +item.wand.spell=Hechizo actual: %1$s +item.wand.mana=Mana: %1$s/%2$s -item.wizardry:wand.addally=%1$s ha sido anadido a tu lista de aliados -item.wizardry:wand.removeally=%1$s ha sido removido a tu lista de aliados +item.wand.addally=%1$s ha sido anadido a tu lista de aliados +item.wand.removeally=%1$s ha sido removido a tu lista de aliados -item.wizardry:basic_fire_wand.name=Varita de Ascuas -item.wizardry:basic_ice_wand.name=Varita de Escarcha -item.wizardry:basic_lightning_wand.name=Varita de Chispas -item.wizardry:basic_necromancy_wand.name=Varita de las Sombras -item.wizardry:basic_earth_wand.name=Varita del Bosque -item.wizardry:basic_sorcery_wand.name=Varita del Misterio -item.wizardry:basic_healing_wand.name=Varita de la Curacion +item.basicFireWand.name=Varita de Ascuas +item.basicIceWand.name=Varita de Escarcha +item.basicLightningWand.name=Varita de Chispas +item.basicNecromancyWand.name=Varita de las Sombras +item.basicEarthWand.name=Varita del Bosque +item.basicSorceryWand.name=Varita del Misterio +item.basicHealingWand.name=Varita de la Curacion -item.wizardry:apprentice_fire_wand.name=Varita del Piromano Aprendiz -item.wizardry:apprentice_ice_wand.name=Varita del Mago de Hielo Aprendiz -item.wizardry:apprentice_lightning_wand.name=Varita del Mago de Tormenta Aprendiz -item.wizardry:apprentice_necromancy_wand.name=Varita del Nigromante Aprendiz -item.wizardry:apprentice_earth_wand.name=Varita del Mago de Tierra Aprendiz -item.wizardry:apprentice_sorcery_wand.name=Varita del Hechicero Aprendiz -item.wizardry:apprentice_healing_wand.name=Varita del Sanador Aprendiz +item.apprenticeFireWand.name=Varita del Piromano Aprendiz +item.apprenticeIceWand.name=Varita del Mago de Hielo Aprendiz +item.apprenticeLightningWand.name=Varita del Mago de Tormenta Aprendiz +item.apprenticeNecromancyWand.name=Varita del Nigromante Aprendiz +item.apprenticeEarthWand.name=Varita del Mago de Tierra Aprendiz +item.apprenticeSorceryWand.name=Varita del Hechicero Aprendiz +item.apprenticeHealingWand.name=Varita del Sanador Aprendiz -item.wizardry:advanced_fire_wand.name=Varita del Piromano -item.wizardry:advanced_ice_wand.name=Varita del Mago de Hielo -item.wizardry:advanced_lightning_wand.name=Varita del Mago de Tormenta -item.wizardry:advanced_necromancy_wand.name=Varita del Nigromante -item.wizardry:advanced_earth_wand.name=Varita del Mago de Tierra -item.wizardry:advanced_sorcery_wand.name=Varita del Hechicero -item.wizardry:advanced_healing_wand.name=Varita del Sanador +item.advancedFireWand.name=Varita del Piromano +item.advancedIceWand.name=Varita del Mago de Hielo +item.advancedLightningWand.name=Varita del Mago de Tormenta +item.advancedNecromancyWand.name=Varita del Nigromante +item.advancedEarthWand.name=Varita del Mago de Tierra +item.advancedSorceryWand.name=Varita del Hechicero +item.advancedHealingWand.name=Varita del Sanador -item.wizardry:master_fire_wand.name=Varita del Piromano Maestro -item.wizardry:master_ice_wand.name=Varita del Mago de Hielo Maestro -item.wizardry:master_lightning_wand.name=Varita del Mago de Tormenta Maestro -item.wizardry:master_necromancy_wand.name=Varita del Nigromante Maestro -item.wizardry:master_earth_wand.name=Varita del Mago de Tierra Maestro -item.wizardry:master_sorcery_wand.name=Varita del Hechicero Maestro -item.wizardry:master_healing_wand.name=Varita del Sanador Maestro +item.masterFireWand.name=Varita del Piromano Maestro +item.masterIceWand.name=Varita del Mago de Hielo Maestro +item.masterLightningWand.name=Varita del Mago de Tormenta Maestro +item.masterNecromancyWand.name=Varita del Nigromante Maestro +item.masterEarthWand.name=Varita del Mago de Tierra Maestro +item.masterSorceryWand.name=Varita del Hechicero Maestro +item.masterHealingWand.name=Varita del Sanador Maestro -item.wizardry:spectral_sword.name=Espada Espectral -item.wizardry:spectral_pickaxe.name=Pico Espectral -item.wizardry:spectral_bow.name=Arco Espectral +item.spectralSword.name=Espada Espectral +item.spectralPickaxe.name=Pico Espectral +item.spectralBow.name=Arco Espectral -item.wizardry:mana_flask.name=Frasco de Mana -item.wizardry:storage_upgrade.name=Mejora de Almacenamiento para Varita -item.wizardry:siphon_upgrade.name=Mejora de Sifon para Varita -item.wizardry:condenser_upgrade.name=Mejora de Condensador para Varita -item.wizardry:range_upgrade.name=Mejora de Rango para Varita -item.wizardry:duration_upgrade.name=Mejora de Duracion para Varita -item.wizardry:cooldown_upgrade.name=Mejora de Tiempo de Reactivacion para Varita -item.wizardry:blast_upgrade.name=Mejora de Explosion para Varita -item.wizardry:attunement_upgrade.name=Mejora de Sintonizacion para Varita +item.manaFlask.name=Frasco de Mana +item.storageUpgrade.name=Mejora de Almacenamiento para Varita +item.siphonUpgrade.name=Mejora de Sifon para Varita +item.condenserUpgrade.name=Mejora de Condensador para Varita +item.rangeUpgrade.name=Mejora de Rango para Varita +item.durationUpgrade.name=Mejora de Duracion para Varita +item.cooldownUpgrade.name=Mejora de Tiempo de Reactivacion para Varita +item.blastUpgrade.name=Mejora de Explosion para Varita +item.attunementUpgrade.name=Mejora de Sintonizacion para Varita -item.wizardry:flaming_axe.name=Hacha Llameante -item.wizardry:frost_axe.name=Hacha Escarchada +item.flamingAxe.name=Hacha Llameante +item.frostAxe.name=Hacha Escarchada -item.wizardry:firebomb.name=Bomba de fuego -item.wizardry:poison_bomb.name=Bomba de veneno -item.wizardry:smoke_bomb.name=Bomba de humo +item.firebomb.name=Bomba de fuego +item.poisonBomb.name=Bomba de veneno +item.smoke_bomb.name=Bomba de humo -item.wizardry:blank_scroll.name=Pergamino en blanco -item.wizardry:scroll.name=Pergamino de %1$s -item.wizardry:scroll.undiscovered.name=Pergamino "%1$s" -item.wizardry:identification_scroll.name=Pergamino de la Identificacion -item.wizardry:identification_scroll.desc1=%1$sIdentifica un libro o pergamino -item.wizardry:identification_scroll.desc2=%1$sdesconocido -item.wizardry:identification_scroll.nothing_to_identify=Nada que identificar! +item.blankScroll.name=Pergamino en blanco +item.scroll.name=Pergamino de %1$s +item.scroll.undiscovered.name=Pergamino "%1$s" +item.identification_scroll.name=Pergamino de la Identificacion +item.identification_scroll.desc1=%1$sIdentifica un libro o pergamino +item.identification_scroll.desc2=%1$sdesconocido +item.identification_scroll.nothing_to_identify=Nada que identificar! -item.wizardry:armour_upgrade.name=Sello Arcano de la Proteccion -item.wizardry:armour_upgrade.desc1=%1$sMejora cualquier armadura -item.wizardry:armour_upgrade.desc2=%1$spara volverla %2$slegendaria +item.armourUpgrade.name=Sello Arcano de la Proteccion +item.armourUpgrade.desc1=%1$sMejora cualquier armadura +item.armourUpgrade.desc2=%1$spara volverla %2$slegendaria -item.wizardry:magic_silk.name=Seda Magica +item.magicSilk.name=Seda Magica -item.wizardry:wizard_armour.legendary=Legendario -item.wizardry:wizard_armour.buff=-%1$s %2$s costo -item.wizardry:wizard_armour.mana=Mana: %1$s/%2$s +item.wizardArmour.legendary=Legendario +item.wizardArmour.buff=-%1$s %2$s costo +item.wizardArmour.mana=Mana: %1$s/%2$s -item.wizardry:wizard_hat.name=Sombrero de Mago -item.wizardry:wizard_robe.name=Tunica de Mago -item.wizardry:wizard_leggings.name=Pantalones de Mago -item.wizardry:wizard_boots.name=Botas de Mago +item.wizard_hat.name=Sombrero de Mago +item.wizard_robe.name=Tunica de Mago +item.wizard_leggings.name=Pantalones de Mago +item.wizard_boots.name=Botas de Mago -item.wizardry:wizard_hat_fire.name=Sombrero de Piromano -item.wizardry:wizard_robe_fire.name=Tunica de Piromano -item.wizardry:wizard_leggings_fire.name=Pantalones de Piromano -item.wizardry:wizard_boots_fire.name=Botas de Piromano +item.wizard_hat_fire.name=Sombrero de Piromano +item.wizard_robe_fire.name=Tunica de Piromano +item.wizard_leggings_fire.name=Pantalones de Piromano +item.wizard_boots_fire.name=Botas de Piromano -item.wizardry:wizard_hat_ice.name=Sombrero de Mago de Hielo -item.wizardry:wizard_robe_ice.name=Tunica de Mago de Hielo -item.wizardry:wizard_leggings_ice.name=Pantalones de Mago de Hielo -item.wizardry:wizard_boots_ice.name=Botas de Mago de Hielo +item.wizard_hat_ice.name=Sombrero de Mago de Hielo +item.wizard_robe_ice.name=Tunica de Mago de Hielo +item.wizard_leggings_ice.name=Pantalones de Mago de Hielo +item.wizard_boots_ice.name=Botas de Mago de Hielo -item.wizardry:wizard_hat_lightning.name=Sombrero de Mago de Tormenta -item.wizardry:wizard_robe_lightning.name=Tunica de Mago de Tormenta -item.wizardry:wizard_leggings_lightning.name=Pantalones de Mago de Tormenta -item.wizardry:wizard_boots_lightning.name=Botas de Mago de Tormenta +item.wizard_hat_lightning.name=Sombrero de Mago de Tormenta +item.wizard_robe_lightning.name=Tunica de Mago de Tormenta +item.wizard_leggings_lightning.name=Pantalones de Mago de Tormenta +item.wizard_boots_lightning.name=Botas de Mago de Tormenta -item.wizardry:wizard_hat_necromancy.name=Sombrero de Nigromante -item.wizardry:wizard_robe_necromancy.name=Tunica de Nigromante -item.wizardry:wizard_leggings_necromancy.name=Pantalones de Nigromante -item.wizardry:wizard_boots_necromancy.name=Botas de Nigromante +item.wizard_hat_necromancy.name=Sombrero de Nigromante +item.wizard_robe_necromancy.name=Tunica de Nigromante +item.wizard_leggings_necromancy.name=Pantalones de Nigromante +item.wizard_boots_necromancy.name=Botas de Nigromante -item.wizardry:wizard_hat_earth.name=Sombrero de Mago de Tierra -item.wizardry:wizard_robe_earth.name=Tunica de Mago de Tierra -item.wizardry:wizard_leggings_earth.name=Pantalones de Mago de Tierra -item.wizardry:wizard_boots_earth.name=Botas de Mago de Tierra +item.wizard_hat_earth.name=Sombrero de Mago de Tierra +item.wizard_robe_earth.name=Tunica de Mago de Tierra +item.wizard_leggings_earth.name=Pantalones de Mago de Tierra +item.wizard_boots_earth.name=Botas de Mago de Tierra -item.wizardry:wizard_hat_sorcery.name=Sombrero de Hechicero -item.wizardry:wizard_robe_sorcery.name=Tunica de Hechicero -item.wizardry:wizard_leggings_sorcery.name=Pantalones de Hechicero -item.wizardry:wizard_boots_sorcery.name=Botas de Hechicero +item.wizard_hat_sorcery.name=Sombrero de Hechicero +item.wizard_robe_sorcery.name=Tunica de Hechicero +item.wizard_leggings_sorcery.name=Pantalones de Hechicero +item.wizard_boots_sorcery.name=Botas de Hechicero -item.wizardry:wizard_hat_healing.name=Sombrero de Sanador -item.wizardry:wizard_robe_healing.name=Tunica de Sanador -item.wizardry:wizard_leggings_healing.name=Pantalones de Sanador -item.wizardry:wizard_boots_healing.name=Botas de Sanador +item.wizard_hat_healing.name=Sombrero de Sanador +item.wizard_robe_healing.name=Tunica de Sanador +item.wizard_leggings_healing.name=Pantalones de Sanador +item.wizard_boots_healing.name=Botas de Sanador -item.wizardry:spawn_wizard.name=Invocar Mago -item.wizardry:spawn_evil_wizard.name=Invocar Mago Malvado +item.spawn_wizard.name=Invocar Mago +item.spawn_evil_wizard.name=Invocar Mago Malvado -item.wizardry:spectral_helmet.name=Casco Espectral -item.wizardry:spectral_chestplate.name=Pechera Espectral -item.wizardry:spectral_leggings.name=Grebas Espectrales -item.wizardry:spectral_boots.name=Botas Espectrales +item.spectral_helmet.name=Casco Espectral +item.spectral_chestplate.name=Pechera Espectral +item.spectral_leggings.name=Grebas Espectrales +item.spectral_boots.name=Botas Espectrales entity.wizardry.summonedcreature.nameplate=%2$s de %1$s -entity.wizardry.zombie_minion.name=Zombi -entity.wizardry.skeleton_minion.name=Esqueleto -entity.wizardry.spider_minion.name=Arana -entity.wizardry.blaze_minion.name=Blaze -entity.wizardry.ice_wraith.name=Espectro de Hielo -entity.wizardry.lightning_wraith.name=Espectro de Relampago -entity.wizardry.shadow_wraith.name=Espectro de las Sombras -entity.wizardry.spirit_wolf.name=Lobo Espiritual -entity.wizardry.spirit_horse.name=Caballo Espiritual -entity.wizardry.ice_giant.name=Gigante de Hielo -entity.wizardry.phoenix.name=Fenix -entity.wizardry.wizard.name=Mago -entity.wizardry.magic_slime.name=Slime Magico -entity.wizardry.silverfish_minion.name=Lepisma -entity.wizardry.storm_elemental.name=Elemental de Tormenta -entity.wizardry.evil_wizard.name=Mago Malvado -entity.wizardry.decoy.name=Senuelo +entity.wizardry.Zombie Minion.name=Zombi +entity.wizardry.Skeleton Minion.name=Esqueleto +entity.wizardry.Spider Minion.name=Arana +entity.wizardry.Blaze Minion.name=Blaze +entity.wizardry.Ice Wraith.name=Espectro de Hielo +entity.wizardry.Lightning Wraith.name=Espectro de Relampago +entity.wizardry.Shadow Wraith.name=Espectro de las Sombras +entity.wizardry.Spirit Wolf.name=Lobo Espiritual +entity.wizardry.Spirit Horse.name=Caballo Espiritual +entity.wizardry.Ice Giant.name=Gigante de Hielo +entity.wizardry.Phoenix.name=Fenix +entity.wizardry.Wizard.name=Mago +entity.wizardry.Magic Slime.name=Slime Magico +entity.wizardry.Silverfish Minion.name=Lepisma +entity.wizardry.Storm Elemental.name=Elemental de Tormenta +entity.wizardry.Evil Wizard.name=Mago Malvado +entity.wizardry.Decoy.name=Senuelo -entity.wizardry.magic_missile.name=Magia -entity.wizardry.arc.name=Magia -entity.wizardry.spark_bomb.name=Magia -entity.wizardry.ice_shard.name=Magia -entity.wizardry.firebomb.name=Magic -entity.wizardry.poison_bomb.name=Magia -entity.wizardry.force_orb.name=Magia -entity.wizardry.spark.name=Magia -entity.wizardry.darkness_orb.name=Magia -entity.wizardry.fire_sigil.name=Magia -entity.wizardry.frost_sigil.name=Magia -entity.wizardry.lightning_sigil.name=Magia -entity.wizardry.lightning_arrow.name=Magia -entity.wizardry.firebolt.name=Magia -entity.wizardry.ice_charge.name=Magia -entity.wizardry.force_arrow.name=Magia -entity.wizardry.dart.name=Magia -entity.wizardry.lightning_disc.name=Magia -entity.wizardry.thunderbolt.name=Magia -entity.wizardry.decay.name=Magia -entity.wizardry.ice_lance.name=Magia -entity.wizardry.smoke_bomb.name=Magia -entity.wizardry.ice_spike.name=Magia +entity.wizardry.Magic Missile.name=Magia +entity.wizardry.Arc.name=Magia +entity.wizardry.Spark Bomb.name=Magia +entity.wizardry.Ice Shard.name=Magia +entity.wizardry.Firebomb.name=Magic +entity.wizardry.Poison Bomb.name=Magia +entity.wizardry.Force Orb.name=Magia +entity.wizardry.Spark.name=Magia +entity.wizardry.Darkness Orb.name=Magia +entity.wizardry.Fire Sigil.name=Magia +entity.wizardry.Frost Sigil.name=Magia +entity.wizardry.Lightning Sigil.name=Magia +entity.wizardry.Lightning Arrow.name=Magia +entity.wizardry.Firebolt.name=Magia +entity.wizardry.Ice Charge.name=Magia +entity.wizardry.Force Arrow.name=Magia +entity.wizardry.Dart.name=Magia +entity.wizardry.Lightning Disc.name=Magia +entity.wizardry.Thunderbolt.name=Magia +entity.wizardry.Decay.name=Magia +entity.wizardry.Ice Lance.name=Magia +entity.wizardry.Smoke Bomb.name=Magia +entity.wizardry.Ice Spike.name=Magia -entity.wizardry.black_hole.name=Agujero Negro -entity.wizardry.shield.name=Escudo -entity.wizardry.meteor.name=Meteoro -entity.wizardry.blizzard.name=Ventisca -entity.wizardry.bubble.name=Burbuja -entity.wizardry.tornado.name=Tornado -entity.wizardry.lightning_hammer.name=Martillo Relampago -entity.wizardry.arrow_rain.name=Lluvia de Flechas -entity.wizardry.healing_aura.name=Aura Curador -entity.wizardry.forcefield.name=Campo de Fuerza -entity.wizardry.ring_of_fire.name=Anillo de Fuego -entity.wizardry.earthquake.name=Terremoto -entity.wizardry.falling_grass.name=Hierba Descendiente -entity.wizardry.hailstorm.name=Tormenta de Granizo -entity.wizardry.lightning_pulse.name=Pulso de Relampago +entity.wizardry.Black Hole.name=Agujero Negro +entity.wizardry.Shield.name=Escudo +entity.wizardry.Meteor.name=Meteoro +entity.wizardry.Blizzard.name=Ventisca +entity.wizardry.Bubble.name=Burbuja +entity.wizardry.Tornado.name=Tornado +entity.wizardry.Lightning Hammer.name=Martillo Relampago +entity.wizardry.Arrow Rain.name=Lluvia de Flechas +entity.wizardry.Healing Aura.name=Aura Curador +entity.wizardry.Forcefield.name=Campo de Fuerza +entity.wizardry.Ring of Fire.name=Anillo de Fuego +entity.wizardry.Earthquake.name=Terremoto +entity.wizardry.Falling Grass.name=Hierba Descendiente +entity.wizardry.Hailstorm.name=Tormenta de Granizo +entity.wizardry.Lightning Pulse.name=Pulso de Relampago -item_group.wizardry=Wizardry -item_group.wizardryspells=Hechizos de Wizardry +itemGroup.wizardry=Wizardry +itemGroup.wizardryspells=Hechizos de Wizardry -achievement.crystal=Un Cristral Curioso... -achievement.crystal.desc=Pica un Cristal Magico -achievement.arcane_initiate=Inicio Arcano -achievement.arcane_initiate.desc=Craftea una varita magica con una pepita de oro, un palo y un cristal magico -achievement.apprentice=Aprendiz de Mago -achievement.apprentice.desc=Usa un tomo de lo arcano para mejorar tu varita -achievement.master=Maestro Arcano -achievement.master.desc=Obten una varita de maestro -achievement.all_spells=Mago de Todos los Oficios -achievement.all_spells.desc=Lanza todos los hechizos disponibles -achievement.wizard_trade=Comercio Magico -achievement.wizard_trade.desc=Compra un objeto a un mago -achievement.buy_master_spell=El Conocimiento es Poder -achievement.buy_master_spell.wizardry:desc=Compra un hechizo maestro a un mago -achievement.freeze_blaze=Ya No Estas Tan Caliente -achievement.freeze_blaze.desc=Congela a un blaze -achievement.charge_creeper=Va a Explotar!! -achievement.charge_creeper.desc='Accidentalmente' carga un creeper -achievement.frankenstein=Frankenstein -achievement.frankenstein.desc=Convierte a un cerdo en un hombrecerdo zombi usando el hechizo de rayo -achievement.special_upgrade=Remiendo Arcano -achievement.special_upgrade.desc=Aplica una mejora a una varita -achievement.craft_flask=Es Magia, Embotellada! -achievement.craft_flask.desc=Craftea un frasco de mana -achievement.elemental=Elemental -achievement.elemental.desc=Obten una varita elemental -achievement.armour_set=Now Eres un Mago Apropiado -achievement.armour_set.desc=Craftea y equipa el set completo de armadura de mago -achievement.legendary=Legendario -achievement.legendary.desc=Obten una pieza de armadura de mago legendaria -achievement.self_destruct=Tiro por la culata -achievement.self_destruct.desc=Muere por tu propia magia -achievement.pig_tornado=No De Nuevo... -achievement.pig_tornado.desc=Monta un cerdo hacia un tornado -achievement.jam_wizard=Sesion de Interferencia -achievement.jam_wizard.desc=Usa el hechizo arcano de interferencia en un mago -achievement.slime_skeleton=Situacion Pegajosa -achievement.slime_skeleton.desc=Sumerge un esqueleto en slime -achievement.anger_wizard=Te Arrepentiras de Eso -achievement.anger_wizard.desc=Haz que un mago se enoje -achievement.defeat_evil_wizard=Justicia -achievement.defeat_evil_wizard.desc=Derrota a un mago malvado -achievement.max_out_wand=Equipada Al Maximo! -achievement.max_out_wand.desc=Aplica el maximo numero de mejoras a una varita maestra -achievement.element_master=Maestria Elemental -achievement.element_master.desc=Lanza todos los hechizos de cualquier elemento -achievement.identify_spell=Apreciacion Arcana -achievement.identify_spell.wizardry:desc=Usa un pergamino de la identificacion para identificar un libro de hechizos o pergamino +achievement.Crystal=Un Cristral Curioso... +achievement.Crystal.desc=Pica un Cristal Magico +achievement.ArcaneInitiate=Inicio Arcano +achievement.ArcaneInitiate.desc=Craftea una varita magica con una pepita de oro, un palo y un cristal magico +achievement.Apprentice=Aprendiz de Mago +achievement.Apprentice.desc=Usa un tomo de lo arcano para mejorar tu varita +achievement.Master=Maestro Arcano +achievement.Master.desc=Obten una varita de maestro +achievement.AllSpells=Mago de Todos los Oficios +achievement.AllSpells.desc=Lanza todos los hechizos disponibles +achievement.WizardTrade=Comercio Magico +achievement.WizardTrade.desc=Compra un objeto a un mago +achievement.BuyMasterSpell=El Conocimiento es Poder +achievement.BuyMasterSpell.desc=Compra un hechizo maestro a un mago +achievement.FreezeBlaze=Ya No Estas Tan Caliente +achievement.FreezeBlaze.desc=Congela a un blaze +achievement.ChargeCreeper=Va a Explotar!! +achievement.ChargeCreeper.desc='Accidentalmente' carga un creeper +achievement.Frankenstein=Frankenstein +achievement.Frankenstein.desc=Convierte a un cerdo en un hombrecerdo zombi usando el hechizo de rayo +achievement.SpecialUpgrade=Remiendo Arcano +achievement.SpecialUpgrade.desc=Aplica una mejora a una varita +achievement.CraftFlask=Es Magia, Embotellada! +achievement.CraftFlask.desc=Craftea un frasco de mana +achievement.Elemental=Elemental +achievement.Elemental.desc=Obten una varita elemental +achievement.ArmourSet=Now Eres un Mago Apropiado +achievement.ArmourSet.desc=Craftea y equipa el set completo de armadura de mago +achievement.Legendary=Legendario +achievement.Legendary.desc=Obten una pieza de armadura de mago legendaria +achievement.SelfDestruct=Tiro por la culata +achievement.SelfDestruct.desc=Muere por tu propia magia +achievement.PigTornado=No De Nuevo... +achievement.PigTornado.desc=Monta un cerdo hacia un tornado +achievement.JamWizard=Sesion de Interferencia +achievement.JamWizard.desc=Usa el hechizo arcano de interferencia en un mago +achievement.SlimeSkeleton=Situacion Pegajosa +achievement.SlimeSkeleton.desc=Sumerge un esqueleto en slime +achievement.AngerWizard=Te Arrepentiras de Eso +achievement.AngerWizard.desc=Haz que un mago se enoje +achievement.DefeatEvilWizard=Justicia +achievement.DefeatEvilWizard.desc=Derrota a un mago malvado +achievement.MaxOutWand=Equipada Al Maximo! +achievement.MaxOutWand.desc=Aplica el maximo numero de mejoras a una varita maestra +achievement.ElementMaster=Maestria Elemental +achievement.ElementMaster.desc=Lanza todos los hechizos de cualquier elemento +achievement.IdentifySpell=Apreciacion Arcana +achievement.IdentifySpell.desc=Usa un pergamino de la identificacion para identificar un libro de hechizos o pergamino -tile.wizardry:transportation_stone.confirm=A partir de ahora retornaras a este lugar cuando lances %1$s -tile.wizardry:transportation_stone.invalid=Primero debes hacer un circulo con 8 piedras de transportacion! +tile.transportationStone.confirm=A partir de ahora retornaras a este lugar cuando lances %1$s +tile.transportationStone.invalid=Primero debes hacer un circulo con 8 piedras de transportacion! -container.wizardry:arcane_workbench=Mesa de Trabajo Arcana -container.wizardry:arcane_workbench.apply=Aplicar -container.wizardry:arcane_workbench.mana=Mana: -container.wizardry:arcane_workbench.upgrades=Mejoras Aplicadas: +container.arcaneWorkbench=Mesa de Trabajo Arcana +container.arcaneWorkbench.apply=Aplicar +container.arcaneWorkbench.mana=Mana: +container.arcaneWorkbench.upgrades=Mejoras Aplicadas: tier.basic=Novato tier.apprentice=Aprendiz @@ -300,437 +300,470 @@ spell.disabled=%1$s ha sido desactivado en la configuracion spell.resist=%1$s resistio %2$s spell.discover=Descubrio el hechizo %1$s! -spell.wizardry:agility=Agilidad -spell.wizardry:arc=Arco Electrico -spell.wizardry:arcane_jammer=Perturbador Arcano -spell.wizardry:arrow_rain=Lluvia de Flechas -spell.wizardry:banish=Desaparecer -spell.wizardry:black_hole=Agujero Negro -spell.wizardry:blink=Parpadeo -spell.wizardry:blizzard=Ventisca -spell.wizardry:bubble=Burbuja -spell.wizardry:chain_lightning=Cadena de Rayos -spell.wizardry:clairvoyance=Clarividencia -spell.wizardry:cobwebs=Telas de Araña -spell.wizardry:conjure_armour=Conjurar Armadura -spell.wizardry:conjure_bow=Conjurar Arco -spell.wizardry:conjure_pickaxe=Conjurar Pico -spell.wizardry:conjure_sword=Conjurar Espada -spell.wizardry:cure_effects=Purificar Efectos -spell.wizardry:curse_of_soulbinding=Maldicion de Atadura al Alma -spell.wizardry:darkness_orb=Orbe de la Oscuridad -spell.wizardry:darkvision=Vision Oscura -spell.wizardry:dart=Dardo -spell.wizardry:decay=Deterioro -spell.wizardry:decoy=Senuelo -spell.wizardry:detonate=Detonar -spell.wizardry:diamondflesh=Piel de Diamante -spell.wizardry:earthquake=Terremoto -spell.wizardry:entrapment=Atrapamiento -spell.wizardry:fireball=Bola de Fuego -spell.wizardry:firebolt=Disparo de Fuego -spell.wizardry:firebomb=Bomba de Fuego -spell.wizardry:fire_resistance=Resistencia al Fuego -spell.wizardry:fire_sigil=Sigilo de Fuego -spell.wizardry:fireskin=Piel de Fuego -spell.wizardry:firestorm=Tormenta de Fuego -spell.wizardry:flame_ray=Rayo de Fuego -spell.wizardry:flaming_axe=Hacha Llameante -spell.wizardry:flaming_weapon=Arma Llameante -spell.wizardry:flight=Vuelo -spell.wizardry:font_of_mana=Fuente de Mana -spell.wizardry:font_of_vitality=Fuente de Vitalidad -spell.wizardry:force_arrow=Flecha de Fuerza -spell.wizardry:forcefield=Campo de Fuerza -spell.wizardry:force_orb=Orbe de Fuerza -spell.wizardry:forests_curse=Maldicion del Bosque -spell.wizardry:freeze=Congelar -spell.wizardry:freezing_weapon=Arma Congelante -spell.wizardry:frost_axe=Hacha Escarchada -spell.wizardry:frost_ray=Rayo de Escarcha -spell.wizardry:frost_sigil=Sigilo de Escarcha -spell.wizardry:glide=Planear -spell.wizardry:greater_fireball=Bola de Fuego Mayor -spell.wizardry:greater_heal=Curacion Mayor -spell.wizardry:group_heal=Curacion Grupal -spell.wizardry:growth_aura= Aura de Crecimiento -spell.wizardry:hailstorm=Tormenta de Granizo -spell.wizardry:heal=Curar -spell.wizardry:heal_ally=curar Aliado -spell.wizardry:healing_aura=Aura de Curacion -spell.wizardry:homing_spark=Chispa Dirigida -spell.wizardry:ice_age=Era de Hielo -spell.wizardry:ice_charge=Carga de Hielo -spell.wizardry:ice_lance=Lanza de Hielo -spell.wizardry:ice_shard=Fragmento de Hielo -spell.wizardry:ice_shroud=Velo de Hielo -spell.wizardry:ice_spikes=Pinchos de Hielo -spell.wizardry:ice_statue=Estatua de Hielo -spell.wizardry:ignite=Encender -spell.wizardry:imbue_weapon=Imbuir Arma -spell.wizardry:intimidate=Intimidar -spell.wizardry:invigorating_presence=Presencia Vigorizante -spell.wizardry:invisibility=Invisibilidad -spell.wizardry:invoke_weather=Invocar clima -spell.wizardry:ironflesh=Piel de Hierro -spell.wizardry:leap=Salto -spell.wizardry:levitation=Levitacion -spell.wizardry:life_drain=Drenaje de Vida -spell.wizardry:light=Luz -spell.wizardry:lightning_arrow=Flecha de Rayo -spell.wizardry:lightning_bolt=Disparo de Rayo -spell.wizardry:lightning_disc=Disco de Rayo -spell.wizardry:lightning_hammer=Martillo Relampago -spell.wizardry:lightning_pulse=Pulso Electrico -spell.wizardry:lightning_ray=Rayo Electrico -spell.wizardry:lightning_sigil=Sigilo Electrico -spell.wizardry:lightning_web=Red Electrica -spell.wizardry:magic_missile=Misil Magico -spell.wizardry:metamorphosis=Metamorfosis -spell.wizardry:meteor=Meteoro -spell.wizardry:mind_control=Control Mental -spell.wizardry:mind_trick=Truco Mental -spell.wizardry:none=[Espacio Vacio] -spell.wizardry:oakflesh=Piel de Roble -spell.wizardry:petrify=Petrificar -spell.wizardry:phase_step=Paso de Fase -spell.wizardry:plague_of_darkness=Plaga de la Oscuridad -spell.wizardry:pocket_furnace=Horno del Bolsillo -spell.wizardry:pocket_workbench=Mesa de Trabajo de Bolsillo -spell.wizardry:poison=Veneno -spell.wizardry:poison_bomb=Bomba de Veneno -spell.wizardry:replenish_hunger=Rellenar hambre -spell.wizardry:ring_of_fire=Anillo de Fuego -spell.wizardry:shadow_ward=Guarda de las Sombras -spell.wizardry:shield=Escudo -spell.wizardry:shockwave=Onda de Choque -spell.wizardry:silverfish_swarm=Emjambre de Lepismas -spell.wizardry:sixth_sense=Sexto Sentido -spell.wizardry:slime=Slime -spell.wizardry:smoke_bomb=Bomba de Humo -spell.wizardry:snare=Trampa -spell.wizardry:snowball=Bola de Nieve -spell.wizardry:spark_bomb=Bomba de Chispa -spell.wizardry:spectral_pathway=Camino Espectral -spell.wizardry:spider_swarm=Emjambre de Arañas -spell.wizardry:static_aura=Aura Estatica -spell.wizardry:summon_blaze=Invocar Blaze -spell.wizardry:summon_ice_giant=Invocar Gigante de Hielo -spell.wizardry:summon_ice_wraith=Invocar Espectro de Hielo -spell.wizardry:summon_iron_golem=Invocar Golem de Hierro -spell.wizardry:summon_lightning_wraith=Invocar Espectro de Rayo -spell.wizardry:summon_phoenix=Invocar Fenix -spell.wizardry:summon_shadow_wraith=Invocar Espectro de las Sombras -spell.wizardry:summon_skeleton=Invocar Esqueleto -spell.wizardry:summon_skeleton_legion=Invocar Legion de Esqueletos -spell.wizardry:summon_snow_golem=Invocar Golem de Nieve -spell.wizardry:summon_spirit_horse=Invocar Caballo Espiritual -spell.wizardry:summon_spirit_wolf=Invocar Lobo Espiritual -spell.wizardry:summon_storm_elemental=Invocar Elemental del Rayo -spell.wizardry:summon_wither_skeleton=Invocar Esqueleto del Wither -spell.wizardry:summon_zombie=Invocar Zombi -spell.wizardry:telekinesis=Telequinesis -spell.wizardry:thunderbolt=Rayo -spell.wizardry:thunderstorm=Tormenta Electrica -spell.wizardry:tornado=Tornado -spell.wizardry:transience=Transitoriedad -spell.wizardry:transportation=Transportacion -spell.wizardry:vanishing_box=Caja Desvaneciente -spell.wizardry:wall_of_frost=Pared de Escarcha -spell.wizardry:water_breathing=Respiracion Acuatica -spell.wizardry:whirlwind=Remolino de Viento -spell.wizardry:wither=Marchitar -spell.wizardry:wither_skull=Craneo de Wither +spell.agility=Agilidad +spell.arc=Arco Electrico +spell.arcane_jammer=Perturbador Arcano +spell.arrow_rain=Lluvia de Flechas +spell.banish=Desaparecer +spell.black_hole=Agujero Negro +spell.blink=Parpadeo +spell.blizzard=Ventisca +spell.bubble=Burbuja +spell.chain_lightning=Cadena de Rayos +spell.clairvoyance=Clarividencia +spell.cobwebs=Telas de Araña +spell.conjure_armour=Conjurar Armadura +spell.conjure_bow=Conjurar Arco +spell.conjure_pickaxe=Conjurar Pico +spell.conjure_sword=Conjurar Espada +spell.cure_effects=Purificar Efectos +spell.curse_of_soulbinding=Maldicion de Atadura al Alma +spell.darkness_orb=Orbe de la Oscuridad +spell.darkvision=Vision Oscura +spell.dart=Dardo +spell.decay=Deterioro +spell.decoy=Senuelo +spell.detonate=Detonar +spell.diamondflesh=Piel de Diamante +spell.earthquake=Terremoto +spell.entrapment=Atrapamiento +spell.fireball=Bola de Fuego +spell.firebolt=Disparo de Fuego +spell.firebomb=Bomba de Fuego +spell.fire_resistance=Resistencia al Fuego +spell.fire_sigil=Sigilo de Fuego +spell.fireskin=Piel de Fuego +spell.firestorm=Tormenta de Fuego +spell.flame_ray=Rayo de Fuego +spell.flaming_axe=Hacha Llameante +spell.flaming_weapon=Arma Llameante +spell.flight=Vuelo +spell.font_of_mana=Fuente de Mana +spell.font_of_vitality=Fuente de Vitalidad +spell.force_arrow=Flecha de Fuerza +spell.forcefield=Campo de Fuerza +spell.force_orb=Orbe de Fuerza +spell.forests_curse=Maldicion del Bosque +spell.freeze=Congelar +spell.freezing_weapon=Arma Congelante +spell.frost_axe=Hacha Escarchada +spell.frost_ray=Rayo de Escarcha +spell.frost_sigil=Sigilo de Escarcha +spell.glide=Planear +spell.greater_fireball=Bola de Fuego Mayor +spell.greater_heal=Curacion Mayor +spell.group_heal=Curacion Grupal +spell.growth_aura= Aura de Crecimiento +spell.hailstorm=Tormenta de Granizo +spell.heal=Curar +spell.heal_ally=curar Aliado +spell.healing_aura=Aura de Curacion +spell.homing_spark=Chispa Dirigida +spell.ice_age=Era de Hielo +spell.ice_charge=Carga de Hielo +spell.ice_lance=Lanza de Hielo +spell.ice_shard=Fragmento de Hielo +spell.ice_shroud=Velo de Hielo +spell.ice_spikes=Pinchos de Hielo +spell.ice_statue=Estatua de Hielo +spell.ignite=Encender +spell.imbue_weapon=Imbuir Arma +spell.intimidate=Intimidar +spell.invigorating_presence=Presencia Vigorizante +spell.invisibility=Invisibilidad +spell.invoke_weather=Invocar clima +spell.ironflesh=Piel de Hierro +spell.leap=Salto +spell.levitation=Levitacion +spell.life_drain=Drenaje de Vida +spell.light=Luz +spell.lightning_arrow=Flecha de Rayo +spell.lightning_bolt=Disparo de Rayo +spell.lightning_disc=Disco de Rayo +spell.lightning_hammer=Martillo Relampago +spell.lightning_pulse=Pulso Electrico +spell.lightning_ray=Rayo Electrico +spell.lightning_sigil=Sigilo Electrico +spell.lightning_web=Red Electrica +spell.magic_missile=Misil Magico +spell.metamorphosis=Metamorfosis +spell.meteor=Meteoro +spell.mind_control=Control Mental +spell.mind_trick=Truco Mental +spell.none=[Espacio Vacio] +spell.oakflesh=Piel de Roble +spell.petrify=Petrificar +spell.phase_step=Paso de Fase +spell.plague_of_darkness=Plaga de la Oscuridad +spell.pocket_furnace=Horno del Bolsillo +spell.pocket_workbench=Mesa de Trabajo de Bolsillo +spell.poison=Veneno +spell.poison_bomb=Bomba de Veneno +spell.replenish_hunger=Rellenar hambre +spell.ring_of_fire=Anillo de Fuego +spell.shadow_ward=Guarda de las Sombras +spell.shield=Escudo +spell.shockwave=Onda de Choque +spell.silverfish_swarm=Emjambre de Lepismas +spell.sixth_sense=Sexto Sentido +spell.slime=Slime +spell.smoke_bomb=Bomba de Humo +spell.snare=Trampa +spell.snowball=Bola de Nieve +spell.spark_bomb=Bomba de Chispa +spell.spectral_pathway=Camino Espectral +spell.spider_swarm=Emjambre de Arañas +spell.static_aura=Aura Estatica +spell.summon_blaze=Invocar Blaze +spell.summon_ice_giant=Invocar Gigante de Hielo +spell.summon_ice_wraith=Invocar Espectro de Hielo +spell.summon_iron_golem=Invocar Golem de Hierro +spell.summon_lightning_wraith=Invocar Espectro de Rayo +spell.summon_phoenix=Invocar Fenix +spell.summon_shadow_wraith=Invocar Espectro de las Sombras +spell.summon_skeleton=Invocar Esqueleto +spell.summon_skeleton_legion=Invocar Legion de Esqueletos +spell.summon_snow_golem=Invocar Golem de Nieve +spell.summon_spirit_horse=Invocar Caballo Espiritual +spell.summon_spirit_wolf=Invocar Lobo Espiritual +spell.summon_storm_elemental=Invocar Elemental del Rayo +spell.summon_wither_skeleton=Invocar Esqueleto del Wither +spell.summon_zombie=Invocar Zombi +spell.telekinesis=Telequinesis +spell.thunderbolt=Rayo +spell.thunderstorm=Tormenta Electrica +spell.tornado=Tornado +spell.transience=Transitoriedad +spell.transportation=Transportacion +spell.vanishing_box=Caja Desvaneciente +spell.wall_of_frost=Pared de Escarcha +spell.water_breathing=Respiracion Acuatica +spell.whirlwind=Remolino de Viento +spell.wither=Marchitar +spell.wither_skull=Craneo de Wither -spell.wizardry:agility.desc=Concede al mago velocidad de movimiento incrementada y un salto mas alto por 30 segundos. -spell.wizardry:arc.desc=Dispara una chispa de rayo al objetivo. -spell.wizardry:arcane_jammer.desc=No permite que el usuario use magia en los proximos 15 segundos. -spell.wizardry:arrow_rain.desc="Arqueros, disparen!" -spell.wizardry:banish.desc=Teletransporta al objetivo una posicion cercana aleatoria en contra de su voluntad. -spell.wizardry:black_hole.desc=Desgarra la realidad. -spell.wizardry:blink.desc=Teletransporta al mago a la posicion que estan apuntando. -spell.wizardry:blizzard.desc=Crea una zona de aire frio, la cual ralentiza y hiere continuamente a cualquiera en su interior. El creador del hechizo es inmune al dano pero no al efecto. -spell.wizardry:bubble.desc=Dispara un chorro de burbujas que causa que lo primero que toque flote hacia el cielo. La burbuja explota despues de un tiempo o si el objetivo es golpeado. -spell.wizardry:chain_lightning.desc=Dispara un relampago a un objetivo, el cual hace cadena con objetivos cercanos hasta dos veces. -spell.wizardry:clairvoyance.desc=Revela el camino hacia una localizacion guardada. Con este hechizo seleccionado, haga shift-clic derecho en un bloque para guardarlo. Lanza este hechizo para revelar el camino. El camino desaparecera despues de 90 segundos. -spell.wizardry:cobwebs.desc=Crea telas de arana en la direccion a la cual estas apuntando, lo cual limita la movilidad de tu objetivo. Las telas de arana despareceran en 20 segundos o si son rotas. -spell.wizardry:conjure_armour.desc=Crea Armadura Espectral alrededor del mago lo cual ofrece proteccion similar a la armadura de hierro. La armadura dura 60 segundos. El mago debe tener el espacio de armadura vacio. -spell.wizardry:conjure_bow.desc=Crea un Arco Espectral con flechas ilimitadas que dura 30 segundos. -spell.wizardry:conjure_pickaxe.desc=Crea un Pico Espectral con fuerza igual a la de un Pico de Hierro, el cual dura 30 segundos. -spell.wizardry:conjure_sword.desc=Crea una Espada Espectral con igual fuerza que una de hierro y dura 30 segundos. -spell.wizardry:cure_effects.desc=Purifica al usuario de todos los efectos de pocion, ya sean buenos o malos. -spell.wizardry:curse_of_soulbinding.desc=Provoca que el alma del objetivo esta ligada al del mago, lo que significa que todo el dano que recibe el mago lo recibe el objetivo. La maldicion dura hasta que uno de los dos muera. -spell.wizardry:darkness_orb.desc=Dispara una bala de energia oscura en la direccion que apuntes, la cual aplicar wither. -spell.wizardry:darkvision.desc=Concede vision nocturna por 45 segundos. -spell.wizardry:dart.desc=Dispara un dardo en la direccion que estas apuntando el cual hiere y debilita al objetivo. -spell.wizardry:decay.desc=Crea un pezado de deterioro en el suelo lo cual infecta y hiere a cualquier criatura que lo pise, tambien causa que estas criatura sigan esparciendo el deterioro por donde caminen. -spell.wizardry:decoy.desc=Crea un clon ilusorio del mago que atrae a los enemigos. El senuelo desaparecera en 30 segundos. -spell.wizardry:detonate.desc=Causa un explosion donde estes mirando, hiriendo a todas las criaturas cercanas - incluyendo al mago si se encuentra muy cerca. -spell.wizardry:diamondflesh.desc="Tus flechas no son nada contra mi!" -spell.wizardry:earthquake.desc=Un verdadero de Mago de Tierra puede mover montanas. -spell.wizardry:entrapment.desc=Atrpa al objetivo en una esfera de oscuridad que lo eleva y hiere continuamente. -spell.wizardry:fireball.desc=Lanza una bola de fuego en la direccion a la que apuntes. -spell.wizardry:firebolt.desc=Dispara un chorro de fuego a corta distancia en frente de ti. -spell.wizardry:firebomb.desc=Lanza una bomba de fuego, la cual detona cuando impacta quemando todo a su alrededor. -spell.wizardry:fire_resistance.desc=Concede resistencia al fuego al mago por 30 segundos. -spell.wizardry:fire_sigil.desc=Coloca una trampa de fuego que quema y hiere a la criatura que la pise. -spell.wizardry:fireskin.desc=Envuelve al mago en fuego por 30 segundos, provocando que cualquier que lo toque se queme. -spell.wizardry:firestorm.desc="Yo soy el dragon." -spell.wizardry:flame_ray.desc=Crea una corriente de llamas en la direccion a la que apuntas, la cual quema todo a su paso. -spell.wizardry:flaming_axe.desc=Crea una Hacha Llameante que quema a todos los enemigos que golpees. Dura 30 segundos. -spell.wizardry:flaming_weapon.desc=Imbuye con llamas la primera arma en el inventario del mago, la magia de deshace despues de 45 segundos. -spell.wizardry:flight.desc=Vuela como un aguila. -spell.wizardry:font_of_mana.desc="Fuimos llenados con una intensa energia magica que parecia emanar del centro del..." - Extraido del diario de un mago olvidado; el resto de la pagina esta quemada. -spell.wizardry:font_of_vitality.desc=Se siente increible. -spell.wizardry:force_arrow.desc=Dispara una flecha de fuerza en la direccion que apuntes. -spell.wizardry:forcefield.desc=Crea un campo de fuerza alrededor del mago que repele criaturas y proyectiles. -spell.wizardry:force_orb.desc=Lanza una esfera de fuerza que hiere y empuja criaturas cuando impacta. -spell.wizardry:forests_curse.desc="Como te atreves a entrar en mi bosque!" -spell.wizardry:freeze.desc=Congela al objetivo por 10 segundos. Tambien congela el agua y crea nieve en el suelo. -spell.wizardry:freezing_weapon.desc=Imbuye el poder del frio a la primera arma en el inventario del mago, provocando que el arma congela a sus objetivos. La magia deshace despues de 45 segundos. -spell.wizardry:frost_axe.desc=Crea un Hacha Escarchada la cual congela los enemigos que golpees. Dura 30 segundos. -spell.wizardry:frost_ray.desc=Crea un corriente de hielo en la direccion que apuntes la cual ralentiza y hiere continuamente al objetivo. -spell.wizardry:frost_sigil.desc=Coloca un trampa de hielo en el suelo el cual hiere y congela al cualquiera que la pise. -spell.wizardry:glide.desc=Permite que el mago planee en el aire. Debe mantenerse el boton presionado. -spell.wizardry:greater_fireball.desc=Lanza una bola de fuego de mayor tamano. -spell.wizardry:greater_heal.desc=Cura 4 corazones del mago. -spell.wizardry:group_heal.desc=Cura 3 corazones al mago, a aliados cercanos y a criaturas invocadas. -spell.wizardry:growth_aura.desc=Crece todos los cultivos cercanos al mago. Tambien hace crecer flores y hierba alta. -spell.wizardry:hailstorm.desc=Fue durante el Gran Invierno de la 3era Edad que los Magos de Hielo descubrieron su verdadero potencial. -spell.wizardry:heal.desc=Cura 2 corazones del usuario. -spell.wizardry:heal_ally.desc=Cura 2.5 corazones al objetivo. -spell.wizardry:healing_aura.desc=Crea una zona de energia curadora que regenera la salud de todos los alidados cercanos. Los No-_muertos dentro reciben dano. -spell.wizardry:homing_spark.desc=Crea una chispa flotante que persigue enemigos. -spell.wizardry:ice_age.desc="Seras congelado por toda la eternidad!" -spell.wizardry:ice_charge.desc=Lanza una carga de hielo que explota cuando impacta, congelando todas las criaturas y soltando fragmentos en todas las direcciones. -spell.wizardry:ice_lance.desc=Dispara una gran lanza de hielo en la direccion a la que estas apuntando, la cual atraviesa los objetivos hieriendo y congelandolos. -spell.wizardry:ice_shard.desc=Dispara un fragemento de hielo que hace dano y ralentiza -spell.wizardry:ice_shroud.desc=Cubre al mago con hielo, lo que ocasiona que cualquier que lo ataque sea congelado. -spell.wizardry:ice_spikes.desc=Causa que pinchos de hielo crezcan desde el suelo hiriendo a los enemigos. -spell.wizardry:ice_statue.desc=Congela al objetivo durante 20 segundos. El objetivo no se puede mover ni atacar pero tambien es inmune al dano. -spell.wizardry:ignite.desc=Quema al objetivo. Tambien funciona como un mechero. -spell.wizardry:imbue_weapon.desc=Imbuye la primera arma en el inventario con magia, haciendola mas efectiva. La magia se deshace despues de 45 segundos. -spell.wizardry:intimidate.desc=Emite un grunido intimidante el cual provoca que las criaturas espacen. -spell.wizardry:invigorating_presence.desc=Concede al mago y a los aliados cercanos fuerza incrementada por 45 segundos. -spell.wizardry:invisibility.desc=Le otorga invisibilidad al mago por 30 segundos. -spell.wizardry:invoke_weather.desc=Cambia el clima del mundo. -spell.wizardry:ironflesh.desc=Mejora grandemente la resistencia del mago por 30 segundos. -spell.wizardry:leap.desc=Causa que el mago salte alto y se mueve levemente hacia adelante. -spell.wizardry:levitation.desc=Levanta al mago hacia el cielo mientras el boton siga presionado. Si es usando antes de golpear el suelo, anula el dano por caida. -spell.wizardry:life_drain.desc=Crea una correinte de energia oscura que drena la vida de tu objetivo y te cura. -spell.wizardry:light.desc=Crea una esfera de luz que alumbra el area. Dura 30 segundos. -spell.wizardry:lightning_arrow.desc=Lanza una flecha electrificada en la direccion que apuntes. -spell.wizardry:lightning_bolt.desc=Causa que un trueno caiga en la direccion que apuntes. -spell.wizardry:lightning_disc.desc=Envia un disco electrico en la direccion que apuntes, el cual busca objetivos. -spell.wizardry:lightning_hammer.desc="Te golpeare con la ira de los cielos!" -spell.wizardry:lightning_pulse.desc=Carga el suelo cerca del mago con corriente electrica, hiriendo y repeliendo criaturas cercanas. -spell.wizardry:lightning_ray.desc=Crea una corriente de energia electrica que hiere a tus objetivos continuamente. -spell.wizardry:lightning_sigil.desc=Coloca una trampa electrificada que electrocuta a la criatura que la pise. -spell.wizardry:lightning_web.desc="Concentrare. Canaliza la tormenta en tu mente a traves de tu varita y liberala." -spell.wizardry:magic_missile.desc=Dispara una bala de energia magica. -spell.wizardry:metamorphosis.desc=Cambia la forma del objetivo. Solo funciona en algunas criaturas. -spell.wizardry:meteor.desc=Algunos magos solo quieren ver el mundo arder... -spell.wizardry:mind_control.desc=Toma control de la mente del objetivo por 30 segundos, provocando que cambie de bando y peleen a tu favor. No funciona con criaturas de voluntad muy fuerte. -spell.wizardry:mind_trick.desc=Confunde y desorienta al objetivo por 15 segundos, volviendolo incapaz de atacar. El efecto se desactiva si el objetivo recibe dano. -spell.wizardry:none.desc=Para obtener un libro de hechizo con el comando /give, usa la metadata: /give [player] wizardry:spell_book 1 [spell id] (_si encontraste este libro en un cofre significa que otro mod esta alterando las cosas). -spell.wizardry:oakflesh.desc=Mejora la resistencia del amgo durante 30 segundos. -spell.wizardry:petrify.desc=Convierte al objetivo en piedra hasta que se libere, con un chance de liberarse cuando se pone de noche. El objetivo no se puede mover ni atacar y no puede ser atacado. -spell.wizardry:phase_step.desc=Transporta al mago a traves de una pared de 1 bloque de grosor. El rango mejora el grosor por el cual te puedes transportar. -spell.wizardry:plague_of_darkness.desc=La Oscuridad los consumira a todos... -spell.wizardry:pocket_furnace.desc=Cocina 5 objetos en el inventario. Los objetos en la barra seran cocinados primero. -spell.wizardry:pocket_workbench.desc=Permite al mago craftear objetos. -spell.wizardry:poison.desc=Dispara veneno en la direccion que apuntes. -spell.wizardry:poison_bomb.desc=Lanza una bomba de veneno, la cual detona esparciendo mas veneno. -spell.wizardry:replenish_hunger.desc=Rellena 6 puntos de hambre del mago. -spell.wizardry:ring_of_fire.desc=Crea un anillo de fuego alrededor del mago, hiriendo y quemando a los objetivos cercanos. -spell.wizardry:shadow_ward.desc=Crea una pared de oscurdiad en frente del mago lo cual hace que la mitad del dano recibido sea aplicado al atacante. -spell.wizardry:shield.desc=Crea una barrera protectora que bloquea proyectiles y magia. Tambien concede al mago un efecto debil de resistencia. -spell.wizardry:shockwave.desc=Boom. -spell.wizardry:silverfish_swarm.desc="Ahhhh! Se estan multiplicando!!" -spell.wizardry:sixth_sense.desc=Le permite al mago sentir las criaturas cercanas a el, incluso a traves de paredes, durante 20 segundos. -spell.wizardry:slime.desc=Envuelve al objetivo en slime lo cual ralentiza y hiere continuamente. El slime explota despues de 10 segundos. -spell.wizardry:smoke_bomb.desc=Lanza una bomba de humo la cual explota cuando impacta. Creando una nube de humo y dandole ceguera a las criaturas en el area de impacto. -spell.wizardry:snare.desc=Coloca un trampa en el suelo que hiere y ralentiza al que la pise. -spell.wizardry:snowball.desc=Lanza una bola de nieve. -spell.wizardry:spark_bomb.desc=Lanza una bomba electrica que electrocuta a los objetivos cerca de su zona de impacto. -spell.wizardry:spectral_pathway.desc=Crea un puente magico indestructible al frente del mago que se extiende a 15 bloques. El puente desaperece luego de 60 segundos. -spell.wizardry:spider_swarm.desc=Invoca un emjambre de aranas venenosas. Desapareceran despues de 3o segundos o si son eliminadas. -spell.wizardry:static_aura.desc=Rodea al mago de electricidad durante 30 segundos, disparando chispa de rayo a cualquiera que lo golpee. -spell.wizardry:summon_blaze.desc=Invoca un Blaze que pelea por ti. El blaze desparecera despues de 30 segundos o si es derrotado. -spell.wizardry:summon_ice_giant.desc="Smash them!" -spell.wizardry:summon_ice_wraith.desc=Invoca un Espectro de Hielo que pelea por ti. El Espectro de Hielo desparecera despues de 30 segundos o si es derrotado. -spell.wizardry:summon_iron_golem.desc=Autómata autónomo automatizado automático. -spell.wizardry:summon_lightning_wraith.desc=Invoca un Espectro de Rayo que pelea por ti. El Espectro de Rayo desparecera despues de 30 segundos o si es derrotado. -spell.wizardry:summon_phoenix.desc=Desde las cenizas... -spell.wizardry:summon_shadow_wraith.desc=Invoca un Espectro de las Sombras que pelea por ti. -spell.wizardry:summon_skeleton.desc=Invoca un Esqueleto que pelea por ti. El esqueleto desparecera despues de 30 segundos o si es derrotado. -spell.wizardry:summon_skeleton_legion.desc="Levantate, Ejercito No-_muerto!" -spell.wizardry:summon_snow_golem.desc=Crea un Golem de Nieve que pelea por ti. Dura hasta que el golem muera. -spell.wizardry:summon_spirit_horse.desc=Invoca un Caballo Espectral para que lo montes. El caballo desparecera despues de que dure mucho tiempo sin ser montado o hagas shift-clic derecho con cualquier varita. -spell.wizardry:summon_spirit_wolf.desc=Invoca un Lobo Espiritual que pelea por ti. El lobo solo desparecera si es matado o haces shift-clic derecho con cualquier varita. -spell.wizardry:summon_storm_elemental.desc="Elemental de Rayo: Una manifestacion antigua de los elementos, difícilmente puede contener la energía que se agita dentro de el." - Guia del Mago sobre Entidades Arcanas, Volumen I_i -spell.wizardry:summon_wither_skeleton.desc=Invoca un Esqueleto del Wither que pelea por ti. El esqueleto del wither desparecera despues de 30 segundos o si es derrotado. -spell.wizardry:summon_zombie.desc=Invoca un Zombi que pelea por ti. El zombi desparecera despues de 30 segundos o si es derrotado. -spell.wizardry:telekinesis.desc=Mueve un item o un objeto pequeno hacia ti si haces clic derecho sobre el bloque. Tambien puede desarmar jugadores. -spell.wizardry:thunderbolt.desc=Dispara una bala de trueno que empuja los enemigos. -spell.wizardry:thunderstorm.desc="Mwahahahahahaha!" -spell.wizardry:tornado.desc=Libera un tornado en la direccion que mires, el cual atrae y levanta a todos las criaturas en su paso. -spell.wizardry:transience.desc=Hace que el mago transcienda, volviendo inmune a todo dano pero volviendo incapaz de atacar, interactuar o romper bloques -spell.wizardry:transportation.desc=Teletransporta al mago a su circulo de piedra. Para guardar un circulo de piedra haz clic derecho con el hechizo seleccionado. -spell.wizardry:vanishing_box.desc=Le permite al mago accesar a su cofre de Ender. -spell.wizardry:wall_of_frost.desc=El invierno en la punta de tus dedos. -spell.wizardry:water_breathing.desc=Le permite al mago respirar debajo del agua durante 60 segundos. -spell.wizardry:whirlwind.desc=Causa que el objetivo sea soplado lejos de ti a gran velocidad. -spell.wizardry:wither.desc=Dispara un rayo de oscuridad que aplica wither a todo lo que toque. -spell.wizardry:wither_skull.desc=Lanza una Cabeza de Wither en la direccion que apuntes. +spell.agility.desc=Concede al mago velocidad de movimiento incrementada y un salto mas alto por 30 segundos. +spell.arc.desc=Dispara una chispa de rayo al objetivo. +spell.arcane_jammer.desc=No permite que el usuario use magia en los proximos 15 segundos. +spell.arrow_rain.desc="Arqueros, disparen!" +spell.banish.desc=Teletransporta al objetivo una posicion cercana aleatoria en contra de su voluntad. +spell.black_hole.desc=Desgarra la realidad. +spell.blink.desc=Teletransporta al mago a la posicion que estan apuntando. +spell.blizzard.desc=Crea una zona de aire frio, la cual ralentiza y hiere continuamente a cualquiera en su interior. El creador del hechizo es inmune al dano pero no al efecto. +spell.bubble.desc=Dispara un chorro de burbujas que causa que lo primero que toque flote hacia el cielo. La burbuja explota despues de un tiempo o si el objetivo es golpeado. +spell.chain_lightning.desc=Dispara un relampago a un objetivo, el cual hace cadena con objetivos cercanos hasta dos veces. +spell.clairvoyance.desc=Revela el camino hacia una localizacion guardada. Con este hechizo seleccionado, haga shift-clic derecho en un bloque para guardarlo. Lanza este hechizo para revelar el camino. El camino desaparecera despues de 90 segundos. +spell.cobwebs.desc=Crea telas de arana en la direccion a la cual estas apuntando, lo cual limita la movilidad de tu objetivo. Las telas de arana despareceran en 20 segundos o si son rotas. +spell.conjure_armour.desc=Crea Armadura Espectral alrededor del mago lo cual ofrece proteccion similar a la armadura de hierro. La armadura dura 60 segundos. El mago debe tener el espacio de armadura vacio. +spell.conjure_bow.desc=Crea un Arco Espectral con flechas ilimitadas que dura 30 segundos. +spell.conjure_pickaxe.desc=Crea un Pico Espectral con fuerza igual a la de un Pico de Hierro, el cual dura 30 segundos. +spell.conjure_sword.desc=Crea una Espada Espectral con igual fuerza que una de hierro y dura 30 segundos. +spell.cure_effects.desc=Purifica al usuario de todos los efectos de pocion, ya sean buenos o malos. +spell.curse_of_soulbinding.desc=Provoca que el alma del objetivo esta ligada al del mago, lo que significa que todo el dano que recibe el mago lo recibe el objetivo. La maldicion dura hasta que uno de los dos muera. +spell.darkness_orb.desc=Dispara una bala de energia oscura en la direccion que apuntes, la cual aplicar wither. +spell.darkvision.desc=Concede vision nocturna por 45 segundos. +spell.dart.desc=Dispara un dardo en la direccion que estas apuntando el cual hiere y debilita al objetivo. +spell.decay.desc=Crea un pezado de deterioro en el suelo lo cual infecta y hiere a cualquier criatura que lo pise, tambien causa que estas criatura sigan esparciendo el deterioro por donde caminen. +spell.decoy.desc=Crea un clon ilusorio del mago que atrae a los enemigos. El senuelo desaparecera en 30 segundos. +spell.detonate.desc=Causa un explosion donde estes mirando, hiriendo a todas las criaturas cercanas - incluyendo al mago si se encuentra muy cerca. +spell.diamondflesh.desc="Tus flechas no son nada contra mi!" +spell.earthquake.desc=Un verdadero de Mago de Tierra puede mover montanas. +spell.entrapment.desc=Atrpa al objetivo en una esfera de oscuridad que lo eleva y hiere continuamente. +spell.fireball.desc=Lanza una bola de fuego en la direccion a la que apuntes. +spell.firebolt.desc=Dispara un chorro de fuego a corta distancia en frente de ti. +spell.firebomb.desc=Lanza una bomba de fuego, la cual detona cuando impacta quemando todo a su alrededor. +spell.fire_resistance.desc=Concede resistencia al fuego al mago por 30 segundos. +spell.fire_sigil.desc=Coloca una trampa de fuego que quema y hiere a la criatura que la pise. +spell.fireskin.desc=Envuelve al mago en fuego por 30 segundos, provocando que cualquier que lo toque se queme. +spell.firestorm.desc="Yo soy el dragon." +spell.flame_ray.desc=Crea una corriente de llamas en la direccion a la que apuntas, la cual quema todo a su paso. +spell.flaming_axe.desc=Crea una Hacha Llameante que quema a todos los enemigos que golpees. Dura 30 segundos. +spell.flaming_weapon.desc=Imbuye con llamas la primera arma en el inventario del mago, la magia de deshace despues de 45 segundos. +spell.flight.desc=Vuela como un aguila. +spell.font_of_mana.desc="Fuimos llenados con una intensa energia magica que parecia emanar del centro del..." - Extraido del diario de un mago olvidado; el resto de la pagina esta quemada. +spell.font_of_vitality.desc=Se siente increible. +spell.force_arrow.desc=Dispara una flecha de fuerza en la direccion que apuntes. +spell.forcefield.desc=Crea un campo de fuerza alrededor del mago que repele criaturas y proyectiles. +spell.force_orb.desc=Lanza una esfera de fuerza que hiere y empuja criaturas cuando impacta. +spell.forests_curse.desc="Como te atreves a entrar en mi bosque!" +spell.freeze.desc=Congela al objetivo por 10 segundos. Tambien congela el agua y crea nieve en el suelo. +spell.freezing_weapon.desc=Imbuye el poder del frio a la primera arma en el inventario del mago, provocando que el arma congela a sus objetivos. La magia deshace despues de 45 segundos. +spell.frost_axe.desc=Crea un Hacha Escarchada la cual congela los enemigos que golpees. Dura 30 segundos. +spell.frost_ray.desc=Crea un corriente de hielo en la direccion que apuntes la cual ralentiza y hiere continuamente al objetivo. +spell.frost_sigil.desc=Coloca un trampa de hielo en el suelo el cual hiere y congela al cualquiera que la pise. +spell.glide.desc=Permite que el mago planee en el aire. Debe mantenerse el boton presionado. +spell.greater_fireball.desc=Lanza una bola de fuego de mayor tamano. +spell.greater_heal.desc=Cura 4 corazones del mago. +spell.group_heal.desc=Cura 3 corazones al mago, a aliados cercanos y a criaturas invocadas. +spell.growth_aura.desc=Crece todos los cultivos cercanos al mago. Tambien hace crecer flores y hierba alta. +spell.hailstorm.desc=Fue durante el Gran Invierno de la 3era Edad que los Magos de Hielo descubrieron su verdadero potencial. +spell.heal.desc=Cura 2 corazones del usuario. +spell.heal_ally.desc=Cura 2.5 corazones al objetivo. +spell.healing_aura.desc=Crea una zona de energia curadora que regenera la salud de todos los alidados cercanos. Los No-Muertos dentro reciben dano. +spell.homing_spark.desc=Crea una chispa flotante que persigue enemigos. +spell.ice_age.desc="Seras congelado por toda la eternidad!" +spell.ice_charge.desc=Lanza una carga de hielo que explota cuando impacta, congelando todas las criaturas y soltando fragmentos en todas las direcciones. +spell.ice_lance.desc=Dispara una gran lanza de hielo en la direccion a la que estas apuntando, la cual atraviesa los objetivos hieriendo y congelandolos. +spell.ice_shard.desc=Dispara un fragemento de hielo que hace dano y ralentiza +spell.ice_shroud.desc=Cubre al mago con hielo, lo que ocasiona que cualquier que lo ataque sea congelado. +spell.ice_spikes.desc=Causa que pinchos de hielo crezcan desde el suelo hiriendo a los enemigos. +spell.ice_statue.desc=Congela al objetivo durante 20 segundos. El objetivo no se puede mover ni atacar pero tambien es inmune al dano. +spell.ignite.desc=Quema al objetivo. Tambien funciona como un mechero. +spell.imbue_weapon.desc=Imbuye la primera arma en el inventario con magia, haciendola mas efectiva. La magia se deshace despues de 45 segundos. +spell.intimidate.desc=Emite un grunido intimidante el cual provoca que las criaturas espacen. +spell.invigorating_presence.desc=Concede al mago y a los aliados cercanos fuerza incrementada por 45 segundos. +spell.invisibility.desc=Le otorga invisibilidad al mago por 30 segundos. +spell.invoke_weather.desc=Cambia el clima del mundo. +spell.ironflesh.desc=Mejora grandemente la resistencia del mago por 30 segundos. +spell.leap.desc=Causa que el mago salte alto y se mueve levemente hacia adelante. +spell.levitation.desc=Levanta al mago hacia el cielo mientras el boton siga presionado. Si es usando antes de golpear el suelo, anula el dano por caida. +spell.life_drain.desc=Crea una correinte de energia oscura que drena la vida de tu objetivo y te cura. +spell.light.desc=Crea una esfera de luz que alumbra el area. Dura 30 segundos. +spell.lightning_arrow.desc=Lanza una flecha electrificada en la direccion que apuntes. +spell.lightning_bolt.desc=Causa que un trueno caiga en la direccion que apuntes. +spell.lightning_disc.desc=Envia un disco electrico en la direccion que apuntes, el cual busca objetivos. +spell.lightning_hammer.desc="Te golpeare con la ira de los cielos!" +spell.lightning_pulse.desc=Carga el suelo cerca del mago con corriente electrica, hiriendo y repeliendo criaturas cercanas. +spell.lightning_ray.desc=Crea una corriente de energia electrica que hiere a tus objetivos continuamente. +spell.lightning_sigil.desc=Coloca una trampa electrificada que electrocuta a la criatura que la pise. +spell.lightning_web.desc="Concentrare. Canaliza la tormenta en tu mente a traves de tu varita y liberala." +spell.magic_missile.desc=Dispara una bala de energia magica. +spell.metamorphosis.desc=Cambia la forma del objetivo. Solo funciona en algunas criaturas. +spell.meteor.desc=Algunos magos solo quieren ver el mundo arder... +spell.mind_control.desc=Toma control de la mente del objetivo por 30 segundos, provocando que cambie de bando y peleen a tu favor. No funciona con criaturas de voluntad muy fuerte. +spell.mind_trick.desc=Confunde y desorienta al objetivo por 15 segundos, volviendolo incapaz de atacar. El efecto se desactiva si el objetivo recibe dano. +spell.none.desc=Para obtener un libro de hechizo con el comando /give, usa la metadata: /give [player] wizardry:spell_book 1 [spell id] (Si encontraste este libro en un cofre significa que otro mod esta alterando las cosas). +spell.oakflesh.desc=Mejora la resistencia del amgo durante 30 segundos. +spell.petrify.desc=Convierte al objetivo en piedra hasta que se libere, con un chance de liberarse cuando se pone de noche. El objetivo no se puede mover ni atacar y no puede ser atacado. +spell.phase_step.desc=Transporta al mago a traves de una pared de 1 bloque de grosor. El rango mejora el grosor por el cual te puedes transportar. +spell.plague_of_darkness.desc=La Oscuridad los consumira a todos... +spell.pocket_furnace.desc=Cocina 5 objetos en el inventario. Los objetos en la barra seran cocinados primero. +spell.pocket_workbench.desc=Permite al mago craftear objetos. +spell.poison.desc=Dispara veneno en la direccion que apuntes. +spell.poison_bomb.desc=Lanza una bomba de veneno, la cual detona esparciendo mas veneno. +spell.replenish_hunger.desc=Rellena 6 puntos de hambre del mago. +spell.ring_of_fire.desc=Crea un anillo de fuego alrededor del mago, hiriendo y quemando a los objetivos cercanos. +spell.shadow_ward.desc=Crea una pared de oscurdiad en frente del mago lo cual hace que la mitad del dano recibido sea aplicado al atacante. +spell.shield.desc=Crea una barrera protectora que bloquea proyectiles y magia. Tambien concede al mago un efecto debil de resistencia. +spell.shockwave.desc=Boom. +spell.silverfish_swarm.desc="Ahhhh! Se estan multiplicando!!" +spell.sixth_sense.desc=Le permite al mago sentir las criaturas cercanas a el, incluso a traves de paredes, durante 20 segundos. +spell.slime.desc=Envuelve al objetivo en slime lo cual ralentiza y hiere continuamente. El slime explota despues de 10 segundos. +spell.smoke_bomb.desc=Lanza una bomba de humo la cual explota cuando impacta. Creando una nube de humo y dandole ceguera a las criaturas en el area de impacto. +spell.snare.desc=Coloca un trampa en el suelo que hiere y ralentiza al que la pise. +spell.snowball.desc=Lanza una bola de nieve. +spell.spark_bomb.desc=Lanza una bomba electrica que electrocuta a los objetivos cerca de su zona de impacto. +spell.spectral_pathway.desc=Crea un puente magico indestructible al frente del mago que se extiende a 15 bloques. El puente desaperece luego de 60 segundos. +spell.spider_swarm.desc=Invoca un emjambre de aranas venenosas. Desapareceran despues de 3o segundos o si son eliminadas. +spell.static_aura.desc=Rodea al mago de electricidad durante 30 segundos, disparando chispa de rayo a cualquiera que lo golpee. +spell.summon_blaze.desc=Invoca un Blaze que pelea por ti. El blaze desparecera despues de 30 segundos o si es derrotado. +spell.summon_ice_giant.desc="Smash them!" +spell.summon_ice_wraith.desc=Invoca un Espectro de Hielo que pelea por ti. El Espectro de Hielo desparecera despues de 30 segundos o si es derrotado. +spell.summon_iron_golem.desc=Autómata autónomo automatizado automático. +spell.summon_lightning_wraith.desc=Invoca un Espectro de Rayo que pelea por ti. El Espectro de Rayo desparecera despues de 30 segundos o si es derrotado. +spell.summon_phoenix.desc=Desde las cenizas... +spell.summon_shadow_wraith.desc=Invoca un Espectro de las Sombras que pelea por ti. +spell.summon_skeleton.desc=Invoca un Esqueleto que pelea por ti. El esqueleto desparecera despues de 30 segundos o si es derrotado. +spell.summon_skeleton_legion.desc="Levantate, Ejercito No-Muerto!" +spell.summon_snow_golem.desc=Crea un Golem de Nieve que pelea por ti. Dura hasta que el golem muera. +spell.summon_spirit_horse.desc=Invoca un Caballo Espectral para que lo montes. El caballo desparecera despues de que dure mucho tiempo sin ser montado o hagas shift-clic derecho con cualquier varita. +spell.summon_spirit_wolf.desc=Invoca un Lobo Espiritual que pelea por ti. El lobo solo desparecera si es matado o haces shift-clic derecho con cualquier varita. +spell.summon_storm_elemental.desc="Elemental de Rayo: Una manifestacion antigua de los elementos, difícilmente puede contener la energía que se agita dentro de el." - Guia del Mago sobre Entidades Arcanas, Volumen II +spell.summon_wither_skeleton.desc=Invoca un Esqueleto del Wither que pelea por ti. El esqueleto del wither desparecera despues de 30 segundos o si es derrotado. +spell.summon_zombie.desc=Invoca un Zombi que pelea por ti. El zombi desparecera despues de 30 segundos o si es derrotado. +spell.telekinesis.desc=Mueve un item o un objeto pequeno hacia ti si haces clic derecho sobre el bloque. Tambien puede desarmar jugadores. +spell.thunderbolt.desc=Dispara una bala de trueno que empuja los enemigos. +spell.thunderstorm.desc="Mwahahahahahaha!" +spell.tornado.desc=Libera un tornado en la direccion que mires, el cual atrae y levanta a todos las criaturas en su paso. +spell.transience.desc=Hace que el mago transcienda, volviendo inmune a todo dano pero volviendo incapaz de atacar, interactuar o romper bloques +spell.transportation.desc=Teletransporta al mago a su circulo de piedra. Para guardar un circulo de piedra haz clic derecho con el hechizo seleccionado. +spell.vanishing_box.desc=Le permite al mago accesar a su cofre de Ender. +spell.wall_of_frost.desc=El invierno en la punta de tus dedos. +spell.water_breathing.desc=Le permite al mago respirar debajo del agua durante 60 segundos. +spell.whirlwind.desc=Causa que el objetivo sea soplado lejos de ti a gran velocidad. +spell.wither.desc=Dispara un rayo de oscuridad que aplica wither a todo lo que toque. +spell.wither_skull.desc=Lanza una Cabeza de Wither en la direccion que apuntes. -spell.wizardry:invoke_weather.sun=La lluvia empieza a parar... -spell.wizardry:invoke_weather.rain=El cielo se abre... -spell.wizardry:transportation.missing=Tu circulo de piedra no se encuentra o esta siendo obstruido... -spell.wizardry:transportation.undefined=Debes guardar un circulo de piedra primero! -spell.wizardry:transportation.wrongdimension=Tu circulo de piedra se encuentra en otra dimension... -spell.wizardry:clairvoyance.searching=Buscando... -spell.wizardry:clairvoyance.confirm=El camino revelado al lanzar %1$s ahora te llevara a este punto -spell.wizardry:clairvoyance.outofrange=Tu punto guardado esta muy lejos o es inaccesible... -spell.wizardry:clairvoyance.undefined=Debes guardar una localizacion primero! -spell.wizardry:clairvoyance.wrongdimension=Tu localizacion guardada esta en otra dimension... +spell.invoke_weather.sun=La lluvia empieza a parar... +spell.invoke_weather.rain=El cielo se abre... +spell.transportation.missing=Tu circulo de piedra no se encuentra o esta siendo obstruido... +spell.transportation.undefined=Debes guardar un circulo de piedra primero! +spell.transportation.wrongdimension=Tu circulo de piedra se encuentra en otra dimension... +spell.clairvoyance.searching=Buscando... +spell.clairvoyance.confirm=El camino revelado al lanzar %1$s ahora te llevara a este punto +spell.clairvoyance.outofrange=Tu punto guardado esta muy lejos o es inaccesible... +spell.clairvoyance.undefined=Debes guardar una localizacion primero! +spell.clairvoyance.wrongdimension=Tu localizacion guardada esta en otra dimension... -potion.wizardry:frost=Congelacion -potion.wizardry:fireskin=Piel de Fuego -potion.wizardry:ice_shroud=Manto de Hielo -potion.wizardry:static_aura=Aura Estatica -potion.wizardry:transience=Transitoriedad -potion.wizardry:decay=Deterioro -potion.wizardry:sixth_sense=Sexto Sentido -potion.wizardry:arcane_jammer=Perturbador Arcano -potion.wizardry:mind_trick=Truco Mental -potion.wizardry:mind_control=Control Mental -potion.wizardry:font_of_mana=Fuente de Mana -potion.wizardry:fear=Miedo +potion.frost=Congelacion +potion.fireskin=Piel de Fuego +potion.ice_shroud=Manto de Hielo +potion.static_aura=Aura Estatica +potion.transience=Transitoriedad +potion.decay=Deterioro +potion.sixth_sense=Sexto Sentido +potion.arcane_jammer=Perturbador Arcano +potion.mind_trick=Truco Mental +potion.mind_control=Control Mental +potion.font_of_mana=Fuente de Mana +potion.fear=Miedo -enchantment.wizardry:magic_sword=Impregnacion -enchantment.wizardry:magic_bow=Impregnacion -enchantment.wizardry:flaming_weapon=Impregnacion de Fuego -enchantment.wizardry:freezing_weapon=Impregnacion de Fuego +enchantment.magic_sword=Impregnacion +enchantment.magic_bow=Impregnacion +enchantment.flaming_weapon=Impregnacion de Fuego +enchantment.freezing_weapon=Impregnacion de Fuego key.categories.wizardry=Wizardry -key.wizardry.next_spell=Hechizo siguiente -key.wizardry.previous_spell=Hechizo anterior +key.next_spell=Hechizo siguiente +key.previous_spell=Hechizo anterior -death.attack.wizardry_magic=%1$s fue matado por %2$s usando magia -death.attack.indirect_wizardry_magic=%1$s fue matado por %2$s usando magia +death.attack.wizardryMagic=%1$s fue matado por %2$s usando magia +death.attack.indirectWizardryMagic=%1$s fue matado por %2$s usando magia -commands.wizardry:cast.usage=/%1$s [player] [damage multiplier] [range multiplier] [duration multiplier] [blast multiplier] -commands.wizardry:cast.success=Lanzado con exito %1$s -commands.wizardry:cast.success_continuous=Lanzado con exito %1$s; repite el comando para parar -commands.wizardry:cast.success_remote=Lanzado con exito %1$s como %2$s -commands.wizardry:cast.success_remote_continuous=Lanzado con exito %1$s como %2$s; repite el comando para parar -commands.wizardry:cast.fail=Imposible lanzar %1$s -commands.wizardry:cast.not_found=No hay ningun hechizo con ID %1$s +commands.cast.usage=/%1$s [player] [damage multiplier] [range multiplier] [duration multiplier] [blast multiplier] +commands.cast.success=Lanzado con exito %1$s +commands.cast.success_continuous=Lanzado con exito %1$s; repite el comando para parar +commands.cast.success_remote=Lanzado con exito %1$s como %2$s +commands.cast.success_remote_continuous=Lanzado con exito %1$s como %2$s; repite el comando para parar +commands.cast.fail=Imposible lanzar %1$s +commands.cast.not_found=No hay ningun hechizo con ID %1$s -commands.wizardry:ally.usage=/%1$s [player] -commands.wizardry:ally.addally=%1$s ha sido anadido a la lista de aliados de %2$s -commands.wizardry:ally.removeally=%1$s ha sido removido de la lista de aliados de %2$s -commands.wizardry:ally.self=Los jugadores no pueden ser aliados de si mismos! -commands.wizardry:ally.permission=No tienes permiso para cambiar los aliados de otros jugadores +commands.ally.usage=/%1$s [player] +commands.ally.addally=%1$s ha sido anadido a la lista de aliados de %2$s +commands.ally.removeally=%1$s ha sido removido de la lista de aliados de %2$s +commands.ally.self=Los jugadores no pueden ser aliados de si mismos! +commands.ally.permission=No tienes permiso para cambiar los aliados de otros jugadores -commands.wizardry:allies.usage=/%1$s [player] -commands.wizardry:allies.list=Jugadores que son aliados: %1$s -commands.wizardry:allies.list_other=Jugadores que son aliados de %1$s: %2$s -commands.wizardry:allies.permission=No tienes permiso para ver los aliados de otros jugadores -commands.wizardry:allies.none=Ninguno +commands.allies.usage=/%1$s [player] +commands.allies.list=Jugadores que son aliados: %1$s +commands.allies.list_other=Jugadores que son aliados de %1$s: %2$s +commands.allies.permission=No tienes permiso para ver los aliados de otros jugadores +commands.allies.none=Ninguno -commands.wizardry:discoverspell.usage=/%1$s [player] -commands.wizardry:discoverspell.not_found=There is no such spell with ID %1$s -commands.wizardry:discoverspell.clear=Cleared all spell discovery data for %1$s -commands.wizardry:discoverspell.all=Added all spells to %1$s's spell discovery data -commands.wizardry:discoverspell.addspell=Added %1$s to %2$s's spell discovery data -commands.wizardry:discoverspell.removespell=Removed %1$s from %2$s's spell discovery data +commands.discoverspell.usage=/%1$s [player] +commands.discoverspell.not_found=There is no such spell with ID %1$s +commands.discoverspell.clear=Cleared all spell discovery data for %1$s +commands.discoverspell.all=Added all spells to %1$s's spell discovery data +commands.discoverspell.addspell=Added %1$s to %2$s's spell discovery data +commands.discoverspell.removespell=Removed %1$s from %2$s's spell discovery data -config.wizardry.title.general=Mod Options +config.title.general=Mod Options -config.wizardry.category.spells=Configurar Hechizos -config.wizardry.category.spells.tooltip=Seleccionar que hechizos estan activados -config.wizardry.title.spells=Configuracion de Hechizos -config.wizardry.subtitle.spells=Establece un hechizo en falso para desactivarlo. +config.category.spells=Configurar Hechizos +config.category.spells.tooltip=Seleccionar que hechizos estan activados +config.title.spells=Configuracion de Hechizos +config.subtitle.spells=Establece un hechizo en falso para desactivarlo. -config.wizardry.category.resistances=Configurar Resistencias -config.wizardry.category.resistances.tooltip=Configura cuales mobs son inmunes a los tipos de magia -config.wizardry.title.resistances=Configuracion de Resistencias -config.wizardry.subtitle.resistances=Ve las descripciones de opciones individuales para mas detalles. +config.category.resistances=Configurar Resistencias +config.category.resistances.tooltip=Configura cuales mobs son inmunes a los tipos de magia +config.title.resistances=Configuracion de Resistencias +config.subtitle.resistances=Ve las descripciones de opciones individuales para mas detalles. -config.wizardry.category.ids=Configurar IDs -config.wizardry.category.ids.tooltip=Cambiar los IDs usados por Wizardry -config.wizardry.title.ids=Configuracion de IDs -config.wizardry.subtitle.ids=Cambia estos IDs si tienen conflicto con otro mod. +config.category.ids=Configurar IDs +config.category.ids.tooltip=Cambiar los IDs usados por Wizardry +config.title.ids=Configuracion de IDs +config.subtitle.ids=Cambia estos IDs si tienen conflicto con otro mod. -config.wizardry.tower_rarity=Rareza de Torres -config.wizardry.ore_dimensions=Dimensiones de Mena -config.wizardry.flower_dimensions=Dimensiones de Flores -config.wizardry.tower_dimensions=Dimensiones de Torres -config.wizardry.spell_book_drop_chance=Oportunidad de Dropeo de Libro de Hechizo -config.wizardry.generate_loot=Generar Botin -config.wizardry.firebomb_is_craftable=Bomba de Fuego es crafteable -config.wizardry.poison_bomb_is_craftable=Bomba de Veneno es crafteable -config.wizardry.smoke_bomb_is_craftable=Bomba de Humo es crafteable -config.wizardry.use_alternate_scroll_recipe=Usa la receta alternativa de pergamino -config.wizardry.teleport_through_unbreakable_blocks=Teletransportarte a traves de bloques indestructibles -config.wizardry.show_summoned_creature_names=Mostrar los nombres de las criaturas invocadas -config.wizardry.friendly_fire=Fuego Amigo -config.wizardry.telekinetic_disarmament=Desarme Telequinetico -config.wizardry.discovery_mode=Modo Descubrir -config.wizardry.enable_shift_scrolling=Permitir shift-rueda del raton para cambiar de hechizo -config.wizardry.minion_revenge_targeting=Enfoque de venganza de minion -config.wizardry.player_damage_scaling=Factor de escala de dano del Jugador -config.wizardry.npc_damage_scaling=Factor de escala de dano de NPC -config.wizardry.cast_command_multiplier_limit=Limite del Multiplicador de lanzamiento de hechizo por Comando -config.wizardry.summoned_creature_targets_whitelist=Lista blanca de objetivos de criaturas invocadas -config.wizardry.summoned_creature_targets_blacklist=Lista negra de objetivos de criaturas invocadas -config.wizardry.spell_hud_position=Posicion del HUD de hechizos -config.wizardry.cast_command_name=Nombre del Hechizo lanzado por comando -config.wizardry.discoverspell_command_name=Descubrir el nombre del hechizo lanzado por comando -config.wizardry.ally_command_name=Colocar el nombre del comando de aliado -config.wizardry.allies_command_name=Ver el nombre del comandod de aliado +config.tower_rarity=Rareza de Torres +config.ore_dimensions=Dimensiones de Mena +config.flower_dimensions=Dimensiones de Flores +config.tower_dimensions=Dimensiones de Torres +config.spell_book_drop_chance=Oportunidad de Dropeo de Libro de Hechizo +config.generate_loot=Generar Botin +config.firebomb_is_craftable=Bomba de Fuego es crafteable +config.poison_bomb_is_craftable=Bomba de Veneno es crafteable +config.smoke_bomb_is_craftable=Bomba de Humo es crafteable +config.use_alternate_scroll_recipe=Usa la receta alternativa de pergamino +config.teleport_through_unbreakable_blocks=Teletransportarte a traves de bloques indestructibles +config.show_summoned_creature_names=Mostrar los nombres de las criaturas invocadas +config.friendly_fire=Fuego Amigo +config.telekinetic_disarmament=Desarme Telequinetico +config.discovery_mode=Modo Descubrir +config.enable_shift_scrolling=Permitir shift-rueda del raton para cambiar de hechizo +config.minion_revenge_targeting=Enfoque de venganza de minion +config.player_damage_scaling=Factor de escala de dano del Jugador +config.npc_damage_scaling=Factor de escala de dano de NPC +config.cast_command_multiplier_limit=Limite del Multiplicador de lanzamiento de hechizo por Comando +config.summoned_creature_targets_whitelist=Lista blanca de objetivos de criaturas invocadas +config.summoned_creature_targets_blacklist=Lista negra de objetivos de criaturas invocadas +config.spell_hud_position=Posicion del HUD de hechizos +config.cast_command_name=Nombre del Hechizo lanzado por comando +config.discoverspell_command_name=Descubrir el nombre del hechizo lanzado por comando +config.ally_command_name=Colocar el nombre del comando de aliado +config.allies_command_name=Ver el nombre del comandod de aliado -config.wizardry.mobs_immune_to_fire=Mobs Inmunes Al Fuego -config.wizardry.mobs_immune_to_ice=Mobs Inmunees Al Frio -config.wizardry.mobs_immune_to_lightning=Mobs Inmunes Al Rayo -config.wizardry.mobs_immune_to_wither=Mobs Inmunes Al Wither -config.wizardry.mobs_immune_to_poison=Mobs Inmunes Al Veneno +config.mobs_immune_to_fire=Mobs Inmunes Al Fuego +config.mobs_immune_to_ice=Mobs Inmunees Al Frio +config.mobs_immune_to_lightning=Mobs Inmunes Al Rayo +config.mobs_immune_to_wither=Mobs Inmunes Al Wither +config.mobs_immune_to_poison=Mobs Inmunes Al Veneno -config.wizardry.tower_rarity.tooltip=Rareza para las torres de magos. Numeros mayores suben la rareza. Coloque un 0 para desactivarlas. -config.wizardry.ore_dimensions.tooltip=Lista de dimensiones en las cuales la Mena de Cristal Magico aparecera. -config.wizardry.flower_dimensions.tooltip=Lista de dimensiones en las cuales apareceran flores de cristal magico. -config.wizardry.tower_dimensions.tooltip=Lista de dimensiones donde se generaran torres de magos. -config.wizardry.spell_book_drop_chance.tooltip=La probabilidad de que un mob arroje un libro de hechizos cuando muera. Mientras mas alto sea el numero, mas chance tendras. Coloca un 0 para desactivar el dropeo de libros. Coloque 200 para asegurar el dropeo 100%. -config.wizardry.generate_loot.tooltip=Si se debe generar botin del mod en cofres de mazmorras. -config.wizardry.firebomb_is_craftable.tooltip=Si las bombas de fuego son crafteables o no. -config.wizardry.poison_bomb_is_craftable.tooltip=Si las bombas de veneno son crafteables o no. -config.wizardry.smoke_bomb_is_craftable.tooltip=Si las bombas de humo son crafteables o no. -config.wizardry.use_alternate_scroll_recipe.tooltip=Si se requiere cristal magico para craftear pergaminos vacioes. Utilice esta opcion si otro mod tiene conflicto. -config.wizardry.teleport_through_unbreakable_blocks.tooltip=Si los jugadores son capaces de pasar a traves de bloques indestructibles (bedrock) usando Paso de Fase. -config.wizardry.show_summoned_creature_names.tooltip=Si mostrar los nombres de las criaturas invocadas y sus duenos sobre su cabeza. -config.wizardry.friendly_fire.tooltip=Permitir que los aliados se puedan herir con magia. -config.wizardry.telekinetic_disarmament.tooltip=Permitir que los jugadores puedan desarmar otros jugadores con el hechizo de Telequinesis. -config.wizardry.discovery_mode.tooltip=Para aquellos que le guste el misterio! Si esta en verdadero, los hechizos que no se hayan conjurado seran ilegibles. No tiene efecto en creativo. -config.wizardry.enable_shift_scrolling.tooltip=Si eres capaz de cambiar de hechizos al agacharte y usar la rueda del raton. Nota: Esta funcionalidad es del lado cliente, otros jugadores no dependen de esta, deben configurar su propia opcion. -config.wizardry.minion_revenge_targeting.tooltip=Si las criaturas invocadas atacan a su invocador si este los ataca. -config.wizardry.player_damage_scaling.tooltip=Factor de incremento de dano global para el dano hecho por jugadores, relativo a 1. -config.wizardry.npc_damage_scaling.tooltip=Factor de incremento de dano global para el dano hecho por NPCs, relativo a 1. -config.wizardry.cast_command_multiplier_limit.tooltip=Limite maximo usado con el comando /cast. Esto esta aqui para evitar que accidentalmente destruyan un mundo o servidor. -config.wizardry.summoned_creature_targets_whitelist.tooltip=Lista de nombres de entidades que los magos y criaturas invocadas pueden atacar. -config.wizardry.summoned_creature_targets_blacklist.tooltip=Lista de nombres de entidades que los magos y criaturas invocadas no pueden atacar. Si eliminas creeper hazlo bajo tu responsabilidad!! -config.wizardry.spell_hud_position.tooltip=La posicion de la interfaz de hechizos. -config.wizardry.cast_command_name.tooltip=El nombre del comando /cast. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'magia', entonces el comando seria /magia. -config.wizardry.discoverspell_command_name.tooltip=El nombre del comando /discoverspell. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'descubrir', entonces el comando seria /descubrir. -config.wizardry.ally_command_name.tooltip=El nombre del comando /ally. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'aliado', entonces el comando seria /aliado. -config.wizardry.allies_command_name.tooltip=El nombre del comando /allies command. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'aliados', entonces el comando seria /aliados. +config.frost_potion_id=ID de la pocion de Congelacion +config.transience_potion_id=ID de la pocion de Transitoriedad +config.fireskin_potion_id=ID de la pocion de Piel de Fuego +config.ice_shroud_potion_id=ID de la pocion de Manto de Hielo +config.static_aura_potion_id=ID de la pocion de Aura Estatica +config.decay_potion_id=ID de la pocion de Deterioro +config.sixth_sense_potion_id=ID de la pocion de Sexto Sentido +config.arcane_jammer_potion_id=ID de la pocion de Perturbador Arcano +config.mind_trick_potion_id=ID de la pocion de Truco Mental +config.mind_control_potion_id=ID de la pocion de Control Mental +config.font_of_mana_potion_id=ID de la pocion de Fuente de Mana +config.fear_potion_id=ID de la pocion de Miedo +config.magic_sword_enchantment_id=ID del Encantamiento de Espada Magica +config.magic_bow_enchantment_id=ID del Encantamiento de Arco Magico +config.flaming_weapon_enchantment_id=ID del Encantamiento de Arma Llameante +config.freezing_weapon_enchantment_id=ID del Encantamiento de Arma Congelada -config.wizardry.mobs_immune_to_fire.tooltip=Lista de nombres de entidades que son inmunes al fuego, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al fuego. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:_mago). -config.wizardry.mobs_immune_to_ice.tooltip=Lista de nombres de entidades que son inmunes al frio, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al frio. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:_mago). -config.wizardry.mobs_immune_to_lightning.tooltip=Lista de nombres de entidades que son inmunes al rayo, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al rayo. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:_mago). -config.wizardry.mobs_immune_to_wither.tooltip=Lista de nombres de entidades que son inmunes al wither, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al wither. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:_mago). -config.wizardry.mobs_immune_to_poison.tooltip=Lista de nombres de entidades que son inmunes al veneno, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al veneno. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:_mago). +config.tower_rarity.tooltip=Rareza para las torres de magos. Numeros mayores suben la rareza. Coloque un 0 para desactivarlas. +config.ore_dimensions.tooltip=Lista de dimensiones en las cuales la Mena de Cristal Magico aparecera. +config.flower_dimensions.tooltip=Lista de dimensiones en las cuales apareceran flores de cristal magico. +config.tower_dimensions.tooltip=Lista de dimensiones donde se generaran torres de magos. +config.spell_book_drop_chance.tooltip=La probabilidad de que un mob arroje un libro de hechizos cuando muera. Mientras mas alto sea el numero, mas chance tendras. Coloca un 0 para desactivar el dropeo de libros. Coloque 200 para asegurar el dropeo 100%. +config.generate_loot.tooltip=Si se debe generar botin del mod en cofres de mazmorras. +config.firebomb_is_craftable.tooltip=Si las bombas de fuego son crafteables o no. +config.poison_bomb_is_craftable.tooltip=Si las bombas de veneno son crafteables o no. +config.smoke_bomb_is_craftable.tooltip=Si las bombas de humo son crafteables o no. +config.use_alternate_scroll_recipe.tooltip=Si se requiere cristal magico para craftear pergaminos vacioes. Utilice esta opcion si otro mod tiene conflicto. +config.teleport_through_unbreakable_blocks.tooltip=Si los jugadores son capaces de pasar a traves de bloques indestructibles (bedrock) usando Paso de Fase. +config.show_summoned_creature_names.tooltip=Si mostrar los nombres de las criaturas invocadas y sus duenos sobre su cabeza. +config.friendly_fire.tooltip=Permitir que los aliados se puedan herir con magia. +config.telekinetic_disarmament.tooltip=Permitir que los jugadores puedan desarmar otros jugadores con el hechizo de Telequinesis. +config.discovery_mode.tooltip=Para aquellos que le guste el misterio! Si esta en verdadero, los hechizos que no se hayan conjurado seran ilegibles. No tiene efecto en creativo. +config.enable_shift_scrolling.tooltip=Si eres capaz de cambiar de hechizos al agacharte y usar la rueda del raton. Nota: Esta funcionalidad es del lado cliente, otros jugadores no dependen de esta, deben configurar su propia opcion. +config.minion_revenge_targeting.tooltip=Si las criaturas invocadas atacan a su invocador si este los ataca. +config.player_damage_scaling.tooltip=Factor de incremento de dano global para el dano hecho por jugadores, relativo a 1. +config.npc_damage_scaling.tooltip=Factor de incremento de dano global para el dano hecho por NPCs, relativo a 1. +config.cast_command_multiplier_limit.tooltip=Limite maximo usado con el comando /cast. Esto esta aqui para evitar que accidentalmente destruyan un mundo o servidor. +config.summoned_creature_targets_whitelist.tooltip=Lista de nombres de entidades que los magos y criaturas invocadas pueden atacar. +config.summoned_creature_targets_blacklist.tooltip=Lista de nombres de entidades que los magos y criaturas invocadas no pueden atacar. Si eliminas creeper hazlo bajo tu responsabilidad!! +config.spell_hud_position.tooltip=La posicion de la interfaz de hechizos. +config.cast_command_name.tooltip=El nombre del comando /cast. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'magia', entonces el comando seria /magia. +config.discoverspell_command_name.tooltip=El nombre del comando /discoverspell. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'descubrir', entonces el comando seria /descubrir. +config.ally_command_name.tooltip=El nombre del comando /ally. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'aliado', entonces el comando seria /aliado. +config.allies_command_name.tooltip=El nombre del comando /allies command. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'aliados', entonces el comando seria /aliados. +config.mobs_immune_to_fire.tooltip=Lista de nombres de entidades que son inmunes al fuego, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al fuego. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:Mago). +config.mobs_immune_to_ice.tooltip=Lista de nombres de entidades que son inmunes al frio, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al frio. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:Mago). +config.mobs_immune_to_lightning.tooltip=Lista de nombres de entidades que son inmunes al rayo, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al rayo. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:Mago). +config.mobs_immune_to_wither.tooltip=Lista de nombres de entidades que son inmunes al wither, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al wither. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:Mago). +config.mobs_immune_to_poison.tooltip=Lista de nombres de entidades que son inmunes al veneno, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al veneno. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:Mago). + +config.frost_potion_id.tooltip=ID de la pocion de Congelacion. Cambialo si hay conflicto con otro mod. +config.transience_potion_id.tooltip=ID de la pocion de Transitoriedad. Cambialo si hay conflicto con otro mod. +config.fireskin_potion_id.tooltip=ID de la pocion de Piel de Fuego. Cambialo si hay conflicto con otro mod. +config.ice_shroud_potion_id.tooltip=ID de la pocion de Velo de Hielo. Cambialo si hay conflicto con otro mod. +config.static_aura_potion_id.tooltip=ID de la pocion de Aura Estatica. Cambialo si hay conflicto con otro mod. +config.decay_potion_id.tooltip=ID de la pocion de Deterioro. Cambialo si hay conflicto con otro mod. +config.sixth_sense_potion_id.tooltip=ID de la pocion de Sexto Sentido. Cambialo si hay conflicto con otro mod. +config.arcane_jammer_potion_id.tooltip=ID de la pocion de Perturbador Arcano. Cambialo si hay conflicto con otro mod. +config.mind_trick_potion_id.tooltip=ID de la pocion de Truco Mental. Cambialo si hay conflicto con otro mod. +config.mind_control_potion_id.tooltip=ID de la pocion de Control Mental. Cambialo si hay conflicto con otro mod. +config.font_of_mana_potion_id.tooltip=ID de la pocion de Fuente de Mana. Cambialo si hay conflicto con otro mod. +config.fear_potion_id.tooltip=ID de la pocion de Miedo. Cambialo si hay conflicto con otro mod. +config.magic_sword_enchantment_id.tooltip=ID del Encantamiendo de Espada Magica. Cambialo si hay conflicto con otro mod. +config.magic_bow_enchantment_id.tooltip=ID del Encantamiento de Arco Magico. Cambialo si hay conflicto con otro mod. +config.flaming_weapon_enchantment_id.tooltip=ID del Encantamiento de Arma Llameante. Cambialo si hay conflicto con otro mod. +config.freezing_weapon_enchantment_id.tooltip=ID del Encantamiento de Arma Congelada. Cambialo si hay conflicto con otro mod. wizard.debug=%1$s, %2$s, %3$s \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/lang/es_MX.lang b/src/main/resources/assets/wizardry/lang/es_MX.lang index 38ffd4fc..fefdc2b2 100644 --- a/src/main/resources/assets/wizardry/lang/es_MX.lang +++ b/src/main/resources/assets/wizardry/lang/es_MX.lang @@ -1,272 +1,272 @@ -tile.wizardry:arcane_workbench.name=Mesa de Trabajo Arcana -tile.wizardry:crystal_ore.name=Mena de Cristal Magico -tile.wizardry:petrified_stone.name=Piedra Petrificada -tile.wizardry:ice_statue.name=Estatua de Hielo -tile.wizardry:crystal_flower.name=Flor de Cristal Magico -tile.wizardry:snare.name=Trampa -tile.wizardry:transportation_stone.name=Piedra de Transportacion -tile.wizardry:spectral_block.name=Bloque Espectral -tile.wizardry:crystal_block.name=Bloque de Cristal Magico +tile.arcaneWorkbench.name=Mesa de Trabajo Arcana +tile.crystalOre.name=Mena de Cristal Magico +tile.petrifiedStone.name=Piedra Petrificada +tile.iceStatue.name=Estatua de Hielo +tile.crystalFlower.name=Flor de Cristal Magico +tile.snare.name=Trampa +tile.transportationStone.name=Piedra de Transportacion +tile.spectralBlock.name=Bloque Espectral +tile.crystalBlock.name=Bloque de Cristal Magico -item.wizardry:magic_crystal.name=Cristal Magico -item.wizardry:magic_wand.name=Varita Magica -item.wizardry:apprentice_wand.name=Varita de Aprendiz -item.wizardry:advanced_wand.name=Varita Avanzada -item.wizardry:master_wand.name=Varita de Maestro -item.wizardry:spell_book.name=Libro de Hechizo +item.magicCrystal.name=Cristal Magico +item.magicWand.name=Varita Magica +item.apprenticeWand.name=Varita de Aprendiz +item.advancedWand.name=Varita Avanzada +item.masterWand.name=Varita de Maestro +item.spellBook.name=Libro de Hechizo -item.wizardry:arcane_tome.name=Tomo de lo Arcano -item.wizardry:arcane_tome.desc1=Mejora cualquier %1$s -item.wizardry:arcane_tome.desc2=varita a nivel %1$s +item.arcaneTome.name=Tomo de lo Arcano +item.arcaneTome.desc1=Mejora cualquier %1$s +item.arcaneTome.desc2=varita a nivel %1$s -item.wizardry:wizard_handbook.name=El Manual del Hechizero -item.wizardry:wizard_handbook.desc=por %1$s +item.wizardHandbook.name=El Manual del Hechizero +item.wizardHandbook.desc=por %1$s -item.wizardry:wand.buff=+%1$s %2$s de potencia -item.wizardry:wand.spell=Hechizo actual: %1$s -item.wizardry:wand.mana=Mana: %1$s/%2$s +item.wand.buff=+%1$s %2$s de potencia +item.wand.spell=Hechizo actual: %1$s +item.wand.mana=Mana: %1$s/%2$s -item.wizardry:wand.addally=%1$s ha sido anadido a tu lista de aliados -item.wizardry:wand.removeally=%1$s ha sido removido a tu lista de aliados +item.wand.addally=%1$s ha sido anadido a tu lista de aliados +item.wand.removeally=%1$s ha sido removido a tu lista de aliados -item.wizardry:basic_fire_wand.name=Varita de Ascuas -item.wizardry:basic_ice_wand.name=Varita de Escarcha -item.wizardry:basic_lightning_wand.name=Varita de Chispas -item.wizardry:basic_necromancy_wand.name=Varita de las Sombras -item.wizardry:basic_earth_wand.name=Varita del Bosque -item.wizardry:basic_sorcery_wand.name=Varita del Misterio -item.wizardry:basic_healing_wand.name=Varita de la Curacion +item.basicFireWand.name=Varita de Ascuas +item.basicIceWand.name=Varita de Escarcha +item.basicLightningWand.name=Varita de Chispas +item.basicNecromancyWand.name=Varita de las Sombras +item.basicEarthWand.name=Varita del Bosque +item.basicSorceryWand.name=Varita del Misterio +item.basicHealingWand.name=Varita de la Curacion -item.wizardry:apprentice_fire_wand.name=Varita del Piromano Aprendiz -item.wizardry:apprentice_ice_wand.name=Varita del Mago de Hielo Aprendiz -item.wizardry:apprentice_lightning_wand.name=Varita del Mago de Tormenta Aprendiz -item.wizardry:apprentice_necromancy_wand.name=Varita del Nigromante Aprendiz -item.wizardry:apprentice_earth_wand.name=Varita del Mago de Tierra Aprendiz -item.wizardry:apprentice_sorcery_wand.name=Varita del Hechicero Aprendiz -item.wizardry:apprentice_healing_wand.name=Varita del Sanador Aprendiz +item.apprenticeFireWand.name=Varita del Piromano Aprendiz +item.apprenticeIceWand.name=Varita del Mago de Hielo Aprendiz +item.apprenticeLightningWand.name=Varita del Mago de Tormenta Aprendiz +item.apprenticeNecromancyWand.name=Varita del Nigromante Aprendiz +item.apprenticeEarthWand.name=Varita del Mago de Tierra Aprendiz +item.apprenticeSorceryWand.name=Varita del Hechicero Aprendiz +item.apprenticeHealingWand.name=Varita del Sanador Aprendiz -item.wizardry:advanced_fire_wand.name=Varita del Piromano -item.wizardry:advanced_ice_wand.name=Varita del Mago de Hielo -item.wizardry:advanced_lightning_wand.name=Varita del Mago de Tormenta -item.wizardry:advanced_necromancy_wand.name=Varita del Nigromante -item.wizardry:advanced_earth_wand.name=Varita del Mago de Tierra -item.wizardry:advanced_sorcery_wand.name=Varita del Hechicero -item.wizardry:advanced_healing_wand.name=Varita del Sanador +item.advancedFireWand.name=Varita del Piromano +item.advancedIceWand.name=Varita del Mago de Hielo +item.advancedLightningWand.name=Varita del Mago de Tormenta +item.advancedNecromancyWand.name=Varita del Nigromante +item.advancedEarthWand.name=Varita del Mago de Tierra +item.advancedSorceryWand.name=Varita del Hechicero +item.advancedHealingWand.name=Varita del Sanador -item.wizardry:master_fire_wand.name=Varita del Piromano Maestro -item.wizardry:master_ice_wand.name=Varita del Mago de Hielo Maestro -item.wizardry:master_lightning_wand.name=Varita del Mago de Tormenta Maestro -item.wizardry:master_necromancy_wand.name=Varita del Nigromante Maestro -item.wizardry:master_earth_wand.name=Varita del Mago de Tierra Maestro -item.wizardry:master_sorcery_wand.name=Varita del Hechicero Maestro -item.wizardry:master_healing_wand.name=Varita del Sanador Maestro +item.masterFireWand.name=Varita del Piromano Maestro +item.masterIceWand.name=Varita del Mago de Hielo Maestro +item.masterLightningWand.name=Varita del Mago de Tormenta Maestro +item.masterNecromancyWand.name=Varita del Nigromante Maestro +item.masterEarthWand.name=Varita del Mago de Tierra Maestro +item.masterSorceryWand.name=Varita del Hechicero Maestro +item.masterHealingWand.name=Varita del Sanador Maestro -item.wizardry:spectral_sword.name=Espada Espectral -item.wizardry:spectral_pickaxe.name=Pico Espectral -item.wizardry:spectral_bow.name=Arco Espectral +item.spectralSword.name=Espada Espectral +item.spectralPickaxe.name=Pico Espectral +item.spectralBow.name=Arco Espectral -item.wizardry:mana_flask.name=Frasco de Mana -item.wizardry:storage_upgrade.name=Mejora de Almacenamiento para Varita -item.wizardry:siphon_upgrade.name=Mejora de Sifon para Varita -item.wizardry:condenser_upgrade.name=Mejora de Condensador para Varita -item.wizardry:range_upgrade.name=Mejora de Rango para Varita -item.wizardry:duration_upgrade.name=Mejora de Duracion para Varita -item.wizardry:cooldown_upgrade.name=Mejora de Tiempo de Reactivacion para Varita -item.wizardry:blast_upgrade.name=Mejora de Explosion para Varita -item.wizardry:attunement_upgrade.name=Mejora de Sintonizacion para Varita +item.manaFlask.name=Frasco de Mana +item.storageUpgrade.name=Mejora de Almacenamiento para Varita +item.siphonUpgrade.name=Mejora de Sifon para Varita +item.condenserUpgrade.name=Mejora de Condensador para Varita +item.rangeUpgrade.name=Mejora de Rango para Varita +item.durationUpgrade.name=Mejora de Duracion para Varita +item.cooldownUpgrade.name=Mejora de Tiempo de Reactivacion para Varita +item.blastUpgrade.name=Mejora de Explosion para Varita +item.attunementUpgrade.name=Mejora de Sintonizacion para Varita -item.wizardry:flaming_axe.name=Hacha Llameante -item.wizardry:frost_axe.name=Hacha Escarchada +item.flamingAxe.name=Hacha Llameante +item.frostAxe.name=Hacha Escarchada -item.wizardry:firebomb.name=Bomba de fuego -item.wizardry:poison_bomb.name=Bomba de veneno -item.wizardry:smoke_bomb.name=Bomba de humo +item.firebomb.name=Bomba de fuego +item.poisonBomb.name=Bomba de veneno +item.smoke_bomb.name=Bomba de humo -item.wizardry:blank_scroll.name=Pergamino en blanco -item.wizardry:scroll.name=Pergamino de %1$s -item.wizardry:scroll.undiscovered.name=Pergamino "%1$s" -item.wizardry:identification_scroll.name=Pergamino de la Identificacion -item.wizardry:identification_scroll.desc1=%1$sIdentifica un libro o pergamino -item.wizardry:identification_scroll.desc2=%1$sdesconocido -item.wizardry:identification_scroll.nothing_to_identify=Nada que identificar! +item.blankScroll.name=Pergamino en blanco +item.scroll.name=Pergamino de %1$s +item.scroll.undiscovered.name=Pergamino "%1$s" +item.identification_scroll.name=Pergamino de la Identificacion +item.identification_scroll.desc1=%1$sIdentifica un libro o pergamino +item.identification_scroll.desc2=%1$sdesconocido +item.identification_scroll.nothing_to_identify=Nada que identificar! -item.wizardry:armour_upgrade.name=Sello Arcano de la Proteccion -item.wizardry:armour_upgrade.desc1=%1$sMejora cualquier armadura -item.wizardry:armour_upgrade.desc2=%1$spara volverla %2$slegendaria +item.armourUpgrade.name=Sello Arcano de la Proteccion +item.armourUpgrade.desc1=%1$sMejora cualquier armadura +item.armourUpgrade.desc2=%1$spara volverla %2$slegendaria -item.wizardry:magic_silk.name=Seda Magica +item.magicSilk.name=Seda Magica -item.wizardry:wizard_armour.legendary=Legendario -item.wizardry:wizard_armour.buff=-%1$s %2$s costo -item.wizardry:wizard_armour.mana=Mana: %1$s/%2$s +item.wizardArmour.legendary=Legendario +item.wizardArmour.buff=-%1$s %2$s costo +item.wizardArmour.mana=Mana: %1$s/%2$s -item.wizardry:wizard_hat.name=Sombrero de Mago -item.wizardry:wizard_robe.name=Tunica de Mago -item.wizardry:wizard_leggings.name=Pantalones de Mago -item.wizardry:wizard_boots.name=Botas de Mago +item.wizard_hat.name=Sombrero de Mago +item.wizard_robe.name=Tunica de Mago +item.wizard_leggings.name=Pantalones de Mago +item.wizard_boots.name=Botas de Mago -item.wizardry:wizard_hat_fire.name=Sombrero de Piromano -item.wizardry:wizard_robe_fire.name=Tunica de Piromano -item.wizardry:wizard_leggings_fire.name=Pantalones de Piromano -item.wizardry:wizard_boots_fire.name=Botas de Piromano +item.wizard_hat_fire.name=Sombrero de Piromano +item.wizard_robe_fire.name=Tunica de Piromano +item.wizard_leggings_fire.name=Pantalones de Piromano +item.wizard_boots_fire.name=Botas de Piromano -item.wizardry:wizard_hat_ice.name=Sombrero de Mago de Hielo -item.wizardry:wizard_robe_ice.name=Tunica de Mago de Hielo -item.wizardry:wizard_leggings_ice.name=Pantalones de Mago de Hielo -item.wizardry:wizard_boots_ice.name=Botas de Mago de Hielo +item.wizard_hat_ice.name=Sombrero de Mago de Hielo +item.wizard_robe_ice.name=Tunica de Mago de Hielo +item.wizard_leggings_ice.name=Pantalones de Mago de Hielo +item.wizard_boots_ice.name=Botas de Mago de Hielo -item.wizardry:wizard_hat_lightning.name=Sombrero de Mago de Tormenta -item.wizardry:wizard_robe_lightning.name=Tunica de Mago de Tormenta -item.wizardry:wizard_leggings_lightning.name=Pantalones de Mago de Tormenta -item.wizardry:wizard_boots_lightning.name=Botas de Mago de Tormenta +item.wizard_hat_lightning.name=Sombrero de Mago de Tormenta +item.wizard_robe_lightning.name=Tunica de Mago de Tormenta +item.wizard_leggings_lightning.name=Pantalones de Mago de Tormenta +item.wizard_boots_lightning.name=Botas de Mago de Tormenta -item.wizardry:wizard_hat_necromancy.name=Sombrero de Nigromante -item.wizardry:wizard_robe_necromancy.name=Tunica de Nigromante -item.wizardry:wizard_leggings_necromancy.name=Pantalones de Nigromante -item.wizardry:wizard_boots_necromancy.name=Botas de Nigromante +item.wizard_hat_necromancy.name=Sombrero de Nigromante +item.wizard_robe_necromancy.name=Tunica de Nigromante +item.wizard_leggings_necromancy.name=Pantalones de Nigromante +item.wizard_boots_necromancy.name=Botas de Nigromante -item.wizardry:wizard_hat_earth.name=Sombrero de Mago de Tierra -item.wizardry:wizard_robe_earth.name=Tunica de Mago de Tierra -item.wizardry:wizard_leggings_earth.name=Pantalones de Mago de Tierra -item.wizardry:wizard_boots_earth.name=Botas de Mago de Tierra +item.wizard_hat_earth.name=Sombrero de Mago de Tierra +item.wizard_robe_earth.name=Tunica de Mago de Tierra +item.wizard_leggings_earth.name=Pantalones de Mago de Tierra +item.wizard_boots_earth.name=Botas de Mago de Tierra -item.wizardry:wizard_hat_sorcery.name=Sombrero de Hechicero -item.wizardry:wizard_robe_sorcery.name=Tunica de Hechicero -item.wizardry:wizard_leggings_sorcery.name=Pantalones de Hechicero -item.wizardry:wizard_boots_sorcery.name=Botas de Hechicero +item.wizard_hat_sorcery.name=Sombrero de Hechicero +item.wizard_robe_sorcery.name=Tunica de Hechicero +item.wizard_leggings_sorcery.name=Pantalones de Hechicero +item.wizard_boots_sorcery.name=Botas de Hechicero -item.wizardry:wizard_hat_healing.name=Sombrero de Sanador -item.wizardry:wizard_robe_healing.name=Tunica de Sanador -item.wizardry:wizard_leggings_healing.name=Pantalones de Sanador -item.wizardry:wizard_boots_healing.name=Botas de Sanador +item.wizard_hat_healing.name=Sombrero de Sanador +item.wizard_robe_healing.name=Tunica de Sanador +item.wizard_leggings_healing.name=Pantalones de Sanador +item.wizard_boots_healing.name=Botas de Sanador -item.wizardry:spawn_wizard.name=Invocar Mago -item.wizardry:spawn_evil_wizard.name=Invocar Mago Malvado +item.spawn_wizard.name=Invocar Mago +item.spawn_evil_wizard.name=Invocar Mago Malvado -item.wizardry:spectral_helmet.name=Casco Espectral -item.wizardry:spectral_chestplate.name=Pechera Espectral -item.wizardry:spectral_leggings.name=Grebas Espectrales -item.wizardry:spectral_boots.name=Botas Espectrales +item.spectral_helmet.name=Casco Espectral +item.spectral_chestplate.name=Pechera Espectral +item.spectral_leggings.name=Grebas Espectrales +item.spectral_boots.name=Botas Espectrales entity.wizardry.summonedcreature.nameplate=%2$s de %1$s -entity.wizardry.zombie_minion.name=Zombi -entity.wizardry.skeleton_minion.name=Esqueleto -entity.wizardry.spider_minion.name=Arana -entity.wizardry.blaze_minion.name=Blaze -entity.wizardry.ice_wraith.name=Espectro de Hielo -entity.wizardry.lightning_wraith.name=Espectro de Relampago -entity.wizardry.shadow_wraith.name=Espectro de las Sombras -entity.wizardry.spirit_wolf.name=Lobo Espiritual -entity.wizardry.spirit_horse.name=Caballo Espiritual -entity.wizardry.ice_giant.name=Gigante de Hielo -entity.wizardry.phoenix.name=Fenix -entity.wizardry.wizard.name=Mago -entity.wizardry.magic_slime.name=Slime Magico -entity.wizardry.silverfish_minion.name=Lepisma -entity.wizardry.storm_elemental.name=Elemental de Tormenta -entity.wizardry.evil_wizard.name=Mago Malvado -entity.wizardry.decoy.name=Senuelo +entity.wizardry.Zombie Minion.name=Zombi +entity.wizardry.Skeleton Minion.name=Esqueleto +entity.wizardry.Spider Minion.name=Arana +entity.wizardry.Blaze Minion.name=Blaze +entity.wizardry.Ice Wraith.name=Espectro de Hielo +entity.wizardry.Lightning Wraith.name=Espectro de Relampago +entity.wizardry.Shadow Wraith.name=Espectro de las Sombras +entity.wizardry.Spirit Wolf.name=Lobo Espiritual +entity.wizardry.Spirit Horse.name=Caballo Espiritual +entity.wizardry.Ice Giant.name=Gigante de Hielo +entity.wizardry.Phoenix.name=Fenix +entity.wizardry.Wizard.name=Mago +entity.wizardry.Magic Slime.name=Slime Magico +entity.wizardry.Silverfish Minion.name=Lepisma +entity.wizardry.Storm Elemental.name=Elemental de Tormenta +entity.wizardry.Evil Wizard.name=Mago Malvado +entity.wizardry.Decoy.name=Senuelo -entity.wizardry.magic_missile.name=Magia -entity.wizardry.arc.name=Magia -entity.wizardry.spark_bomb.name=Magia -entity.wizardry.ice_shard.name=Magia -entity.wizardry.firebomb.name=Magic -entity.wizardry.poison_bomb.name=Magia -entity.wizardry.force_orb.name=Magia -entity.wizardry.spark.name=Magia -entity.wizardry.darkness_orb.name=Magia -entity.wizardry.fire_sigil.name=Magia -entity.wizardry.frost_sigil.name=Magia -entity.wizardry.lightning_sigil.name=Magia -entity.wizardry.lightning_arrow.name=Magia -entity.wizardry.firebolt.name=Magia -entity.wizardry.ice_charge.name=Magia -entity.wizardry.force_arrow.name=Magia -entity.wizardry.dart.name=Magia -entity.wizardry.lightning_disc.name=Magia -entity.wizardry.thunderbolt.name=Magia -entity.wizardry.decay.name=Magia -entity.wizardry.ice_lance.name=Magia -entity.wizardry.smoke_bomb.name=Magia -entity.wizardry.ice_spike.name=Magia +entity.wizardry.Magic Missile.name=Magia +entity.wizardry.Arc.name=Magia +entity.wizardry.Spark Bomb.name=Magia +entity.wizardry.Ice Shard.name=Magia +entity.wizardry.Firebomb.name=Magic +entity.wizardry.Poison Bomb.name=Magia +entity.wizardry.Force Orb.name=Magia +entity.wizardry.Spark.name=Magia +entity.wizardry.Darkness Orb.name=Magia +entity.wizardry.Fire Sigil.name=Magia +entity.wizardry.Frost Sigil.name=Magia +entity.wizardry.Lightning Sigil.name=Magia +entity.wizardry.Lightning Arrow.name=Magia +entity.wizardry.Firebolt.name=Magia +entity.wizardry.Ice Charge.name=Magia +entity.wizardry.Force Arrow.name=Magia +entity.wizardry.Dart.name=Magia +entity.wizardry.Lightning Disc.name=Magia +entity.wizardry.Thunderbolt.name=Magia +entity.wizardry.Decay.name=Magia +entity.wizardry.Ice Lance.name=Magia +entity.wizardry.Smoke Bomb.name=Magia +entity.wizardry.Ice Spike.name=Magia -entity.wizardry.black_hole.name=Agujero Negro -entity.wizardry.shield.name=Escudo -entity.wizardry.meteor.name=Meteoro -entity.wizardry.blizzard.name=Ventisca -entity.wizardry.bubble.name=Burbuja -entity.wizardry.tornado.name=Tornado -entity.wizardry.lightning_hammer.name=Martillo Relampago -entity.wizardry.arrow_rain.name=Lluvia de Flechas -entity.wizardry.healing_aura.name=Aura Curador -entity.wizardry.forcefield.name=Campo de Fuerza -entity.wizardry.ring_of_fire.name=Anillo de Fuego -entity.wizardry.earthquake.name=Terremoto -entity.wizardry.falling_grass.name=Hierba Descendiente -entity.wizardry.hailstorm.name=Tormenta de Granizo -entity.wizardry.lightning_pulse.name=Pulso de Relampago +entity.wizardry.Black Hole.name=Agujero Negro +entity.wizardry.Shield.name=Escudo +entity.wizardry.Meteor.name=Meteoro +entity.wizardry.Blizzard.name=Ventisca +entity.wizardry.Bubble.name=Burbuja +entity.wizardry.Tornado.name=Tornado +entity.wizardry.Lightning Hammer.name=Martillo Relampago +entity.wizardry.Arrow Rain.name=Lluvia de Flechas +entity.wizardry.Healing Aura.name=Aura Curador +entity.wizardry.Forcefield.name=Campo de Fuerza +entity.wizardry.Ring of Fire.name=Anillo de Fuego +entity.wizardry.Earthquake.name=Terremoto +entity.wizardry.Falling Grass.name=Hierba Descendiente +entity.wizardry.Hailstorm.name=Tormenta de Granizo +entity.wizardry.Lightning Pulse.name=Pulso de Relampago -item_group.wizardry=Wizardry -item_group.wizardryspells=Hechizos de Wizardry +itemGroup.wizardry=Wizardry +itemGroup.wizardryspells=Hechizos de Wizardry -achievement.crystal=Un Cristral Curioso... -achievement.crystal.desc=Pica un Cristal Magico -achievement.arcane_initiate=Inicio Arcano -achievement.arcane_initiate.desc=Craftea una varita magica con una pepita de oro, un palo y un cristal magico -achievement.apprentice=Aprendiz de Mago -achievement.apprentice.desc=Usa un tomo de lo arcano para mejorar tu varita -achievement.master=Maestro Arcano -achievement.master.desc=Obten una varita de maestro -achievement.all_spells=Mago de Todos los Oficios -achievement.all_spells.desc=Lanza todos los hechizos disponibles -achievement.wizard_trade=Comercio Magico -achievement.wizard_trade.desc=Compra un objeto a un mago -achievement.buy_master_spell=El Conocimiento es Poder -achievement.buy_master_spell.wizardry:desc=Compra un hechizo maestro a un mago -achievement.freeze_blaze=Ya No Estas Tan Caliente -achievement.freeze_blaze.desc=Congela a un blaze -achievement.charge_creeper=Va a Explotar!! -achievement.charge_creeper.desc='Accidentalmente' carga un creeper -achievement.frankenstein=Frankenstein -achievement.frankenstein.desc=Convierte a un cerdo en un hombrecerdo zombi usando el hechizo de rayo -achievement.special_upgrade=Remiendo Arcano -achievement.special_upgrade.desc=Aplica una mejora a una varita -achievement.craft_flask=Es Magia, Embotellada! -achievement.craft_flask.desc=Craftea un frasco de mana -achievement.elemental=Elemental -achievement.elemental.desc=Obten una varita elemental -achievement.armour_set=Now Eres un Mago Apropiado -achievement.armour_set.desc=Craftea y equipa el set completo de armadura de mago -achievement.legendary=Legendario -achievement.legendary.desc=Obten una pieza de armadura de mago legendaria -achievement.self_destruct=Tiro por la culata -achievement.self_destruct.desc=Muere por tu propia magia -achievement.pig_tornado=No De Nuevo... -achievement.pig_tornado.desc=Monta un cerdo hacia un tornado -achievement.jam_wizard=Sesion de Interferencia -achievement.jam_wizard.desc=Usa el hechizo arcano de interferencia en un mago -achievement.slime_skeleton=Situacion Pegajosa -achievement.slime_skeleton.desc=Sumerge un esqueleto en slime -achievement.anger_wizard=Te Arrepentiras de Eso -achievement.anger_wizard.desc=Haz que un mago se enoje -achievement.defeat_evil_wizard=Justicia -achievement.defeat_evil_wizard.desc=Derrota a un mago malvado -achievement.max_out_wand=Equipada Al Maximo! -achievement.max_out_wand.desc=Aplica el maximo numero de mejoras a una varita maestra -achievement.element_master=Maestria Elemental -achievement.element_master.desc=Lanza todos los hechizos de cualquier elemento -achievement.identify_spell=Apreciacion Arcana -achievement.identify_spell.wizardry:desc=Usa un pergamino de la identificacion para identificar un libro de hechizos o pergamino +achievement.Crystal=Un Cristral Curioso... +achievement.Crystal.desc=Pica un Cristal Magico +achievement.ArcaneInitiate=Inicio Arcano +achievement.ArcaneInitiate.desc=Craftea una varita magica con una pepita de oro, un palo y un cristal magico +achievement.Apprentice=Aprendiz de Mago +achievement.Apprentice.desc=Usa un tomo de lo arcano para mejorar tu varita +achievement.Master=Maestro Arcano +achievement.Master.desc=Obten una varita de maestro +achievement.AllSpells=Mago de Todos los Oficios +achievement.AllSpells.desc=Lanza todos los hechizos disponibles +achievement.WizardTrade=Comercio Magico +achievement.WizardTrade.desc=Compra un objeto a un mago +achievement.BuyMasterSpell=El Conocimiento es Poder +achievement.BuyMasterSpell.desc=Compra un hechizo maestro a un mago +achievement.FreezeBlaze=Ya No Estas Tan Caliente +achievement.FreezeBlaze.desc=Congela a un blaze +achievement.ChargeCreeper=Va a Explotar!! +achievement.ChargeCreeper.desc='Accidentalmente' carga un creeper +achievement.Frankenstein=Frankenstein +achievement.Frankenstein.desc=Convierte a un cerdo en un hombrecerdo zombi usando el hechizo de rayo +achievement.SpecialUpgrade=Remiendo Arcano +achievement.SpecialUpgrade.desc=Aplica una mejora a una varita +achievement.CraftFlask=Es Magia, Embotellada! +achievement.CraftFlask.desc=Craftea un frasco de mana +achievement.Elemental=Elemental +achievement.Elemental.desc=Obten una varita elemental +achievement.ArmourSet=Now Eres un Mago Apropiado +achievement.ArmourSet.desc=Craftea y equipa el set completo de armadura de mago +achievement.Legendary=Legendario +achievement.Legendary.desc=Obten una pieza de armadura de mago legendaria +achievement.SelfDestruct=Tiro por la culata +achievement.SelfDestruct.desc=Muere por tu propia magia +achievement.PigTornado=No De Nuevo... +achievement.PigTornado.desc=Monta un cerdo hacia un tornado +achievement.JamWizard=Sesion de Interferencia +achievement.JamWizard.desc=Usa el hechizo arcano de interferencia en un mago +achievement.SlimeSkeleton=Situacion Pegajosa +achievement.SlimeSkeleton.desc=Sumerge un esqueleto en slime +achievement.AngerWizard=Te Arrepentiras de Eso +achievement.AngerWizard.desc=Haz que un mago se enoje +achievement.DefeatEvilWizard=Justicia +achievement.DefeatEvilWizard.desc=Derrota a un mago malvado +achievement.MaxOutWand=Equipada Al Maximo! +achievement.MaxOutWand.desc=Aplica el maximo numero de mejoras a una varita maestra +achievement.ElementMaster=Maestria Elemental +achievement.ElementMaster.desc=Lanza todos los hechizos de cualquier elemento +achievement.IdentifySpell=Apreciacion Arcana +achievement.IdentifySpell.desc=Usa un pergamino de la identificacion para identificar un libro de hechizos o pergamino -tile.wizardry:transportation_stone.confirm=A partir de ahora retornaras a este lugar cuando lances %1$s -tile.wizardry:transportation_stone.invalid=Primero debes hacer un circulo con 8 piedras de transportacion! +tile.transportationStone.confirm=A partir de ahora retornaras a este lugar cuando lances %1$s +tile.transportationStone.invalid=Primero debes hacer un circulo con 8 piedras de transportacion! -container.wizardry:arcane_workbench=Mesa de Trabajo Arcana -container.wizardry:arcane_workbench.apply=Aplicar -container.wizardry:arcane_workbench.mana=Mana: -container.wizardry:arcane_workbench.upgrades=Mejoras Aplicadas: +container.arcaneWorkbench=Mesa de Trabajo Arcana +container.arcaneWorkbench.apply=Aplicar +container.arcaneWorkbench.mana=Mana: +container.arcaneWorkbench.upgrades=Mejoras Aplicadas: tier.basic=Novato tier.apprentice=Aprendiz @@ -300,437 +300,470 @@ spell.disabled=%1$s ha sido desactivado en la configuracion spell.resist=%1$s resistio %2$s spell.discover=Descubrio el hechizo %1$s! -spell.wizardry:agility=Agilidad -spell.wizardry:arc=Arco Electrico -spell.wizardry:arcane_jammer=Perturbador Arcano -spell.wizardry:arrow_rain=Lluvia de Flechas -spell.wizardry:banish=Desaparecer -spell.wizardry:black_hole=Agujero Negro -spell.wizardry:blink=Parpadeo -spell.wizardry:blizzard=Ventisca -spell.wizardry:bubble=Burbuja -spell.wizardry:chain_lightning=Cadena de Rayos -spell.wizardry:clairvoyance=Clarividencia -spell.wizardry:cobwebs=Telas de Araña -spell.wizardry:conjure_armour=Conjurar Armadura -spell.wizardry:conjure_bow=Conjurar Arco -spell.wizardry:conjure_pickaxe=Conjurar Pico -spell.wizardry:conjure_sword=Conjurar Espada -spell.wizardry:cure_effects=Purificar Efectos -spell.wizardry:curse_of_soulbinding=Maldicion de Atadura al Alma -spell.wizardry:darkness_orb=Orbe de la Oscuridad -spell.wizardry:darkvision=Vision Oscura -spell.wizardry:dart=Dardo -spell.wizardry:decay=Deterioro -spell.wizardry:decoy=Senuelo -spell.wizardry:detonate=Detonar -spell.wizardry:diamondflesh=Piel de Diamante -spell.wizardry:earthquake=Terremoto -spell.wizardry:entrapment=Atrapamiento -spell.wizardry:fireball=Bola de Fuego -spell.wizardry:firebolt=Disparo de Fuego -spell.wizardry:firebomb=Bomba de Fuego -spell.wizardry:fire_resistance=Resistencia al Fuego -spell.wizardry:fire_sigil=Sigilo de Fuego -spell.wizardry:fireskin=Piel de Fuego -spell.wizardry:firestorm=Tormenta de Fuego -spell.wizardry:flame_ray=Rayo de Fuego -spell.wizardry:flaming_axe=Hacha Llameante -spell.wizardry:flaming_weapon=Arma Llameante -spell.wizardry:flight=Vuelo -spell.wizardry:font_of_mana=Fuente de Mana -spell.wizardry:font_of_vitality=Fuente de Vitalidad -spell.wizardry:force_arrow=Flecha de Fuerza -spell.wizardry:forcefield=Campo de Fuerza -spell.wizardry:force_orb=Orbe de Fuerza -spell.wizardry:forests_curse=Maldicion del Bosque -spell.wizardry:freeze=Congelar -spell.wizardry:freezing_weapon=Arma Congelante -spell.wizardry:frost_axe=Hacha Escarchada -spell.wizardry:frost_ray=Rayo de Escarcha -spell.wizardry:frost_sigil=Sigilo de Escarcha -spell.wizardry:glide=Planear -spell.wizardry:greater_fireball=Bola de Fuego Mayor -spell.wizardry:greater_heal=Curacion Mayor -spell.wizardry:group_heal=Curacion Grupal -spell.wizardry:growth_aura= Aura de Crecimiento -spell.wizardry:hailstorm=Tormenta de Granizo -spell.wizardry:heal=Curar -spell.wizardry:heal_ally=curar Aliado -spell.wizardry:healing_aura=Aura de Curacion -spell.wizardry:homing_spark=Chispa Dirigida -spell.wizardry:ice_age=Era de Hielo -spell.wizardry:ice_charge=Carga de Hielo -spell.wizardry:ice_lance=Lanza de Hielo -spell.wizardry:ice_shard=Fragmento de Hielo -spell.wizardry:ice_shroud=Velo de Hielo -spell.wizardry:ice_spikes=Pinchos de Hielo -spell.wizardry:ice_statue=Estatua de Hielo -spell.wizardry:ignite=Encender -spell.wizardry:imbue_weapon=Imbuir Arma -spell.wizardry:intimidate=Intimidar -spell.wizardry:invigorating_presence=Presencia Vigorizante -spell.wizardry:invisibility=Invisibilidad -spell.wizardry:invoke_weather=Invocar clima -spell.wizardry:ironflesh=Piel de Hierro -spell.wizardry:leap=Salto -spell.wizardry:levitation=Levitacion -spell.wizardry:life_drain=Drenaje de Vida -spell.wizardry:light=Luz -spell.wizardry:lightning_arrow=Flecha de Rayo -spell.wizardry:lightning_bolt=Disparo de Rayo -spell.wizardry:lightning_disc=Disco de Rayo -spell.wizardry:lightning_hammer=Martillo Relampago -spell.wizardry:lightning_pulse=Pulso Electrico -spell.wizardry:lightning_ray=Rayo Electrico -spell.wizardry:lightning_sigil=Sigilo Electrico -spell.wizardry:lightning_web=Red Electrica -spell.wizardry:magic_missile=Misil Magico -spell.wizardry:metamorphosis=Metamorfosis -spell.wizardry:meteor=Meteoro -spell.wizardry:mind_control=Control Mental -spell.wizardry:mind_trick=Truco Mental -spell.wizardry:none=[Espacio Vacio] -spell.wizardry:oakflesh=Piel de Roble -spell.wizardry:petrify=Petrificar -spell.wizardry:phase_step=Paso de Fase -spell.wizardry:plague_of_darkness=Plaga de la Oscuridad -spell.wizardry:pocket_furnace=Horno del Bolsillo -spell.wizardry:pocket_workbench=Mesa de Trabajo de Bolsillo -spell.wizardry:poison=Veneno -spell.wizardry:poison_bomb=Bomba de Veneno -spell.wizardry:replenish_hunger=Rellenar hambre -spell.wizardry:ring_of_fire=Anillo de Fuego -spell.wizardry:shadow_ward=Guarda de las Sombras -spell.wizardry:shield=Escudo -spell.wizardry:shockwave=Onda de Choque -spell.wizardry:silverfish_swarm=Emjambre de Lepismas -spell.wizardry:sixth_sense=Sexto Sentido -spell.wizardry:slime=Slime -spell.wizardry:smoke_bomb=Bomba de Humo -spell.wizardry:snare=Trampa -spell.wizardry:snowball=Bola de Nieve -spell.wizardry:spark_bomb=Bomba de Chispa -spell.wizardry:spectral_pathway=Camino Espectral -spell.wizardry:spider_swarm=Emjambre de Arañas -spell.wizardry:static_aura=Aura Estatica -spell.wizardry:summon_blaze=Invocar Blaze -spell.wizardry:summon_ice_giant=Invocar Gigante de Hielo -spell.wizardry:summon_ice_wraith=Invocar Espectro de Hielo -spell.wizardry:summon_iron_golem=Invocar Golem de Hierro -spell.wizardry:summon_lightning_wraith=Invocar Espectro de Rayo -spell.wizardry:summon_phoenix=Invocar Fenix -spell.wizardry:summon_shadow_wraith=Invocar Espectro de las Sombras -spell.wizardry:summon_skeleton=Invocar Esqueleto -spell.wizardry:summon_skeleton_legion=Invocar Legion de Esqueletos -spell.wizardry:summon_snow_golem=Invocar Golem de Nieve -spell.wizardry:summon_spirit_horse=Invocar Caballo Espiritual -spell.wizardry:summon_spirit_wolf=Invocar Lobo Espiritual -spell.wizardry:summon_storm_elemental=Invocar Elemental del Rayo -spell.wizardry:summon_wither_skeleton=Invocar Esqueleto del Wither -spell.wizardry:summon_zombie=Invocar Zombi -spell.wizardry:telekinesis=Telequinesis -spell.wizardry:thunderbolt=Rayo -spell.wizardry:thunderstorm=Tormenta Electrica -spell.wizardry:tornado=Tornado -spell.wizardry:transience=Transitoriedad -spell.wizardry:transportation=Transportacion -spell.wizardry:vanishing_box=Caja Desvaneciente -spell.wizardry:wall_of_frost=Pared de Escarcha -spell.wizardry:water_breathing=Respiracion Acuatica -spell.wizardry:whirlwind=Remolino de Viento -spell.wizardry:wither=Marchitar -spell.wizardry:wither_skull=Craneo de Wither +spell.agility=Agilidad +spell.arc=Arco Electrico +spell.arcane_jammer=Perturbador Arcano +spell.arrow_rain=Lluvia de Flechas +spell.banish=Desaparecer +spell.black_hole=Agujero Negro +spell.blink=Parpadeo +spell.blizzard=Ventisca +spell.bubble=Burbuja +spell.chain_lightning=Cadena de Rayos +spell.clairvoyance=Clarividencia +spell.cobwebs=Telas de Araña +spell.conjure_armour=Conjurar Armadura +spell.conjure_bow=Conjurar Arco +spell.conjure_pickaxe=Conjurar Pico +spell.conjure_sword=Conjurar Espada +spell.cure_effects=Purificar Efectos +spell.curse_of_soulbinding=Maldicion de Atadura al Alma +spell.darkness_orb=Orbe de la Oscuridad +spell.darkvision=Vision Oscura +spell.dart=Dardo +spell.decay=Deterioro +spell.decoy=Senuelo +spell.detonate=Detonar +spell.diamondflesh=Piel de Diamante +spell.earthquake=Terremoto +spell.entrapment=Atrapamiento +spell.fireball=Bola de Fuego +spell.firebolt=Disparo de Fuego +spell.firebomb=Bomba de Fuego +spell.fire_resistance=Resistencia al Fuego +spell.fire_sigil=Sigilo de Fuego +spell.fireskin=Piel de Fuego +spell.firestorm=Tormenta de Fuego +spell.flame_ray=Rayo de Fuego +spell.flaming_axe=Hacha Llameante +spell.flaming_weapon=Arma Llameante +spell.flight=Vuelo +spell.font_of_mana=Fuente de Mana +spell.font_of_vitality=Fuente de Vitalidad +spell.force_arrow=Flecha de Fuerza +spell.forcefield=Campo de Fuerza +spell.force_orb=Orbe de Fuerza +spell.forests_curse=Maldicion del Bosque +spell.freeze=Congelar +spell.freezing_weapon=Arma Congelante +spell.frost_axe=Hacha Escarchada +spell.frost_ray=Rayo de Escarcha +spell.frost_sigil=Sigilo de Escarcha +spell.glide=Planear +spell.greater_fireball=Bola de Fuego Mayor +spell.greater_heal=Curacion Mayor +spell.group_heal=Curacion Grupal +spell.growth_aura= Aura de Crecimiento +spell.hailstorm=Tormenta de Granizo +spell.heal=Curar +spell.heal_ally=curar Aliado +spell.healing_aura=Aura de Curacion +spell.homing_spark=Chispa Dirigida +spell.ice_age=Era de Hielo +spell.ice_charge=Carga de Hielo +spell.ice_lance=Lanza de Hielo +spell.ice_shard=Fragmento de Hielo +spell.ice_shroud=Velo de Hielo +spell.ice_spikes=Pinchos de Hielo +spell.ice_statue=Estatua de Hielo +spell.ignite=Encender +spell.imbue_weapon=Imbuir Arma +spell.intimidate=Intimidar +spell.invigorating_presence=Presencia Vigorizante +spell.invisibility=Invisibilidad +spell.invoke_weather=Invocar clima +spell.ironflesh=Piel de Hierro +spell.leap=Salto +spell.levitation=Levitacion +spell.life_drain=Drenaje de Vida +spell.light=Luz +spell.lightning_arrow=Flecha de Rayo +spell.lightning_bolt=Disparo de Rayo +spell.lightning_disc=Disco de Rayo +spell.lightning_hammer=Martillo Relampago +spell.lightning_pulse=Pulso Electrico +spell.lightning_ray=Rayo Electrico +spell.lightning_sigil=Sigilo Electrico +spell.lightning_web=Red Electrica +spell.magic_missile=Misil Magico +spell.metamorphosis=Metamorfosis +spell.meteor=Meteoro +spell.mind_control=Control Mental +spell.mind_trick=Truco Mental +spell.none=[Espacio Vacio] +spell.oakflesh=Piel de Roble +spell.petrify=Petrificar +spell.phase_step=Paso de Fase +spell.plague_of_darkness=Plaga de la Oscuridad +spell.pocket_furnace=Horno del Bolsillo +spell.pocket_workbench=Mesa de Trabajo de Bolsillo +spell.poison=Veneno +spell.poison_bomb=Bomba de Veneno +spell.replenish_hunger=Rellenar hambre +spell.ring_of_fire=Anillo de Fuego +spell.shadow_ward=Guarda de las Sombras +spell.shield=Escudo +spell.shockwave=Onda de Choque +spell.silverfish_swarm=Emjambre de Lepismas +spell.sixth_sense=Sexto Sentido +spell.slime=Slime +spell.smoke_bomb=Bomba de Humo +spell.snare=Trampa +spell.snowball=Bola de Nieve +spell.spark_bomb=Bomba de Chispa +spell.spectral_pathway=Camino Espectral +spell.spider_swarm=Emjambre de Arañas +spell.static_aura=Aura Estatica +spell.summon_blaze=Invocar Blaze +spell.summon_ice_giant=Invocar Gigante de Hielo +spell.summon_ice_wraith=Invocar Espectro de Hielo +spell.summon_iron_golem=Invocar Golem de Hierro +spell.summon_lightning_wraith=Invocar Espectro de Rayo +spell.summon_phoenix=Invocar Fenix +spell.summon_shadow_wraith=Invocar Espectro de las Sombras +spell.summon_skeleton=Invocar Esqueleto +spell.summon_skeleton_legion=Invocar Legion de Esqueletos +spell.summon_snow_golem=Invocar Golem de Nieve +spell.summon_spirit_horse=Invocar Caballo Espiritual +spell.summon_spirit_wolf=Invocar Lobo Espiritual +spell.summon_storm_elemental=Invocar Elemental del Rayo +spell.summon_wither_skeleton=Invocar Esqueleto del Wither +spell.summon_zombie=Invocar Zombi +spell.telekinesis=Telequinesis +spell.thunderbolt=Rayo +spell.thunderstorm=Tormenta Electrica +spell.tornado=Tornado +spell.transience=Transitoriedad +spell.transportation=Transportacion +spell.vanishing_box=Caja Desvaneciente +spell.wall_of_frost=Pared de Escarcha +spell.water_breathing=Respiracion Acuatica +spell.whirlwind=Remolino de Viento +spell.wither=Marchitar +spell.wither_skull=Craneo de Wither -spell.wizardry:agility.desc=Concede al mago velocidad de movimiento incrementada y un salto mas alto por 30 segundos. -spell.wizardry:arc.desc=Dispara una chispa de rayo al objetivo. -spell.wizardry:arcane_jammer.desc=No permite que el usuario use magia en los proximos 15 segundos. -spell.wizardry:arrow_rain.desc="Arqueros, disparen!" -spell.wizardry:banish.desc=Teletransporta al objetivo una posicion cercana aleatoria en contra de su voluntad. -spell.wizardry:black_hole.desc=Desgarra la realidad. -spell.wizardry:blink.desc=Teletransporta al mago a la posicion que estan apuntando. -spell.wizardry:blizzard.desc=Crea una zona de aire frio, la cual ralentiza y hiere continuamente a cualquiera en su interior. El creador del hechizo es inmune al dano pero no al efecto. -spell.wizardry:bubble.desc=Dispara un chorro de burbujas que causa que lo primero que toque flote hacia el cielo. La burbuja explota despues de un tiempo o si el objetivo es golpeado. -spell.wizardry:chain_lightning.desc=Dispara un relampago a un objetivo, el cual hace cadena con objetivos cercanos hasta dos veces. -spell.wizardry:clairvoyance.desc=Revela el camino hacia una localizacion guardada. Con este hechizo seleccionado, haga shift-clic derecho en un bloque para guardarlo. Lanza este hechizo para revelar el camino. El camino desaparecera despues de 90 segundos. -spell.wizardry:cobwebs.desc=Crea telas de arana en la direccion a la cual estas apuntando, lo cual limita la movilidad de tu objetivo. Las telas de arana despareceran en 20 segundos o si son rotas. -spell.wizardry:conjure_armour.desc=Crea Armadura Espectral alrededor del mago lo cual ofrece proteccion similar a la armadura de hierro. La armadura dura 60 segundos. El mago debe tener el espacio de armadura vacio. -spell.wizardry:conjure_bow.desc=Crea un Arco Espectral con flechas ilimitadas que dura 30 segundos. -spell.wizardry:conjure_pickaxe.desc=Crea un Pico Espectral con fuerza igual a la de un Pico de Hierro, el cual dura 30 segundos. -spell.wizardry:conjure_sword.desc=Crea una Espada Espectral con igual fuerza que una de hierro y dura 30 segundos. -spell.wizardry:cure_effects.desc=Purifica al usuario de todos los efectos de pocion, ya sean buenos o malos. -spell.wizardry:curse_of_soulbinding.desc=Provoca que el alma del objetivo esta ligada al del mago, lo que significa que todo el dano que recibe el mago lo recibe el objetivo. La maldicion dura hasta que uno de los dos muera. -spell.wizardry:darkness_orb.desc=Dispara una bala de energia oscura en la direccion que apuntes, la cual aplicar wither. -spell.wizardry:darkvision.desc=Concede vision nocturna por 45 segundos. -spell.wizardry:dart.desc=Dispara un dardo en la direccion que estas apuntando el cual hiere y debilita al objetivo. -spell.wizardry:decay.desc=Crea un pezado de deterioro en el suelo lo cual infecta y hiere a cualquier criatura que lo pise, tambien causa que estas criatura sigan esparciendo el deterioro por donde caminen. -spell.wizardry:decoy.desc=Crea un clon ilusorio del mago que atrae a los enemigos. El senuelo desaparecera en 30 segundos. -spell.wizardry:detonate.desc=Causa un explosion donde estes mirando, hiriendo a todas las criaturas cercanas - incluyendo al mago si se encuentra muy cerca. -spell.wizardry:diamondflesh.desc="Tus flechas no son nada contra mi!" -spell.wizardry:earthquake.desc=Un verdadero de Mago de Tierra puede mover montanas. -spell.wizardry:entrapment.desc=Atrpa al objetivo en una esfera de oscuridad que lo eleva y hiere continuamente. -spell.wizardry:fireball.desc=Lanza una bola de fuego en la direccion a la que apuntes. -spell.wizardry:firebolt.desc=Dispara un chorro de fuego a corta distancia en frente de ti. -spell.wizardry:firebomb.desc=Lanza una bomba de fuego, la cual detona cuando impacta quemando todo a su alrededor. -spell.wizardry:fire_resistance.desc=Concede resistencia al fuego al mago por 30 segundos. -spell.wizardry:fire_sigil.desc=Coloca una trampa de fuego que quema y hiere a la criatura que la pise. -spell.wizardry:fireskin.desc=Envuelve al mago en fuego por 30 segundos, provocando que cualquier que lo toque se queme. -spell.wizardry:firestorm.desc="Yo soy el dragon." -spell.wizardry:flame_ray.desc=Crea una corriente de llamas en la direccion a la que apuntas, la cual quema todo a su paso. -spell.wizardry:flaming_axe.desc=Crea una Hacha Llameante que quema a todos los enemigos que golpees. Dura 30 segundos. -spell.wizardry:flaming_weapon.desc=Imbuye con llamas la primera arma en el inventario del mago, la magia de deshace despues de 45 segundos. -spell.wizardry:flight.desc=Vuela como un aguila. -spell.wizardry:font_of_mana.desc="Fuimos llenados con una intensa energia magica que parecia emanar del centro del..." - Extraido del diario de un mago olvidado; el resto de la pagina esta quemada. -spell.wizardry:font_of_vitality.desc=Se siente increible. -spell.wizardry:force_arrow.desc=Dispara una flecha de fuerza en la direccion que apuntes. -spell.wizardry:forcefield.desc=Crea un campo de fuerza alrededor del mago que repele criaturas y proyectiles. -spell.wizardry:force_orb.desc=Lanza una esfera de fuerza que hiere y empuja criaturas cuando impacta. -spell.wizardry:forests_curse.desc="Como te atreves a entrar en mi bosque!" -spell.wizardry:freeze.desc=Congela al objetivo por 10 segundos. Tambien congela el agua y crea nieve en el suelo. -spell.wizardry:freezing_weapon.desc=Imbuye el poder del frio a la primera arma en el inventario del mago, provocando que el arma congela a sus objetivos. La magia deshace despues de 45 segundos. -spell.wizardry:frost_axe.desc=Crea un Hacha Escarchada la cual congela los enemigos que golpees. Dura 30 segundos. -spell.wizardry:frost_ray.desc=Crea un corriente de hielo en la direccion que apuntes la cual ralentiza y hiere continuamente al objetivo. -spell.wizardry:frost_sigil.desc=Coloca un trampa de hielo en el suelo el cual hiere y congela al cualquiera que la pise. -spell.wizardry:glide.desc=Permite que el mago planee en el aire. Debe mantenerse el boton presionado. -spell.wizardry:greater_fireball.desc=Lanza una bola de fuego de mayor tamano. -spell.wizardry:greater_heal.desc=Cura 4 corazones del mago. -spell.wizardry:group_heal.desc=Cura 3 corazones al mago, a aliados cercanos y a criaturas invocadas. -spell.wizardry:growth_aura.desc=Crece todos los cultivos cercanos al mago. Tambien hace crecer flores y hierba alta. -spell.wizardry:hailstorm.desc=Fue durante el Gran Invierno de la 3era Edad que los Magos de Hielo descubrieron su verdadero potencial. -spell.wizardry:heal.desc=Cura 2 corazones del usuario. -spell.wizardry:heal_ally.desc=Cura 2.5 corazones al objetivo. -spell.wizardry:healing_aura.desc=Crea una zona de energia curadora que regenera la salud de todos los alidados cercanos. Los No-_muertos dentro reciben dano. -spell.wizardry:homing_spark.desc=Crea una chispa flotante que persigue enemigos. -spell.wizardry:ice_age.desc="Seras congelado por toda la eternidad!" -spell.wizardry:ice_charge.desc=Lanza una carga de hielo que explota cuando impacta, congelando todas las criaturas y soltando fragmentos en todas las direcciones. -spell.wizardry:ice_lance.desc=Dispara una gran lanza de hielo en la direccion a la que estas apuntando, la cual atraviesa los objetivos hieriendo y congelandolos. -spell.wizardry:ice_shard.desc=Dispara un fragemento de hielo que hace dano y ralentiza -spell.wizardry:ice_shroud.desc=Cubre al mago con hielo, lo que ocasiona que cualquier que lo ataque sea congelado. -spell.wizardry:ice_spikes.desc=Causa que pinchos de hielo crezcan desde el suelo hiriendo a los enemigos. -spell.wizardry:ice_statue.desc=Congela al objetivo durante 20 segundos. El objetivo no se puede mover ni atacar pero tambien es inmune al dano. -spell.wizardry:ignite.desc=Quema al objetivo. Tambien funciona como un mechero. -spell.wizardry:imbue_weapon.desc=Imbuye la primera arma en el inventario con magia, haciendola mas efectiva. La magia se deshace despues de 45 segundos. -spell.wizardry:intimidate.desc=Emite un grunido intimidante el cual provoca que las criaturas espacen. -spell.wizardry:invigorating_presence.desc=Concede al mago y a los aliados cercanos fuerza incrementada por 45 segundos. -spell.wizardry:invisibility.desc=Le otorga invisibilidad al mago por 30 segundos. -spell.wizardry:invoke_weather.desc=Cambia el clima del mundo. -spell.wizardry:ironflesh.desc=Mejora grandemente la resistencia del mago por 30 segundos. -spell.wizardry:leap.desc=Causa que el mago salte alto y se mueve levemente hacia adelante. -spell.wizardry:levitation.desc=Levanta al mago hacia el cielo mientras el boton siga presionado. Si es usando antes de golpear el suelo, anula el dano por caida. -spell.wizardry:life_drain.desc=Crea una correinte de energia oscura que drena la vida de tu objetivo y te cura. -spell.wizardry:light.desc=Crea una esfera de luz que alumbra el area. Dura 30 segundos. -spell.wizardry:lightning_arrow.desc=Lanza una flecha electrificada en la direccion que apuntes. -spell.wizardry:lightning_bolt.desc=Causa que un trueno caiga en la direccion que apuntes. -spell.wizardry:lightning_disc.desc=Envia un disco electrico en la direccion que apuntes, el cual busca objetivos. -spell.wizardry:lightning_hammer.desc="Te golpeare con la ira de los cielos!" -spell.wizardry:lightning_pulse.desc=Carga el suelo cerca del mago con corriente electrica, hiriendo y repeliendo criaturas cercanas. -spell.wizardry:lightning_ray.desc=Crea una corriente de energia electrica que hiere a tus objetivos continuamente. -spell.wizardry:lightning_sigil.desc=Coloca una trampa electrificada que electrocuta a la criatura que la pise. -spell.wizardry:lightning_web.desc="Concentrare. Canaliza la tormenta en tu mente a traves de tu varita y liberala." -spell.wizardry:magic_missile.desc=Dispara una bala de energia magica. -spell.wizardry:metamorphosis.desc=Cambia la forma del objetivo. Solo funciona en algunas criaturas. -spell.wizardry:meteor.desc=Algunos magos solo quieren ver el mundo arder... -spell.wizardry:mind_control.desc=Toma control de la mente del objetivo por 30 segundos, provocando que cambie de bando y peleen a tu favor. No funciona con criaturas de voluntad muy fuerte. -spell.wizardry:mind_trick.desc=Confunde y desorienta al objetivo por 15 segundos, volviendolo incapaz de atacar. El efecto se desactiva si el objetivo recibe dano. -spell.wizardry:none.desc=Para obtener un libro de hechizo con el comando /give, usa la metadata: /give [player] wizardry:spell_book 1 [spell id] (_si encontraste este libro en un cofre significa que otro mod esta alterando las cosas). -spell.wizardry:oakflesh.desc=Mejora la resistencia del amgo durante 30 segundos. -spell.wizardry:petrify.desc=Convierte al objetivo en piedra hasta que se libere, con un chance de liberarse cuando se pone de noche. El objetivo no se puede mover ni atacar y no puede ser atacado. -spell.wizardry:phase_step.desc=Transporta al mago a traves de una pared de 1 bloque de grosor. El rango mejora el grosor por el cual te puedes transportar. -spell.wizardry:plague_of_darkness.desc=La Oscuridad los consumira a todos... -spell.wizardry:pocket_furnace.desc=Cocina 5 objetos en el inventario. Los objetos en la barra seran cocinados primero. -spell.wizardry:pocket_workbench.desc=Permite al mago craftear objetos. -spell.wizardry:poison.desc=Dispara veneno en la direccion que apuntes. -spell.wizardry:poison_bomb.desc=Lanza una bomba de veneno, la cual detona esparciendo mas veneno. -spell.wizardry:replenish_hunger.desc=Rellena 6 puntos de hambre del mago. -spell.wizardry:ring_of_fire.desc=Crea un anillo de fuego alrededor del mago, hiriendo y quemando a los objetivos cercanos. -spell.wizardry:shadow_ward.desc=Crea una pared de oscurdiad en frente del mago lo cual hace que la mitad del dano recibido sea aplicado al atacante. -spell.wizardry:shield.desc=Crea una barrera protectora que bloquea proyectiles y magia. Tambien concede al mago un efecto debil de resistencia. -spell.wizardry:shockwave.desc=Boom. -spell.wizardry:silverfish_swarm.desc="Ahhhh! Se estan multiplicando!!" -spell.wizardry:sixth_sense.desc=Le permite al mago sentir las criaturas cercanas a el, incluso a traves de paredes, durante 20 segundos. -spell.wizardry:slime.desc=Envuelve al objetivo en slime lo cual ralentiza y hiere continuamente. El slime explota despues de 10 segundos. -spell.wizardry:smoke_bomb.desc=Lanza una bomba de humo la cual explota cuando impacta. Creando una nube de humo y dandole ceguera a las criaturas en el area de impacto. -spell.wizardry:snare.desc=Coloca un trampa en el suelo que hiere y ralentiza al que la pise. -spell.wizardry:snowball.desc=Lanza una bola de nieve. -spell.wizardry:spark_bomb.desc=Lanza una bomba electrica que electrocuta a los objetivos cerca de su zona de impacto. -spell.wizardry:spectral_pathway.desc=Crea un puente magico indestructible al frente del mago que se extiende a 15 bloques. El puente desaperece luego de 60 segundos. -spell.wizardry:spider_swarm.desc=Invoca un emjambre de aranas venenosas. Desapareceran despues de 3o segundos o si son eliminadas. -spell.wizardry:static_aura.desc=Rodea al mago de electricidad durante 30 segundos, disparando chispa de rayo a cualquiera que lo golpee. -spell.wizardry:summon_blaze.desc=Invoca un Blaze que pelea por ti. El blaze desparecera despues de 30 segundos o si es derrotado. -spell.wizardry:summon_ice_giant.desc="Smash them!" -spell.wizardry:summon_ice_wraith.desc=Invoca un Espectro de Hielo que pelea por ti. El Espectro de Hielo desparecera despues de 30 segundos o si es derrotado. -spell.wizardry:summon_iron_golem.desc=Autómata autónomo automatizado automático. -spell.wizardry:summon_lightning_wraith.desc=Invoca un Espectro de Rayo que pelea por ti. El Espectro de Rayo desparecera despues de 30 segundos o si es derrotado. -spell.wizardry:summon_phoenix.desc=Desde las cenizas... -spell.wizardry:summon_shadow_wraith.desc=Invoca un Espectro de las Sombras que pelea por ti. -spell.wizardry:summon_skeleton.desc=Invoca un Esqueleto que pelea por ti. El esqueleto desparecera despues de 30 segundos o si es derrotado. -spell.wizardry:summon_skeleton_legion.desc="Levantate, Ejercito No-_muerto!" -spell.wizardry:summon_snow_golem.desc=Crea un Golem de Nieve que pelea por ti. Dura hasta que el golem muera. -spell.wizardry:summon_spirit_horse.desc=Invoca un Caballo Espectral para que lo montes. El caballo desparecera despues de que dure mucho tiempo sin ser montado o hagas shift-clic derecho con cualquier varita. -spell.wizardry:summon_spirit_wolf.desc=Invoca un Lobo Espiritual que pelea por ti. El lobo solo desparecera si es matado o haces shift-clic derecho con cualquier varita. -spell.wizardry:summon_storm_elemental.desc="Elemental de Rayo: Una manifestacion antigua de los elementos, difícilmente puede contener la energía que se agita dentro de el." - Guia del Mago sobre Entidades Arcanas, Volumen I_i -spell.wizardry:summon_wither_skeleton.desc=Invoca un Esqueleto del Wither que pelea por ti. El esqueleto del wither desparecera despues de 30 segundos o si es derrotado. -spell.wizardry:summon_zombie.desc=Invoca un Zombi que pelea por ti. El zombi desparecera despues de 30 segundos o si es derrotado. -spell.wizardry:telekinesis.desc=Mueve un item o un objeto pequeno hacia ti si haces clic derecho sobre el bloque. Tambien puede desarmar jugadores. -spell.wizardry:thunderbolt.desc=Dispara una bala de trueno que empuja los enemigos. -spell.wizardry:thunderstorm.desc="Mwahahahahahaha!" -spell.wizardry:tornado.desc=Libera un tornado en la direccion que mires, el cual atrae y levanta a todos las criaturas en su paso. -spell.wizardry:transience.desc=Hace que el mago transcienda, volviendo inmune a todo dano pero volviendo incapaz de atacar, interactuar o romper bloques -spell.wizardry:transportation.desc=Teletransporta al mago a su circulo de piedra. Para guardar un circulo de piedra haz clic derecho con el hechizo seleccionado. -spell.wizardry:vanishing_box.desc=Le permite al mago accesar a su cofre de Ender. -spell.wizardry:wall_of_frost.desc=El invierno en la punta de tus dedos. -spell.wizardry:water_breathing.desc=Le permite al mago respirar debajo del agua durante 60 segundos. -spell.wizardry:whirlwind.desc=Causa que el objetivo sea soplado lejos de ti a gran velocidad. -spell.wizardry:wither.desc=Dispara un rayo de oscuridad que aplica wither a todo lo que toque. -spell.wizardry:wither_skull.desc=Lanza una Cabeza de Wither en la direccion que apuntes. +spell.agility.desc=Concede al mago velocidad de movimiento incrementada y un salto mas alto por 30 segundos. +spell.arc.desc=Dispara una chispa de rayo al objetivo. +spell.arcane_jammer.desc=No permite que el usuario use magia en los proximos 15 segundos. +spell.arrow_rain.desc="Arqueros, disparen!" +spell.banish.desc=Teletransporta al objetivo una posicion cercana aleatoria en contra de su voluntad. +spell.black_hole.desc=Desgarra la realidad. +spell.blink.desc=Teletransporta al mago a la posicion que estan apuntando. +spell.blizzard.desc=Crea una zona de aire frio, la cual ralentiza y hiere continuamente a cualquiera en su interior. El creador del hechizo es inmune al dano pero no al efecto. +spell.bubble.desc=Dispara un chorro de burbujas que causa que lo primero que toque flote hacia el cielo. La burbuja explota despues de un tiempo o si el objetivo es golpeado. +spell.chain_lightning.desc=Dispara un relampago a un objetivo, el cual hace cadena con objetivos cercanos hasta dos veces. +spell.clairvoyance.desc=Revela el camino hacia una localizacion guardada. Con este hechizo seleccionado, haga shift-clic derecho en un bloque para guardarlo. Lanza este hechizo para revelar el camino. El camino desaparecera despues de 90 segundos. +spell.cobwebs.desc=Crea telas de arana en la direccion a la cual estas apuntando, lo cual limita la movilidad de tu objetivo. Las telas de arana despareceran en 20 segundos o si son rotas. +spell.conjure_armour.desc=Crea Armadura Espectral alrededor del mago lo cual ofrece proteccion similar a la armadura de hierro. La armadura dura 60 segundos. El mago debe tener el espacio de armadura vacio. +spell.conjure_bow.desc=Crea un Arco Espectral con flechas ilimitadas que dura 30 segundos. +spell.conjure_pickaxe.desc=Crea un Pico Espectral con fuerza igual a la de un Pico de Hierro, el cual dura 30 segundos. +spell.conjure_sword.desc=Crea una Espada Espectral con igual fuerza que una de hierro y dura 30 segundos. +spell.cure_effects.desc=Purifica al usuario de todos los efectos de pocion, ya sean buenos o malos. +spell.curse_of_soulbinding.desc=Provoca que el alma del objetivo esta ligada al del mago, lo que significa que todo el dano que recibe el mago lo recibe el objetivo. La maldicion dura hasta que uno de los dos muera. +spell.darkness_orb.desc=Dispara una bala de energia oscura en la direccion que apuntes, la cual aplicar wither. +spell.darkvision.desc=Concede vision nocturna por 45 segundos. +spell.dart.desc=Dispara un dardo en la direccion que estas apuntando el cual hiere y debilita al objetivo. +spell.decay.desc=Crea un pezado de deterioro en el suelo lo cual infecta y hiere a cualquier criatura que lo pise, tambien causa que estas criatura sigan esparciendo el deterioro por donde caminen. +spell.decoy.desc=Crea un clon ilusorio del mago que atrae a los enemigos. El senuelo desaparecera en 30 segundos. +spell.detonate.desc=Causa un explosion donde estes mirando, hiriendo a todas las criaturas cercanas - incluyendo al mago si se encuentra muy cerca. +spell.diamondflesh.desc="Tus flechas no son nada contra mi!" +spell.earthquake.desc=Un verdadero de Mago de Tierra puede mover montanas. +spell.entrapment.desc=Atrpa al objetivo en una esfera de oscuridad que lo eleva y hiere continuamente. +spell.fireball.desc=Lanza una bola de fuego en la direccion a la que apuntes. +spell.firebolt.desc=Dispara un chorro de fuego a corta distancia en frente de ti. +spell.firebomb.desc=Lanza una bomba de fuego, la cual detona cuando impacta quemando todo a su alrededor. +spell.fire_resistance.desc=Concede resistencia al fuego al mago por 30 segundos. +spell.fire_sigil.desc=Coloca una trampa de fuego que quema y hiere a la criatura que la pise. +spell.fireskin.desc=Envuelve al mago en fuego por 30 segundos, provocando que cualquier que lo toque se queme. +spell.firestorm.desc="Yo soy el dragon." +spell.flame_ray.desc=Crea una corriente de llamas en la direccion a la que apuntas, la cual quema todo a su paso. +spell.flaming_axe.desc=Crea una Hacha Llameante que quema a todos los enemigos que golpees. Dura 30 segundos. +spell.flaming_weapon.desc=Imbuye con llamas la primera arma en el inventario del mago, la magia de deshace despues de 45 segundos. +spell.flight.desc=Vuela como un aguila. +spell.font_of_mana.desc="Fuimos llenados con una intensa energia magica que parecia emanar del centro del..." - Extraido del diario de un mago olvidado; el resto de la pagina esta quemada. +spell.font_of_vitality.desc=Se siente increible. +spell.force_arrow.desc=Dispara una flecha de fuerza en la direccion que apuntes. +spell.forcefield.desc=Crea un campo de fuerza alrededor del mago que repele criaturas y proyectiles. +spell.force_orb.desc=Lanza una esfera de fuerza que hiere y empuja criaturas cuando impacta. +spell.forests_curse.desc="Como te atreves a entrar en mi bosque!" +spell.freeze.desc=Congela al objetivo por 10 segundos. Tambien congela el agua y crea nieve en el suelo. +spell.freezing_weapon.desc=Imbuye el poder del frio a la primera arma en el inventario del mago, provocando que el arma congela a sus objetivos. La magia deshace despues de 45 segundos. +spell.frost_axe.desc=Crea un Hacha Escarchada la cual congela los enemigos que golpees. Dura 30 segundos. +spell.frost_ray.desc=Crea un corriente de hielo en la direccion que apuntes la cual ralentiza y hiere continuamente al objetivo. +spell.frost_sigil.desc=Coloca un trampa de hielo en el suelo el cual hiere y congela al cualquiera que la pise. +spell.glide.desc=Permite que el mago planee en el aire. Debe mantenerse el boton presionado. +spell.greater_fireball.desc=Lanza una bola de fuego de mayor tamano. +spell.greater_heal.desc=Cura 4 corazones del mago. +spell.group_heal.desc=Cura 3 corazones al mago, a aliados cercanos y a criaturas invocadas. +spell.growth_aura.desc=Crece todos los cultivos cercanos al mago. Tambien hace crecer flores y hierba alta. +spell.hailstorm.desc=Fue durante el Gran Invierno de la 3era Edad que los Magos de Hielo descubrieron su verdadero potencial. +spell.heal.desc=Cura 2 corazones del usuario. +spell.heal_ally.desc=Cura 2.5 corazones al objetivo. +spell.healing_aura.desc=Crea una zona de energia curadora que regenera la salud de todos los alidados cercanos. Los No-Muertos dentro reciben dano. +spell.homing_spark.desc=Crea una chispa flotante que persigue enemigos. +spell.ice_age.desc="Seras congelado por toda la eternidad!" +spell.ice_charge.desc=Lanza una carga de hielo que explota cuando impacta, congelando todas las criaturas y soltando fragmentos en todas las direcciones. +spell.ice_lance.desc=Dispara una gran lanza de hielo en la direccion a la que estas apuntando, la cual atraviesa los objetivos hieriendo y congelandolos. +spell.ice_shard.desc=Dispara un fragemento de hielo que hace dano y ralentiza +spell.ice_shroud.desc=Cubre al mago con hielo, lo que ocasiona que cualquier que lo ataque sea congelado. +spell.ice_spikes.desc=Causa que pinchos de hielo crezcan desde el suelo hiriendo a los enemigos. +spell.ice_statue.desc=Congela al objetivo durante 20 segundos. El objetivo no se puede mover ni atacar pero tambien es inmune al dano. +spell.ignite.desc=Quema al objetivo. Tambien funciona como un mechero. +spell.imbue_weapon.desc=Imbuye la primera arma en el inventario con magia, haciendola mas efectiva. La magia se deshace despues de 45 segundos. +spell.intimidate.desc=Emite un grunido intimidante el cual provoca que las criaturas espacen. +spell.invigorating_presence.desc=Concede al mago y a los aliados cercanos fuerza incrementada por 45 segundos. +spell.invisibility.desc=Le otorga invisibilidad al mago por 30 segundos. +spell.invoke_weather.desc=Cambia el clima del mundo. +spell.ironflesh.desc=Mejora grandemente la resistencia del mago por 30 segundos. +spell.leap.desc=Causa que el mago salte alto y se mueve levemente hacia adelante. +spell.levitation.desc=Levanta al mago hacia el cielo mientras el boton siga presionado. Si es usando antes de golpear el suelo, anula el dano por caida. +spell.life_drain.desc=Crea una correinte de energia oscura que drena la vida de tu objetivo y te cura. +spell.light.desc=Crea una esfera de luz que alumbra el area. Dura 30 segundos. +spell.lightning_arrow.desc=Lanza una flecha electrificada en la direccion que apuntes. +spell.lightning_bolt.desc=Causa que un trueno caiga en la direccion que apuntes. +spell.lightning_disc.desc=Envia un disco electrico en la direccion que apuntes, el cual busca objetivos. +spell.lightning_hammer.desc="Te golpeare con la ira de los cielos!" +spell.lightning_pulse.desc=Carga el suelo cerca del mago con corriente electrica, hiriendo y repeliendo criaturas cercanas. +spell.lightning_ray.desc=Crea una corriente de energia electrica que hiere a tus objetivos continuamente. +spell.lightning_sigil.desc=Coloca una trampa electrificada que electrocuta a la criatura que la pise. +spell.lightning_web.desc="Concentrare. Canaliza la tormenta en tu mente a traves de tu varita y liberala." +spell.magic_missile.desc=Dispara una bala de energia magica. +spell.metamorphosis.desc=Cambia la forma del objetivo. Solo funciona en algunas criaturas. +spell.meteor.desc=Algunos magos solo quieren ver el mundo arder... +spell.mind_control.desc=Toma control de la mente del objetivo por 30 segundos, provocando que cambie de bando y peleen a tu favor. No funciona con criaturas de voluntad muy fuerte. +spell.mind_trick.desc=Confunde y desorienta al objetivo por 15 segundos, volviendolo incapaz de atacar. El efecto se desactiva si el objetivo recibe dano. +spell.none.desc=Para obtener un libro de hechizo con el comando /give, usa la metadata: /give [player] wizardry:spell_book 1 [spell id] (Si encontraste este libro en un cofre significa que otro mod esta alterando las cosas). +spell.oakflesh.desc=Mejora la resistencia del amgo durante 30 segundos. +spell.petrify.desc=Convierte al objetivo en piedra hasta que se libere, con un chance de liberarse cuando se pone de noche. El objetivo no se puede mover ni atacar y no puede ser atacado. +spell.phase_step.desc=Transporta al mago a traves de una pared de 1 bloque de grosor. El rango mejora el grosor por el cual te puedes transportar. +spell.plague_of_darkness.desc=La Oscuridad los consumira a todos... +spell.pocket_furnace.desc=Cocina 5 objetos en el inventario. Los objetos en la barra seran cocinados primero. +spell.pocket_workbench.desc=Permite al mago craftear objetos. +spell.poison.desc=Dispara veneno en la direccion que apuntes. +spell.poison_bomb.desc=Lanza una bomba de veneno, la cual detona esparciendo mas veneno. +spell.replenish_hunger.desc=Rellena 6 puntos de hambre del mago. +spell.ring_of_fire.desc=Crea un anillo de fuego alrededor del mago, hiriendo y quemando a los objetivos cercanos. +spell.shadow_ward.desc=Crea una pared de oscurdiad en frente del mago lo cual hace que la mitad del dano recibido sea aplicado al atacante. +spell.shield.desc=Crea una barrera protectora que bloquea proyectiles y magia. Tambien concede al mago un efecto debil de resistencia. +spell.shockwave.desc=Boom. +spell.silverfish_swarm.desc="Ahhhh! Se estan multiplicando!!" +spell.sixth_sense.desc=Le permite al mago sentir las criaturas cercanas a el, incluso a traves de paredes, durante 20 segundos. +spell.slime.desc=Envuelve al objetivo en slime lo cual ralentiza y hiere continuamente. El slime explota despues de 10 segundos. +spell.smoke_bomb.desc=Lanza una bomba de humo la cual explota cuando impacta. Creando una nube de humo y dandole ceguera a las criaturas en el area de impacto. +spell.snare.desc=Coloca un trampa en el suelo que hiere y ralentiza al que la pise. +spell.snowball.desc=Lanza una bola de nieve. +spell.spark_bomb.desc=Lanza una bomba electrica que electrocuta a los objetivos cerca de su zona de impacto. +spell.spectral_pathway.desc=Crea un puente magico indestructible al frente del mago que se extiende a 15 bloques. El puente desaperece luego de 60 segundos. +spell.spider_swarm.desc=Invoca un emjambre de aranas venenosas. Desapareceran despues de 3o segundos o si son eliminadas. +spell.static_aura.desc=Rodea al mago de electricidad durante 30 segundos, disparando chispa de rayo a cualquiera que lo golpee. +spell.summon_blaze.desc=Invoca un Blaze que pelea por ti. El blaze desparecera despues de 30 segundos o si es derrotado. +spell.summon_ice_giant.desc="Smash them!" +spell.summon_ice_wraith.desc=Invoca un Espectro de Hielo que pelea por ti. El Espectro de Hielo desparecera despues de 30 segundos o si es derrotado. +spell.summon_iron_golem.desc=Autómata autónomo automatizado automático. +spell.summon_lightning_wraith.desc=Invoca un Espectro de Rayo que pelea por ti. El Espectro de Rayo desparecera despues de 30 segundos o si es derrotado. +spell.summon_phoenix.desc=Desde las cenizas... +spell.summon_shadow_wraith.desc=Invoca un Espectro de las Sombras que pelea por ti. +spell.summon_skeleton.desc=Invoca un Esqueleto que pelea por ti. El esqueleto desparecera despues de 30 segundos o si es derrotado. +spell.summon_skeleton_legion.desc="Levantate, Ejercito No-Muerto!" +spell.summon_snow_golem.desc=Crea un Golem de Nieve que pelea por ti. Dura hasta que el golem muera. +spell.summon_spirit_horse.desc=Invoca un Caballo Espectral para que lo montes. El caballo desparecera despues de que dure mucho tiempo sin ser montado o hagas shift-clic derecho con cualquier varita. +spell.summon_spirit_wolf.desc=Invoca un Lobo Espiritual que pelea por ti. El lobo solo desparecera si es matado o haces shift-clic derecho con cualquier varita. +spell.summon_storm_elemental.desc="Elemental de Rayo: Una manifestacion antigua de los elementos, difícilmente puede contener la energía que se agita dentro de el." - Guia del Mago sobre Entidades Arcanas, Volumen II +spell.summon_wither_skeleton.desc=Invoca un Esqueleto del Wither que pelea por ti. El esqueleto del wither desparecera despues de 30 segundos o si es derrotado. +spell.summon_zombie.desc=Invoca un Zombi que pelea por ti. El zombi desparecera despues de 30 segundos o si es derrotado. +spell.telekinesis.desc=Mueve un item o un objeto pequeno hacia ti si haces clic derecho sobre el bloque. Tambien puede desarmar jugadores. +spell.thunderbolt.desc=Dispara una bala de trueno que empuja los enemigos. +spell.thunderstorm.desc="Mwahahahahahaha!" +spell.tornado.desc=Libera un tornado en la direccion que mires, el cual atrae y levanta a todos las criaturas en su paso. +spell.transience.desc=Hace que el mago transcienda, volviendo inmune a todo dano pero volviendo incapaz de atacar, interactuar o romper bloques +spell.transportation.desc=Teletransporta al mago a su circulo de piedra. Para guardar un circulo de piedra haz clic derecho con el hechizo seleccionado. +spell.vanishing_box.desc=Le permite al mago accesar a su cofre de Ender. +spell.wall_of_frost.desc=El invierno en la punta de tus dedos. +spell.water_breathing.desc=Le permite al mago respirar debajo del agua durante 60 segundos. +spell.whirlwind.desc=Causa que el objetivo sea soplado lejos de ti a gran velocidad. +spell.wither.desc=Dispara un rayo de oscuridad que aplica wither a todo lo que toque. +spell.wither_skull.desc=Lanza una Cabeza de Wither en la direccion que apuntes. -spell.wizardry:invoke_weather.sun=La lluvia empieza a parar... -spell.wizardry:invoke_weather.rain=El cielo se abre... -spell.wizardry:transportation.missing=Tu circulo de piedra no se encuentra o esta siendo obstruido... -spell.wizardry:transportation.undefined=Debes guardar un circulo de piedra primero! -spell.wizardry:transportation.wrongdimension=Tu circulo de piedra se encuentra en otra dimension... -spell.wizardry:clairvoyance.searching=Buscando... -spell.wizardry:clairvoyance.confirm=El camino revelado al lanzar %1$s ahora te llevara a este punto -spell.wizardry:clairvoyance.outofrange=Tu punto guardado esta muy lejos o es inaccesible... -spell.wizardry:clairvoyance.undefined=Debes guardar una localizacion primero! -spell.wizardry:clairvoyance.wrongdimension=Tu localizacion guardada esta en otra dimension... +spell.invoke_weather.sun=La lluvia empieza a parar... +spell.invoke_weather.rain=El cielo se abre... +spell.transportation.missing=Tu circulo de piedra no se encuentra o esta siendo obstruido... +spell.transportation.undefined=Debes guardar un circulo de piedra primero! +spell.transportation.wrongdimension=Tu circulo de piedra se encuentra en otra dimension... +spell.clairvoyance.searching=Buscando... +spell.clairvoyance.confirm=El camino revelado al lanzar %1$s ahora te llevara a este punto +spell.clairvoyance.outofrange=Tu punto guardado esta muy lejos o es inaccesible... +spell.clairvoyance.undefined=Debes guardar una localizacion primero! +spell.clairvoyance.wrongdimension=Tu localizacion guardada esta en otra dimension... -potion.wizardry:frost=Congelacion -potion.wizardry:fireskin=Piel de Fuego -potion.wizardry:ice_shroud=Manto de Hielo -potion.wizardry:static_aura=Aura Estatica -potion.wizardry:transience=Transitoriedad -potion.wizardry:decay=Deterioro -potion.wizardry:sixth_sense=Sexto Sentido -potion.wizardry:arcane_jammer=Perturbador Arcano -potion.wizardry:mind_trick=Truco Mental -potion.wizardry:mind_control=Control Mental -potion.wizardry:font_of_mana=Fuente de Mana -potion.wizardry:fear=Miedo +potion.frost=Congelacion +potion.fireskin=Piel de Fuego +potion.ice_shroud=Manto de Hielo +potion.static_aura=Aura Estatica +potion.transience=Transitoriedad +potion.decay=Deterioro +potion.sixth_sense=Sexto Sentido +potion.arcane_jammer=Perturbador Arcano +potion.mind_trick=Truco Mental +potion.mind_control=Control Mental +potion.font_of_mana=Fuente de Mana +potion.fear=Miedo -enchantment.wizardry:magic_sword=Impregnacion -enchantment.wizardry:magic_bow=Impregnacion -enchantment.wizardry:flaming_weapon=Impregnacion de Fuego -enchantment.wizardry:freezing_weapon=Impregnacion de Fuego +enchantment.magic_sword=Impregnacion +enchantment.magic_bow=Impregnacion +enchantment.flaming_weapon=Impregnacion de Fuego +enchantment.freezing_weapon=Impregnacion de Fuego key.categories.wizardry=Wizardry -key.wizardry.next_spell=Hechizo siguiente -key.wizardry.previous_spell=Hechizo anterior +key.next_spell=Hechizo siguiente +key.previous_spell=Hechizo anterior -death.attack.wizardry_magic=%1$s fue matado por %2$s usando magia -death.attack.indirect_wizardry_magic=%1$s fue matado por %2$s usando magia +death.attack.wizardryMagic=%1$s fue matado por %2$s usando magia +death.attack.indirectWizardryMagic=%1$s fue matado por %2$s usando magia -commands.wizardry:cast.usage=/%1$s [player] [damage multiplier] [range multiplier] [duration multiplier] [blast multiplier] -commands.wizardry:cast.success=Lanzado con exito %1$s -commands.wizardry:cast.success_continuous=Lanzado con exito %1$s; repite el comando para parar -commands.wizardry:cast.success_remote=Lanzado con exito %1$s como %2$s -commands.wizardry:cast.success_remote_continuous=Lanzado con exito %1$s como %2$s; repite el comando para parar -commands.wizardry:cast.fail=Imposible lanzar %1$s -commands.wizardry:cast.not_found=No hay ningun hechizo con ID %1$s +commands.cast.usage=/%1$s [player] [damage multiplier] [range multiplier] [duration multiplier] [blast multiplier] +commands.cast.success=Lanzado con exito %1$s +commands.cast.success_continuous=Lanzado con exito %1$s; repite el comando para parar +commands.cast.success_remote=Lanzado con exito %1$s como %2$s +commands.cast.success_remote_continuous=Lanzado con exito %1$s como %2$s; repite el comando para parar +commands.cast.fail=Imposible lanzar %1$s +commands.cast.not_found=No hay ningun hechizo con ID %1$s -commands.wizardry:ally.usage=/%1$s [player] -commands.wizardry:ally.addally=%1$s ha sido anadido a la lista de aliados de %2$s -commands.wizardry:ally.removeally=%1$s ha sido removido de la lista de aliados de %2$s -commands.wizardry:ally.self=Los jugadores no pueden ser aliados de si mismos! -commands.wizardry:ally.permission=No tienes permiso para cambiar los aliados de otros jugadores +commands.ally.usage=/%1$s [player] +commands.ally.addally=%1$s ha sido anadido a la lista de aliados de %2$s +commands.ally.removeally=%1$s ha sido removido de la lista de aliados de %2$s +commands.ally.self=Los jugadores no pueden ser aliados de si mismos! +commands.ally.permission=No tienes permiso para cambiar los aliados de otros jugadores -commands.wizardry:allies.usage=/%1$s [player] -commands.wizardry:allies.list=Jugadores que son aliados: %1$s -commands.wizardry:allies.list_other=Jugadores que son aliados de %1$s: %2$s -commands.wizardry:allies.permission=No tienes permiso para ver los aliados de otros jugadores -commands.wizardry:allies.none=Ninguno +commands.allies.usage=/%1$s [player] +commands.allies.list=Jugadores que son aliados: %1$s +commands.allies.list_other=Jugadores que son aliados de %1$s: %2$s +commands.allies.permission=No tienes permiso para ver los aliados de otros jugadores +commands.allies.none=Ninguno -commands.wizardry:discoverspell.usage=/%1$s [player] -commands.wizardry:discoverspell.not_found=There is no such spell with ID %1$s -commands.wizardry:discoverspell.clear=Cleared all spell discovery data for %1$s -commands.wizardry:discoverspell.all=Added all spells to %1$s's spell discovery data -commands.wizardry:discoverspell.addspell=Added %1$s to %2$s's spell discovery data -commands.wizardry:discoverspell.removespell=Removed %1$s from %2$s's spell discovery data +commands.discoverspell.usage=/%1$s [player] +commands.discoverspell.not_found=There is no such spell with ID %1$s +commands.discoverspell.clear=Cleared all spell discovery data for %1$s +commands.discoverspell.all=Added all spells to %1$s's spell discovery data +commands.discoverspell.addspell=Added %1$s to %2$s's spell discovery data +commands.discoverspell.removespell=Removed %1$s from %2$s's spell discovery data -config.wizardry.title.general=Mod Options +config.title.general=Mod Options -config.wizardry.category.spells=Configurar Hechizos -config.wizardry.category.spells.tooltip=Seleccionar que hechizos estan activados -config.wizardry.title.spells=Configuracion de Hechizos -config.wizardry.subtitle.spells=Establece un hechizo en falso para desactivarlo. +config.category.spells=Configurar Hechizos +config.category.spells.tooltip=Seleccionar que hechizos estan activados +config.title.spells=Configuracion de Hechizos +config.subtitle.spells=Establece un hechizo en falso para desactivarlo. -config.wizardry.category.resistances=Configurar Resistencias -config.wizardry.category.resistances.tooltip=Configura cuales mobs son inmunes a los tipos de magia -config.wizardry.title.resistances=Configuracion de Resistencias -config.wizardry.subtitle.resistances=Ve las descripciones de opciones individuales para mas detalles. +config.category.resistances=Configurar Resistencias +config.category.resistances.tooltip=Configura cuales mobs son inmunes a los tipos de magia +config.title.resistances=Configuracion de Resistencias +config.subtitle.resistances=Ve las descripciones de opciones individuales para mas detalles. -config.wizardry.category.ids=Configurar IDs -config.wizardry.category.ids.tooltip=Cambiar los IDs usados por Wizardry -config.wizardry.title.ids=Configuracion de IDs -config.wizardry.subtitle.ids=Cambia estos IDs si tienen conflicto con otro mod. +config.category.ids=Configurar IDs +config.category.ids.tooltip=Cambiar los IDs usados por Wizardry +config.title.ids=Configuracion de IDs +config.subtitle.ids=Cambia estos IDs si tienen conflicto con otro mod. -config.wizardry.tower_rarity=Rareza de Torres -config.wizardry.ore_dimensions=Dimensiones de Mena -config.wizardry.flower_dimensions=Dimensiones de Flores -config.wizardry.tower_dimensions=Dimensiones de Torres -config.wizardry.spell_book_drop_chance=Oportunidad de Dropeo de Libro de Hechizo -config.wizardry.generate_loot=Generar Botin -config.wizardry.firebomb_is_craftable=Bomba de Fuego es crafteable -config.wizardry.poison_bomb_is_craftable=Bomba de Veneno es crafteable -config.wizardry.smoke_bomb_is_craftable=Bomba de Humo es crafteable -config.wizardry.use_alternate_scroll_recipe=Usa la receta alternativa de pergamino -config.wizardry.teleport_through_unbreakable_blocks=Teletransportarte a traves de bloques indestructibles -config.wizardry.show_summoned_creature_names=Mostrar los nombres de las criaturas invocadas -config.wizardry.friendly_fire=Fuego Amigo -config.wizardry.telekinetic_disarmament=Desarme Telequinetico -config.wizardry.discovery_mode=Modo Descubrir -config.wizardry.enable_shift_scrolling=Permitir shift-rueda del raton para cambiar de hechizo -config.wizardry.minion_revenge_targeting=Enfoque de venganza de minion -config.wizardry.player_damage_scaling=Factor de escala de dano del Jugador -config.wizardry.npc_damage_scaling=Factor de escala de dano de NPC -config.wizardry.cast_command_multiplier_limit=Limite del Multiplicador de lanzamiento de hechizo por Comando -config.wizardry.summoned_creature_targets_whitelist=Lista blanca de objetivos de criaturas invocadas -config.wizardry.summoned_creature_targets_blacklist=Lista negra de objetivos de criaturas invocadas -config.wizardry.spell_hud_position=Posicion del HUD de hechizos -config.wizardry.cast_command_name=Nombre del Hechizo lanzado por comando -config.wizardry.discoverspell_command_name=Descubrir el nombre del hechizo lanzado por comando -config.wizardry.ally_command_name=Colocar el nombre del comando de aliado -config.wizardry.allies_command_name=Ver el nombre del comandod de aliado +config.tower_rarity=Rareza de Torres +config.ore_dimensions=Dimensiones de Mena +config.flower_dimensions=Dimensiones de Flores +config.tower_dimensions=Dimensiones de Torres +config.spell_book_drop_chance=Oportunidad de Dropeo de Libro de Hechizo +config.generate_loot=Generar Botin +config.firebomb_is_craftable=Bomba de Fuego es crafteable +config.poison_bomb_is_craftable=Bomba de Veneno es crafteable +config.smoke_bomb_is_craftable=Bomba de Humo es crafteable +config.use_alternate_scroll_recipe=Usa la receta alternativa de pergamino +config.teleport_through_unbreakable_blocks=Teletransportarte a traves de bloques indestructibles +config.show_summoned_creature_names=Mostrar los nombres de las criaturas invocadas +config.friendly_fire=Fuego Amigo +config.telekinetic_disarmament=Desarme Telequinetico +config.discovery_mode=Modo Descubrir +config.enable_shift_scrolling=Permitir shift-rueda del raton para cambiar de hechizo +config.minion_revenge_targeting=Enfoque de venganza de minion +config.player_damage_scaling=Factor de escala de dano del Jugador +config.npc_damage_scaling=Factor de escala de dano de NPC +config.cast_command_multiplier_limit=Limite del Multiplicador de lanzamiento de hechizo por Comando +config.summoned_creature_targets_whitelist=Lista blanca de objetivos de criaturas invocadas +config.summoned_creature_targets_blacklist=Lista negra de objetivos de criaturas invocadas +config.spell_hud_position=Posicion del HUD de hechizos +config.cast_command_name=Nombre del Hechizo lanzado por comando +config.discoverspell_command_name=Descubrir el nombre del hechizo lanzado por comando +config.ally_command_name=Colocar el nombre del comando de aliado +config.allies_command_name=Ver el nombre del comandod de aliado -config.wizardry.mobs_immune_to_fire=Mobs Inmunes Al Fuego -config.wizardry.mobs_immune_to_ice=Mobs Inmunees Al Frio -config.wizardry.mobs_immune_to_lightning=Mobs Inmunes Al Rayo -config.wizardry.mobs_immune_to_wither=Mobs Inmunes Al Wither -config.wizardry.mobs_immune_to_poison=Mobs Inmunes Al Veneno +config.mobs_immune_to_fire=Mobs Inmunes Al Fuego +config.mobs_immune_to_ice=Mobs Inmunees Al Frio +config.mobs_immune_to_lightning=Mobs Inmunes Al Rayo +config.mobs_immune_to_wither=Mobs Inmunes Al Wither +config.mobs_immune_to_poison=Mobs Inmunes Al Veneno -config.wizardry.tower_rarity.tooltip=Rareza para las torres de magos. Numeros mayores suben la rareza. Coloque un 0 para desactivarlas. -config.wizardry.ore_dimensions.tooltip=Lista de dimensiones en las cuales la Mena de Cristal Magico aparecera. -config.wizardry.flower_dimensions.tooltip=Lista de dimensiones en las cuales apareceran flores de cristal magico. -config.wizardry.tower_dimensions.tooltip=Lista de dimensiones donde se generaran torres de magos. -config.wizardry.spell_book_drop_chance.tooltip=La probabilidad de que un mob arroje un libro de hechizos cuando muera. Mientras mas alto sea el numero, mas chance tendras. Coloca un 0 para desactivar el dropeo de libros. Coloque 200 para asegurar el dropeo 100%. -config.wizardry.generate_loot.tooltip=Si se debe generar botin del mod en cofres de mazmorras. -config.wizardry.firebomb_is_craftable.tooltip=Si las bombas de fuego son crafteables o no. -config.wizardry.poison_bomb_is_craftable.tooltip=Si las bombas de veneno son crafteables o no. -config.wizardry.smoke_bomb_is_craftable.tooltip=Si las bombas de humo son crafteables o no. -config.wizardry.use_alternate_scroll_recipe.tooltip=Si se requiere cristal magico para craftear pergaminos vacioes. Utilice esta opcion si otro mod tiene conflicto. -config.wizardry.teleport_through_unbreakable_blocks.tooltip=Si los jugadores son capaces de pasar a traves de bloques indestructibles (bedrock) usando Paso de Fase. -config.wizardry.show_summoned_creature_names.tooltip=Si mostrar los nombres de las criaturas invocadas y sus duenos sobre su cabeza. -config.wizardry.friendly_fire.tooltip=Permitir que los aliados se puedan herir con magia. -config.wizardry.telekinetic_disarmament.tooltip=Permitir que los jugadores puedan desarmar otros jugadores con el hechizo de Telequinesis. -config.wizardry.discovery_mode.tooltip=Para aquellos que le guste el misterio! Si esta en verdadero, los hechizos que no se hayan conjurado seran ilegibles. No tiene efecto en creativo. -config.wizardry.enable_shift_scrolling.tooltip=Si eres capaz de cambiar de hechizos al agacharte y usar la rueda del raton. Nota: Esta funcionalidad es del lado cliente, otros jugadores no dependen de esta, deben configurar su propia opcion. -config.wizardry.minion_revenge_targeting.tooltip=Si las criaturas invocadas atacan a su invocador si este los ataca. -config.wizardry.player_damage_scaling.tooltip=Factor de incremento de dano global para el dano hecho por jugadores, relativo a 1. -config.wizardry.npc_damage_scaling.tooltip=Factor de incremento de dano global para el dano hecho por NPCs, relativo a 1. -config.wizardry.cast_command_multiplier_limit.tooltip=Limite maximo usado con el comando /cast. Esto esta aqui para evitar que accidentalmente destruyan un mundo o servidor. -config.wizardry.summoned_creature_targets_whitelist.tooltip=Lista de nombres de entidades que los magos y criaturas invocadas pueden atacar. -config.wizardry.summoned_creature_targets_blacklist.tooltip=Lista de nombres de entidades que los magos y criaturas invocadas no pueden atacar. Si eliminas creeper hazlo bajo tu responsabilidad!! -config.wizardry.spell_hud_position.tooltip=La posicion de la interfaz de hechizos. -config.wizardry.cast_command_name.tooltip=El nombre del comando /cast. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'magia', entonces el comando seria /magia. -config.wizardry.discoverspell_command_name.tooltip=El nombre del comando /discoverspell. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'descubrir', entonces el comando seria /descubrir. -config.wizardry.ally_command_name.tooltip=El nombre del comando /ally. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'aliado', entonces el comando seria /aliado. -config.wizardry.allies_command_name.tooltip=El nombre del comando /allies command. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'aliados', entonces el comando seria /aliados. +config.frost_potion_id=ID de la pocion de Congelacion +config.transience_potion_id=ID de la pocion de Transitoriedad +config.fireskin_potion_id=ID de la pocion de Piel de Fuego +config.ice_shroud_potion_id=ID de la pocion de Manto de Hielo +config.static_aura_potion_id=ID de la pocion de Aura Estatica +config.decay_potion_id=ID de la pocion de Deterioro +config.sixth_sense_potion_id=ID de la pocion de Sexto Sentido +config.arcane_jammer_potion_id=ID de la pocion de Perturbador Arcano +config.mind_trick_potion_id=ID de la pocion de Truco Mental +config.mind_control_potion_id=ID de la pocion de Control Mental +config.font_of_mana_potion_id=ID de la pocion de Fuente de Mana +config.fear_potion_id=ID de la pocion de Miedo +config.magic_sword_enchantment_id=ID del Encantamiento de Espada Magica +config.magic_bow_enchantment_id=ID del Encantamiento de Arco Magico +config.flaming_weapon_enchantment_id=ID del Encantamiento de Arma Llameante +config.freezing_weapon_enchantment_id=ID del Encantamiento de Arma Congelada -config.wizardry.mobs_immune_to_fire.tooltip=Lista de nombres de entidades que son inmunes al fuego, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al fuego. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:_mago). -config.wizardry.mobs_immune_to_ice.tooltip=Lista de nombres de entidades que son inmunes al frio, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al frio. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:_mago). -config.wizardry.mobs_immune_to_lightning.tooltip=Lista de nombres de entidades que son inmunes al rayo, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al rayo. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:_mago). -config.wizardry.mobs_immune_to_wither.tooltip=Lista de nombres de entidades que son inmunes al wither, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al wither. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:_mago). -config.wizardry.mobs_immune_to_poison.tooltip=Lista de nombres de entidades que son inmunes al veneno, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al veneno. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:_mago). +config.tower_rarity.tooltip=Rareza para las torres de magos. Numeros mayores suben la rareza. Coloque un 0 para desactivarlas. +config.ore_dimensions.tooltip=Lista de dimensiones en las cuales la Mena de Cristal Magico aparecera. +config.flower_dimensions.tooltip=Lista de dimensiones en las cuales apareceran flores de cristal magico. +config.tower_dimensions.tooltip=Lista de dimensiones donde se generaran torres de magos. +config.spell_book_drop_chance.tooltip=La probabilidad de que un mob arroje un libro de hechizos cuando muera. Mientras mas alto sea el numero, mas chance tendras. Coloca un 0 para desactivar el dropeo de libros. Coloque 200 para asegurar el dropeo 100%. +config.generate_loot.tooltip=Si se debe generar botin del mod en cofres de mazmorras. +config.firebomb_is_craftable.tooltip=Si las bombas de fuego son crafteables o no. +config.poison_bomb_is_craftable.tooltip=Si las bombas de veneno son crafteables o no. +config.smoke_bomb_is_craftable.tooltip=Si las bombas de humo son crafteables o no. +config.use_alternate_scroll_recipe.tooltip=Si se requiere cristal magico para craftear pergaminos vacioes. Utilice esta opcion si otro mod tiene conflicto. +config.teleport_through_unbreakable_blocks.tooltip=Si los jugadores son capaces de pasar a traves de bloques indestructibles (bedrock) usando Paso de Fase. +config.show_summoned_creature_names.tooltip=Si mostrar los nombres de las criaturas invocadas y sus duenos sobre su cabeza. +config.friendly_fire.tooltip=Permitir que los aliados se puedan herir con magia. +config.telekinetic_disarmament.tooltip=Permitir que los jugadores puedan desarmar otros jugadores con el hechizo de Telequinesis. +config.discovery_mode.tooltip=Para aquellos que le guste el misterio! Si esta en verdadero, los hechizos que no se hayan conjurado seran ilegibles. No tiene efecto en creativo. +config.enable_shift_scrolling.tooltip=Si eres capaz de cambiar de hechizos al agacharte y usar la rueda del raton. Nota: Esta funcionalidad es del lado cliente, otros jugadores no dependen de esta, deben configurar su propia opcion. +config.minion_revenge_targeting.tooltip=Si las criaturas invocadas atacan a su invocador si este los ataca. +config.player_damage_scaling.tooltip=Factor de incremento de dano global para el dano hecho por jugadores, relativo a 1. +config.npc_damage_scaling.tooltip=Factor de incremento de dano global para el dano hecho por NPCs, relativo a 1. +config.cast_command_multiplier_limit.tooltip=Limite maximo usado con el comando /cast. Esto esta aqui para evitar que accidentalmente destruyan un mundo o servidor. +config.summoned_creature_targets_whitelist.tooltip=Lista de nombres de entidades que los magos y criaturas invocadas pueden atacar. +config.summoned_creature_targets_blacklist.tooltip=Lista de nombres de entidades que los magos y criaturas invocadas no pueden atacar. Si eliminas creeper hazlo bajo tu responsabilidad!! +config.spell_hud_position.tooltip=La posicion de la interfaz de hechizos. +config.cast_command_name.tooltip=El nombre del comando /cast. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'magia', entonces el comando seria /magia. +config.discoverspell_command_name.tooltip=El nombre del comando /discoverspell. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'descubrir', entonces el comando seria /descubrir. +config.ally_command_name.tooltip=El nombre del comando /ally. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'aliado', entonces el comando seria /aliado. +config.allies_command_name.tooltip=El nombre del comando /allies command. Esto es lo que escribes luego de /; por ejemplo si esto dijera 'aliados', entonces el comando seria /aliados. +config.mobs_immune_to_fire.tooltip=Lista de nombres de entidades que son inmunes al fuego, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al fuego. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:Mago). +config.mobs_immune_to_ice.tooltip=Lista de nombres de entidades que son inmunes al frio, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al frio. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:Mago). +config.mobs_immune_to_lightning.tooltip=Lista de nombres de entidades que son inmunes al rayo, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al rayo. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:Mago). +config.mobs_immune_to_wither.tooltip=Lista de nombres de entidades que son inmunes al wither, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al wither. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:Mago). +config.mobs_immune_to_poison.tooltip=Lista de nombres de entidades que son inmunes al veneno, a parte de los que estan por defecto. Agrega criaturas de otros mods si quieres que sean inmunes al veneno. Los nombres de la entidades no llevan mayusculas. Para entidades de mods, usa el ID del mod como prefijo (e.g. wizardry:Mago). + +config.frost_potion_id.tooltip=ID de la pocion de Congelacion. Cambialo si hay conflicto con otro mod. +config.transience_potion_id.tooltip=ID de la pocion de Transitoriedad. Cambialo si hay conflicto con otro mod. +config.fireskin_potion_id.tooltip=ID de la pocion de Piel de Fuego. Cambialo si hay conflicto con otro mod. +config.ice_shroud_potion_id.tooltip=ID de la pocion de Velo de Hielo. Cambialo si hay conflicto con otro mod. +config.static_aura_potion_id.tooltip=ID de la pocion de Aura Estatica. Cambialo si hay conflicto con otro mod. +config.decay_potion_id.tooltip=ID de la pocion de Deterioro. Cambialo si hay conflicto con otro mod. +config.sixth_sense_potion_id.tooltip=ID de la pocion de Sexto Sentido. Cambialo si hay conflicto con otro mod. +config.arcane_jammer_potion_id.tooltip=ID de la pocion de Perturbador Arcano. Cambialo si hay conflicto con otro mod. +config.mind_trick_potion_id.tooltip=ID de la pocion de Truco Mental. Cambialo si hay conflicto con otro mod. +config.mind_control_potion_id.tooltip=ID de la pocion de Control Mental. Cambialo si hay conflicto con otro mod. +config.font_of_mana_potion_id.tooltip=ID de la pocion de Fuente de Mana. Cambialo si hay conflicto con otro mod. +config.fear_potion_id.tooltip=ID de la pocion de Miedo. Cambialo si hay conflicto con otro mod. +config.magic_sword_enchantment_id.tooltip=ID del Encantamiendo de Espada Magica. Cambialo si hay conflicto con otro mod. +config.magic_bow_enchantment_id.tooltip=ID del Encantamiento de Arco Magico. Cambialo si hay conflicto con otro mod. +config.flaming_weapon_enchantment_id.tooltip=ID del Encantamiento de Arma Llameante. Cambialo si hay conflicto con otro mod. +config.freezing_weapon_enchantment_id.tooltip=ID del Encantamiento de Arma Congelada. Cambialo si hay conflicto con otro mod. wizard.debug=%1$s, %2$s, %3$s \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/lang/ru_RU.lang b/src/main/resources/assets/wizardry/lang/ru_RU.lang index b2d24126..51df6fa9 100644 --- a/src/main/resources/assets/wizardry/lang/ru_RU.lang +++ b/src/main/resources/assets/wizardry/lang/ru_RU.lang @@ -1,252 +1,230 @@ -tile.wizardry:arcane_workbench.name=ЧародейÑкий Стол -tile.wizardry:crystal_ore.name=КриÑÑ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð ÑƒÐ´Ð° -tile.wizardry:petrified_stone.name=Окаменелый Камень -tile.wizardry:ice_statue.name=ЛедÑÐ½Ð°Ñ Ð¡Ñ‚Ð°Ñ‚ÑƒÑ -tile.wizardry:crystal_flower.name=КриÑтальный Цветок -tile.wizardry:snare.name=Ловушка -tile.wizardry:transportation_stone.name=Камень ТранÑпортировки -tile.wizardry:spectral_block.name=Спектральный Блок -tile.wizardry:crystal_block.name=КриÑтальный Блок +tile.arcaneWorkbench.name=ЧародейÑкий Стол +tile.crystalOre.name=КриÑÑ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ð ÑƒÐ´Ð° +tile.petrifiedStone.name=Окаменелый Камень +tile.iceStatue.name=ЛедÑÐ½Ð°Ñ Ð¡Ñ‚Ð°Ñ‚ÑƒÑ +tile.crystalFlower.name=КриÑтальный Цветок +tile.snare.name=Ловушка +tile.transportationStone.name=Камень ТранÑпортировки +tile.spectralBlock.name=Спектральный Блок +tile.crystalBlock.name=КриÑтальный Блок -item.wizardry:magic_crystal.name=МагичеÑкий КриÑталл -item.wizardry:magic_wand.name=Волшебный Жезл -item.wizardry:apprentice_wand.name=Жезл Ученика -item.wizardry:advanced_wand.name=Продвинутый Жезл -item.wizardry:master_wand.name=Жезл МаÑтера -item.wizardry:spell_book.name=Книга Заклинаний +item.magicCrystal.name=МагичеÑкий КриÑталл +item.magicWand.name=Волшебный Жезл +item.apprenticeWand.name=Жезл Ученика +item.advancedWand.name=Продвинутый Жезл +item.masterWand.name=Жезл МаÑтера +item.spellBook.name=Книга Заклинаний -item.wizardry:arcane_tome.name=Фолиант Ðрканы -item.wizardry:arcane_tome.desc1=Улучшает любые %1$s -item.wizardry:arcane_tome.desc2=жезл %1$s уровень +item.arcaneTome.name=Фолиант Ðрканы +item.arcaneTome.desc1=Улучшает любые %1$s +item.arcaneTome.desc2=жезл %1$s уровень -item.wizardry:wizard_handbook.name=Книга Волшебника -item.wizardry:wizard_handbook.desc=от %1$s +item.wizardHandbook.name=Книга Волшебника +item.wizardHandbook.desc=от %1$s -item.wizardry:wand.buff=+%1$s %2$s ÑффективноÑть -item.wizardry:wand.spell=Текущее Заклинание: %1$s -item.wizardry:wand.mana=Мана: %1$s/%2$s +item.wand.buff=+%1$s %2$s ÑффективноÑть +item.wand.spell=Текущее Заклинание: %1$s +item.wand.mana=Мана: %1$s/%2$s -item.wizardry:basic_fire_wand.name=Жезл ÐžÐ³Ð½Ñ -item.wizardry:basic_ice_wand.name=Жезл Мороза -item.wizardry:basic_lightning_wand.name=Жезл ИÑкр -item.wizardry:basic_necromancy_wand.name=Жезл Теней -item.wizardry:basic_earth_wand.name=Жезл ЛеÑа -item.wizardry:basic_sorcery_wand.name=Жезл Тайн -item.wizardry:basic_healing_wand.name=Жезл Ð›ÐµÑ‡ÐµÐ½Ð¸Ñ +item.basicFireWand.name=Жезл ÐžÐ³Ð½Ñ +item.basicIceWand.name=Жезл Мороза +item.basicLightningWand.name=Жезл ИÑкр +item.basicNecromancyWand.name=Жезл Теней +item.basicEarthWand.name=Жезл ЛеÑа +item.basicSorceryWand.name=Жезл Тайн +item.basicHealingWand.name=Жезл Ð›ÐµÑ‡ÐµÐ½Ð¸Ñ -item.wizardry:apprentice_fire_wand.name=Жезл Ученика Пироманта -item.wizardry:apprentice_ice_wand.name=Жезл Ученика ЛедÑного Мага -item.wizardry:apprentice_lightning_wand.name=Жезл Ученика Штормового Мага -item.wizardry:apprentice_necromancy_wand.name=Жезл Ученика Ðекроманта -item.wizardry:apprentice_earth_wand.name=Жезл Ученика ЗемлÑного Мага -item.wizardry:apprentice_sorcery_wand.name=Жезл Ученика Колдуна -item.wizardry:apprentice_healing_wand.name=Жезл Ученика Ð¦ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ +item.apprenticeFireWand.name=Жезл Ученика Пироманта +item.apprenticeIceWand.name=Жезл Ученика ЛедÑного Мага +item.apprenticeLightningWand.name=Жезл Ученика Штормового Мага +item.apprenticeNecromancyWand.name=Жезл Ученика Ðекроманта +item.apprenticeEarthWand.name=Жезл Ученика ЗемлÑного Мага +item.apprenticeSorceryWand.name=Жезл Ученика Колдуна +item.apprenticeHealingWand.name=Жезл Ученика Ð¦ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ -item.wizardry:advanced_fire_wand.name=Жезл Пироманта -item.wizardry:advanced_ice_wand.name=Жезл ЛедÑного Мага -item.wizardry:advanced_lightning_wand.name=Жезл Штормового Мага -item.wizardry:advanced_necromancy_wand.name=Жезл Ðекроманта -item.wizardry:advanced_earth_wand.name=Жезл ЗемлÑного Мага -item.wizardry:advanced_sorcery_wand.name=Жезл Колдуна -item.wizardry:advanced_healing_wand.name=Жезл Ð¦ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ +item.advancedFireWand.name=Жезл Пироманта +item.advancedIceWand.name=Жезл ЛедÑного Мага +item.advancedLightningWand.name=Жезл Штормового Мага +item.advancedNecromancyWand.name=Жезл Ðекроманта +item.advancedEarthWand.name=Жезл ЗемлÑного Мага +item.advancedSorceryWand.name=Жезл Колдуна +item.advancedHealingWand.name=Жезл Ð¦ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ -item.wizardry:master_fire_wand.name=Жезл МаÑтера Пироманта -item.wizardry:master_ice_wand.name=Жезл МаÑтера ЛедÑного Мага -item.wizardry:master_lightning_wand.name=Жезл МаÑтера Штормового Мага -item.wizardry:master_necromancy_wand.name=Жезл МаÑтера Ðекроманта -item.wizardry:master_earth_wand.name=Жезл МаÑтера ЗемлÑного Мага -item.wizardry:master_sorcery_wand.name=Жезл МаÑтера Колдуна -item.wizardry:master_healing_wand.name=Жезл МаÑтера Ð¦ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ +item.masterFireWand.name=Жезл МаÑтера Пироманта +item.masterIceWand.name=Жезл МаÑтера ЛедÑного Мага +item.masterLightningWand.name=Жезл МаÑтера Штормового Мага +item.masterNecromancyWand.name=Жезл МаÑтера Ðекроманта +item.masterEarthWand.name=Жезл МаÑтера ЗемлÑного Мага +item.masterSorceryWand.name=Жезл МаÑтера Колдуна +item.masterHealingWand.name=Жезл МаÑтера Ð¦ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ -item.wizardry:spectral_sword.name=Спектральный Меч -item.wizardry:spectral_pickaxe.name=Ð¡Ð¿ÐµÐºÑ‚Ñ€Ð°Ð»ÑŒÐ½Ð°Ñ ÐšÐ¸Ñ€ÐºÐ° -item.wizardry:spectral_bow.name=Спектральный Лук +item.spectralSword.name=Спектральный Меч +item.spectralPickaxe.name=Ð¡Ð¿ÐµÐºÑ‚Ñ€Ð°Ð»ÑŒÐ½Ð°Ñ ÐšÐ¸Ñ€ÐºÐ° +item.spectralBow.name=Спектральный Лук -item.wizardry:mana_flask.name=Бутылка Маны -item.wizardry:storage_upgrade.name=Улучшение Хранилища Маны Жезла -item.wizardry:siphon_upgrade.name=Улучшение Сифона Жезла -item.wizardry:condenser_upgrade.name=Улучшение КонденÑатора Жезла -item.wizardry:range_upgrade.name=Улучшение РадиуÑа Жезла -item.wizardry:duration_upgrade.name=Улучшение ДлительноÑти Жезла -item.wizardry:cooldown_upgrade.name=Улучшение Кулдауна Жезла -item.wizardry:blast_upgrade.name=Улучшение ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð–ÐµÐ·Ð»Ð° -item.wizardry:attunement_upgrade.name=Улучшение Хранилища Заклинаний Жезла +item.manaFlask.name=Бутылка Маны +item.storageUpgrade.name=Улучшение Хранилища Жезла +item.siphonUpgrade.name=Улучшение Сифона Жезла +item.condenserUpgrade.name=Улучшение КонденÑатора Жезла +item.rangeUpgrade.name=Улучшение РадиуÑа Жезла +item.durationUpgrade.name=Улучшение ДлительноÑти Жезла +item.cooldownUpgrade.name=Улучшение Кулдауна Жезла +item.blastUpgrade.name=Улучшение ÐžÐ±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð–ÐµÐ·Ð»Ð° -item.wizardry:flaming_axe.name=Огненный Топор -item.wizardry:frost_axe.name=ЛедÑной Топор +item.flamingAxe.name=Огненный Топор +item.frostAxe.name=ЛедÑной Топор -item.wizardry:firebomb.name=ÐžÐ³Ð½ÐµÐ½Ð½Ð°Ñ Ð‘Ð¾Ð¼Ð±Ð° -item.wizardry:poison_bomb.name=Ð¯Ð´Ð¾Ð²Ð¸Ñ‚Ð°Ñ Ð‘Ð¾Ð¼Ð±Ð° -item.wizardry:smoke_bomb.name=Ð”Ñ‹Ð¼Ð¾Ð²Ð°Ñ Ð‘Ð¾Ð¼Ð±Ð° +item.firebomb.name=ÐžÐ³Ð½ÐµÐ½Ð½Ð°Ñ Ð‘Ð¾Ð¼Ð±Ð° +item.poisonBomb.name=Ð¯Ð´Ð¾Ð²Ð¸Ñ‚Ð°Ñ Ð‘Ð¾Ð¼Ð±Ð° -item.wizardry:blank_scroll.name=ПуÑтой Свиток -item.wizardry:scroll.name=Свиток %1$s -item.wizardry:identification_scroll.name=Свиток Идентификации -item.wizardry:identification_scroll.desc1=%1$sИдентифицирует неизвеÑтное -item.wizardry:identification_scroll.desc2=%1$sкнигу Ð·Ð°ÐºÐ»Ð¸Ð½Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ Ñвиток -item.wizardry:identification_scroll.nothing_to_identify=Ðечего Идентифицировать +item.blankScroll.name=ПуÑтой Свиток +item.scroll.name=Свиток %1$s -item.wizardry:armour_upgrade.name=Печать МагичеÑкой Защиты -item.wizardry:armour_upgrade.desc1=%1$sУлучшает Любые ОдеÑÐ½Ð¸Ñ ÐœÐ°Ð³Ð° -item.wizardry:armour_upgrade.desc2=%1$sÑделать Ñто %2$sлегендарным +item.armourUpgrade.name=Печать МагичеÑкой Защиты +item.armourUpgrade.desc1=%1$sУлучшает Любые ОдеÑÐ½Ð¸Ñ ÐœÐ°Ð³Ð° +item.armourUpgrade.desc2=%1$sÑделать Ñто %2$sлегендарным -item.wizardry:magic_silk.name=МагичеÑкий Шёлк +item.magicSilk.name=МагичеÑкий Шёлк -item.wizardry:wizard_armour.legendary=Легендарный -item.wizardry:wizard_armour.buff=-%1$s %2$s ÑтоимоÑть -item.wizardry:wizard_armour.mana=Мана: %1$s/%2$s +item.wizardArmour.legendary=Легендарный +item.wizardArmour.buff=-%1$s %2$s ÑтоимоÑть +item.wizardArmour.mana=Мана: %1$s/%2$s -item.wizardry:wizard_hat.name=ШлÑпа Волшебника -item.wizardry:wizard_robe.name=Роба Волшебника -item.wizardry:wizard_leggings.name=Поножи Волшебника -item.wizardry:wizard_boots.name=Ботинки Волшебника +item.wizard_hat.name=ШлÑпа Волшебника +item.wizard_robe.name=Роба Волшебника +item.wizard_leggings.name=Поножи Волшебника +item.wizard_boots.name=Ботинки Волшебника -item.wizardry:wizard_hat_fire.name=ШлÑпа Пироманта -item.wizardry:wizard_robe_fire.name=Роба Пироманта -item.wizardry:wizard_leggings_fire.name=Поножи Пироманта -item.wizardry:wizard_boots_fire.name=Ботинки Пироманта +item.wizard_hat_fire.name=ШлÑпа Пироманта +item.wizard_robe_fire.name=Роба Пироманта +item.wizard_leggings_fire.name=Поножи Пироманта +item.wizard_boots_fire.name=Ботинки Пироманта -item.wizardry:wizard_hat_ice.name=ШлÑпа ЛедÑного Мага -item.wizardry:wizard_robe_ice.name=Роба ЛедÑного Мага -item.wizardry:wizard_leggings_ice.name=Поножи ЛедÑного Мага -item.wizardry:wizard_boots_ice.name=Ботинки ЛедÑного Мага +item.wizard_hat_ice.name=ШлÑпа ЛедÑного Мага +item.wizard_robe_ice.name=Роба ЛедÑного Мага +item.wizard_leggings_ice.name=Поножи ЛедÑного Мага +item.wizard_boots_ice.name=Ботинки ЛедÑного Мага -item.wizardry:wizard_hat_lightning.name=ШлÑпа Штормового Мага -item.wizardry:wizard_robe_lightning.name=Роба Штормового Мага -item.wizardry:wizard_leggings_lightning.name=Поножи Штормового Мага -item.wizardry:wizard_boots_lightning.name=Ботинки Штормового Мага +item.wizard_hat_lightning.name=ШлÑпа Штормового Мага +item.wizard_robe_lightning.name=Роба Штормового Мага +item.wizard_leggings_lightning.name=Поножи Штормового Мага +item.wizard_boots_lightning.name=Ботинки Штормового Мага -item.wizardry:wizard_hat_necromancy.name=ШлÑпа Ðекроманта -item.wizardry:wizard_robe_necromancy.name=Роба Ðекроманта -item.wizardry:wizard_leggings_necromancy.name=Поножи Ðекроманта -item.wizardry:wizard_boots_necromancy.name=Ботинки Ðекроманта +item.wizard_hat_necromancy.name=ШлÑпа Ðекроманта +item.wizard_robe_necromancy.name=Роба Ðекроманта +item.wizard_leggings_necromancy.name=Поножи Ðекроманта +item.wizard_boots_necromancy.name=Ботинки Ðекроманта -item.wizardry:wizard_hat_earth.name=ШлÑпа ЗемлÑного Мага -item.wizardry:wizard_robe_earth.name=Роба ЗемлÑного Мага -item.wizardry:wizard_leggings_earth.name=Поножи ЗемлÑного Мага -item.wizardry:wizard_boots_earth.name=Ботинки ЗемлÑного Мага +item.wizard_hat_earth.name=ШлÑпа ЗемлÑного Мага +item.wizard_robe_earth.name=Роба ЗемлÑного Мага +item.wizard_leggings_earth.name=Поножи ЗемлÑного Мага +item.wizard_boots_earth.name=Ботинки ЗемлÑного Мага -item.wizardry:wizard_hat_sorcery.name=ШлÑпа Колдуна -item.wizardry:wizard_robe_sorcery.name=Роба Колдуна -item.wizardry:wizard_leggings_sorcery.name=Поножи Колдуна -item.wizardry:wizard_boots_sorcery.name=Ботинки Колдуна +item.wizard_hat_sorcery.name=ШлÑпа Колдуна +item.wizard_robe_sorcery.name=Роба Колдуна +item.wizard_leggings_sorcery.name=Поножи Колдуна +item.wizard_boots_sorcery.name=Ботинки Колдуна -item.wizardry:wizard_hat_healing.name=ШлÑпа Ð¦ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ -item.wizardry:wizard_robe_healing.name=Роба Ð¦ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ -item.wizardry:wizard_leggings_healing.name=Поножи Ð¦ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ -item.wizardry:wizard_boots_healing.name=Ботинки Ð¦ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ +item.wizard_hat_healing.name=ШлÑпа Ð¦ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ +item.wizard_robe_healing.name=Роба Ð¦ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ +item.wizard_leggings_healing.name=Поножи Ð¦ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ +item.wizard_boots_healing.name=Ботинки Ð¦ÐµÐ»Ð¸Ñ‚ÐµÐ»Ñ -item.wizardry:spawn_wizard.name=Спаун Волшебника +item.spawn_wizard.name=Спаун Волшебника -entity.wizardry.zombie_minion.name=Зомби -entity.wizardry.skeleton_minion.name=Скелет -entity.wizardry.spider_minion.name=Паук -entity.wizardry.blaze_minion.name=Блейз -entity.wizardry.ice_wraith.name=ЛедÑной Призрак -entity.wizardry.lightning_wraith.name=Штормовой Призрак -entity.wizardry.shadow_wraith.name=Теневой Призрак -entity.wizardry.spirit_wolf.name=Призрачный Волк -entity.wizardry.spirit_horse.name=ÐŸÑ€Ð¸Ð·Ñ€Ð°Ñ‡Ð½Ð°Ñ Ð›Ð¾ÑˆÐ°Ð´ÑŒ -entity.wizardry.ice_giant.name=ЛедÑной Гигант -entity.wizardry.phoenix.name=Ð¤ÐµÐ½Ð¸ÐºÑ -entity.wizardry.wizard.name=Волшебник -entity.wizardry.magic_slime.name=МагичеÑкий Слизень -entity.wizardry.silverfish_minion.name=Чешуйница +entity.wizardry.Zombie Minion.name=Зомби +entity.wizardry.Skeleton Minion.name=Скелет +entity.wizardry.Spider Minion.name=Паук +entity.wizardry.Blaze Minion.name=Блейз +entity.wizardry.Ice Wraith.name=ЛедÑной Призрак +entity.wizardry.Lightning Wraith.name=Штормовой Призрак +entity.wizardry.Shadow Wraith.name=Теневой Призрак +entity.wizardry.Spirit Wolf.name=Призрачный Волк +entity.wizardry.Spirit Horse.name=ÐŸÑ€Ð¸Ð·Ñ€Ð°Ñ‡Ð½Ð°Ñ Ð›Ð¾ÑˆÐ°Ð´ÑŒ +entity.wizardry.Ice Giant.name=ЛедÑной Гигант +entity.wizardry.Phoenix.name=Ð¤ÐµÐ½Ð¸ÐºÑ +entity.wizardry.Wizard.name=Волшебник +entity.wizardry.Magic Slime.name=МагичеÑкий Слизень +entity.wizardry.Silverfish Minion.name=Чешуйница -entity.wizardry.magic_missile.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.arc.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.spark_bomb.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.ice_shard.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.firebomb.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.poison_bomb.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.force_orb.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.spark.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.darkness_orb.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.fire_sigil.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.frost_sigil.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.lightning_sigil.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.lightning_arrow.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.firebolt.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.ice_charge.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.force_arrow.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.dart.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.lightning_disc.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.thunderbolt.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.decay.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Magic Missile.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Arc.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Spark Bomb.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Ice Shard.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Firebomb.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Poison Bomb.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Force Orb.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Spark.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Darkness Orb.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Fire Sigil.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Frost Sigil.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Lightning Sigil.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Lightning Arrow.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Firebolt.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Ice Charge.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Force Arrow.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Dart.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Lightning Disc.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Thunderbolt.name=ÐœÐ°Ð³Ð¸Ñ +entity.wizardry.Decay.name=ÐœÐ°Ð³Ð¸Ñ -entity.wizardry.black_hole.name=Ð§Ñ‘Ñ€Ð½Ð°Ñ Ð”Ñ‹Ñ€Ð° -entity.wizardry.shield.name=Щит -entity.wizardry.meteor.name=Метеор -entity.wizardry.blizzard.name=Метель -entity.wizardry.bubble.name=Пузыри -entity.wizardry.tornado.name=Торнадо -entity.wizardry.lightning_hammer.name=Молот Шторма -entity.wizardry.arrow_rain.name=Дождь Стрел -entity.wizardry.healing_aura.name=Ðура Ð›ÐµÑ‡ÐµÐ½Ð¸Ñ -entity.wizardry.forcefield.name=Силовое Поле -entity.wizardry.ring_of_fire.name=Кольцо ÐžÐ³Ð½Ñ +entity.wizardry.Black Hole.name=Ð§Ñ‘Ñ€Ð½Ð°Ñ Ð”Ñ‹Ñ€Ð° +entity.wizardry.Shield.name=Щит +entity.wizardry.Meteor.name=Метеор +entity.wizardry.Blizzard.name=Метель +entity.wizardry.Bubble.name=Пузыри +entity.wizardry.Tornado.name=Торнадо +entity.wizardry.Lightning Hammer.name=Молот Шторма +entity.wizardry.Arrow Rain.name=Дождь Стрел +entity.wizardry.Healing Aura.name=Ðура Ð›ÐµÑ‡ÐµÐ½Ð¸Ñ +entity.wizardry.Forcefield.name=Силовое Поле +entity.wizardry.Ring of Fire.name=Кольцо ÐžÐ³Ð½Ñ -item_group.wizardry=ВолшебÑтво -item_group.wizardryspells=Волшебные Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ð½Ð¸Ñ +itemGroup.wizardry=ВолшебÑтво +itemGroup.wizardryspells=Волшебные Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ð½Ð¸Ñ -achievement.crystal=Любопытный КриÑталл... -achievement.crystal.desc=Добудьте МагичеÑкий КриÑталл -achievement.arcane_initiate=ПоÑвÑщение Ð’ Магию -achievement.arcane_initiate.desc=Создайте Волшебную Палочку Из Золотого Самородка И МагичеÑкого КриÑталла -achievement.apprentice=Ученик Волшебника -achievement.apprentice.desc=ИÑпользуйте Фолиант Ðрканы Ð”Ð»Ñ Ð£Ð»ÑƒÑ‡ÑˆÐµÐ½Ð¸Ñ Ð–ÐµÐ·Ð»Ð° -achievement.master=МаÑтер Магии -achievement.master.desc=Получите Жезл МаÑтера -achievement.all_spells=Маг Ð’Ñех ПрофеÑÑий -achievement.all_spells.desc=ИÑпользуйте Каждое Заклинание Ð’ Игре -achievement.wizard_trade=МагичеÑÐºÐ°Ñ Ð¡Ð´ÐµÐ»ÐºÐ° -achievement.wizard_trade.desc=Купите Предмет У Волшебника -achievement.buy_master_spell=Знание-Ñила -achievement.buy_master_spell.wizardry:desc=Купите заклинание маÑтера у волшебника -achievement.freeze_blaze=Ðе Так Жарко -achievement.freeze_blaze.desc=Заморозьте Блейза -achievement.charge_creeper=Это Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð’Ð·Ð¾Ñ€Ð²Ñ‘Ñ‚ÑÑ -achievement.charge_creeper.desc="Случайно" ЗарÑдите Крипира -achievement.frankenstein=Франкенштейн -achievement.frankenstein.desc=Привратите Свинью Ð’ Свинозомби С Помощью Молнии -achievement.special_upgrade=ЧародейÑкое РемеÑло -achievement.special_upgrade.desc=Применить Специальное Улучшение Ð”Ð»Ñ Ð–ÐµÐ·Ð»Ð° -achievement.craft_flask=Это ÐœÐ°Ð³Ð¸Ñ Ð’ Бутылке! -achievement.craft_flask.desc=Создайте Ману Ð’ Бутылке -achievement.elemental=Стихии -achievement.elemental.desc=Получите Стихийный Жезл -achievement.armour_set=Теперь Ты ÐаÑтоÑщий Волшебник -achievement.armour_set.desc=Создайте И Экипируйте Полный Ðабор ОдеÑÐ½Ð¸Ñ Ð’Ð¾Ð»ÑˆÐµÐ±Ð½Ð¸ÐºÐ° -achievement.legendary=Легендарный -achievement.legendary.desc=Получите ЧаÑть Легендарного ОдеÑÐ½Ð¸Ñ Ð’Ð¾Ð»ÑˆÐµÐ±Ð½Ð¸ÐºÐ° -achievement.self_destruct=Обратно -achievement.self_destruct.desc=УбейÑÑ Ð¡Ð¾Ð±Ñтвенной Магией -achievement.pig_tornado=Ðе СейчаÑ... -achievement.pig_tornado.desc=Заедьте Ðа Свинье Ð’ Торнадо -achievement.max_out_wand=Полное ОÑнощение -achievement.max_out_wand.desc=Примените макÑимальное количеÑтво улучшений к жезлу маÑтера -achievement.slime_skeleton=Ð›Ð¸Ð¿ÐºÐ°Ñ Ð¡Ð¸Ñ‚ÑƒÐ°Ñ†Ð¸Ñ -achievement.slime_skeleton.desc=Захватите Ñкелета Ñлизьнем -achievement.jam_wizard=Помехи -achievement.jam_wizard.desc=ИÑпользуйте заклинание магичеÑÐºÐ°Ñ Ð³Ð»ÑƒÑˆÐ¸Ð»ÐºÐ° на волшебнике -achievement.identify_spell=Ð¢Ð°Ð¹Ð½Ð°Ñ Ð­ÐºÑпертиза -achievement.identify_spell.wizardry:desc=ИÑпользуйте Ñвиток идентификации Ð´Ð»Ñ Ð½ÐµÐ¸Ð·Ð²ÐµÑтной книги Ð·Ð°ÐºÐ»Ð¸Ð½Ð°Ð½Ð¸Ñ Ð¸Ð»Ð¸ Ñвитка -achievement.element_master=МаÑтер Элементов -achievement.element_master.desc=ИÑпользуйте вÑе Ð·Ð°ÐºÐ»Ð¸Ð½Ð°Ð½Ð¸Ñ Ð»ÑŽÐ±Ð¾Ð³Ð¾ Ñлемента -achievement.anger_wizard=Ты пожалеешь об Ñтом -achievement.anger_wizard.desc=Разозлите волшебника -achievement.defeat_evil_wizard=ПраведноÑть -achievement.defeat_evil_wizard.desc=Победите злого волшебника +achievement.Crystal=Любопытный КриÑталл... +achievement.Crystal.desc=Добудьте МагичеÑкий КриÑталл +achievement.ArcaneInitiate=ПоÑвÑщение Ð’ Магию +achievement.ArcaneInitiate.desc=Создайте Волшебную Палочку Из Золотого Самородка И МагичеÑкого КриÑталла +achievement.Apprentice=Ученик Волшебника +achievement.Apprentice.desc=ИÑпользуйте Фолиант Ðрканы Ð”Ð»Ñ Ð£Ð»ÑƒÑ‡ÑˆÐµÐ½Ð¸Ñ Ð–ÐµÐ·Ð»Ð° +achievement.Master=МаÑтер Магии +achievement.Master.desc=Получите Жезл МаÑтера +achievement.AllSpells=Маг Ð’Ñех ПрофеÑÑий +achievement.AllSpells.desc=ИÑпользуйте Каждое Заклинание Ð’ Игре +achievement.WizardTrade=МагичеÑÐºÐ°Ñ Ð¡Ð´ÐµÐ»ÐºÐ° +achievement.WizardTrade.desc=Купите Предмет У Волшебника +achievement.BuyMasterSpell=Знание-Сила +achievement.BuyMasterSpell.desc=Купите Заклинание МаÑтера У Волшебника +achievement.FreezeBlaze=Ðе Так Жарко +achievement.FreezeBlaze.desc=Заморозьте Блейза +achievement.ChargeCreeper=Это Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð’Ð·Ð¾Ñ€Ð²Ñ‘Ñ‚ÑÑ +achievement.ChargeCreeper.desc="Случайно" ЗарÑдите Крипира +achievement.Frankenstein=Франкенштейн +achievement.Frankenstein.desc=Привратите Свинью Ð’ Свинозомби С Помощью Молнии +achievement.SpecialUpgrade=ЧародейÑкое РемеÑло +achievement.SpecialUpgrade.desc=Применить Специальное Улучшение Ð”Ð»Ñ Ð–ÐµÐ·Ð»Ð° +achievement.CraftFlask=Это ÐœÐ°Ð³Ð¸Ñ Ð’ Бутылке! +achievement.CraftFlask.desc=Создайте Ману Ð’ Бутылке +achievement.Elemental=Стихии +achievement.Elemental.desc=Получите Стихийный Жезл +achievement.ArmourSet=Теперь Ты ÐаÑтоÑщий Волшебник +achievement.ArmourSet.desc=Создайте И Экипируйте Полный Ðабор ОдеÑÐ½Ð¸Ñ Ð’Ð¾Ð»ÑˆÐµÐ±Ð½Ð¸ÐºÐ° +achievement.Legendary=Легендарный +achievement.Legendary.desc=Получите ЧаÑть Легендарного ОдеÑÐ½Ð¸Ñ Ð’Ð¾Ð»ÑˆÐµÐ±Ð½Ð¸ÐºÐ° +achievement.SelfDestruct=Обратно +achievement.SelfDestruct.desc=УбейÑÑ Ð¡Ð¾Ð±Ñтвенной Магией +achievement.PigTornado=Ðе СейчаÑ... +achievement.PigTornado.desc=Заедьте Ðа Свинье Ð’ Торнадо +tile.transportationStone.confirm=Теперь вы будете возвращены Ñюда при иÑпользовании Ð·Ð°ÐºÐ»Ð¸Ð½Ð°Ð½Ð¸Ñ %1$s +tile.transportationStone.invalid=Сначала вы должны Ñделать круг из 8 камней транÑпортировки! - -tile.wizardry:transportation_stone.confirm=Теперь вы будете возвращены Ñюда при иÑпользовании Ð·Ð°ÐºÐ»Ð¸Ð½Ð°Ð½Ð¸Ñ %1$s -tile.wizardry:transportation_stone.invalid=Сначала вы должны Ñделать круг из 8 камней транÑпортировки! - -container.wizardry:arcane_workbench=ЧародейÑкий Стол -container.wizardry:arcane_workbench.apply=Применить -container.wizardry:arcane_workbench.mana=Мана: -container.wizardry:arcane_workbench.upgrades=Применённые УлучшениÑ: +container.arcaneWorkbench=ЧародейÑкий Стол +container.arcaneWorkbench.apply=Применить +container.arcaneWorkbench.mana=Мана: +container.arcaneWorkbench.upgrades=Применённые УлучшениÑ: tier.basic=Ðачинающий tier.apprentice=Ученик @@ -278,333 +256,270 @@ spelltype.minion=Миньон spell.disabled=%1$s было отключенно в конфиге -spell.wizardry:agility=ЛовкоÑть -spell.wizardry:arc=Дуга -spell.wizardry:arrow_rain=Дождь Стрел -spell.wizardry:black_hole=Ð§Ñ‘Ñ€Ð½Ð°Ñ Ð”Ñ‹Ñ€Ð° -spell.wizardry:blink=Блинк -spell.wizardry:blizzard=Метель -spell.wizardry:bubble=Пузыри -spell.wizardry:chain_lightning=Ð¦ÐµÐ¿Ð½Ð°Ñ ÐœÐ¾Ð»Ð½Ð¸Ñ -spell.wizardry:conjure_bow=Призвать Лук -spell.wizardry:conjure_pickaxe=Призвать Кирку -spell.wizardry:conjure_sword=Призвать Меч -spell.wizardry:cure_effects=Эффект Ð›ÐµÑ‡ÐµÐ½Ð¸Ñ -spell.wizardry:darkness_orb=Ð¢Ñ‘Ð¼Ð½Ð°Ñ Ð¡Ñ„ÐµÑ€Ð° -spell.wizardry:dart=Дротик -spell.wizardry:decay=Гниение -spell.wizardry:detonate=Взрыв -spell.wizardry:diamondflesh=ÐÐ»Ð¼Ð°Ð·Ð½Ð°Ñ ÐšÐ¾Ð¶Ð° -spell.wizardry:entrapment=Захват -spell.wizardry:fireball=Огненный Шар -spell.wizardry:firebolt=Огненный Болт -spell.wizardry:firebomb=ÐžÐ³ÐµÐ½Ð½Ð°Ñ Ð‘Ð¾Ð¼Ð±Ð° -spell.wizardry:fire_resistance=ОгеÑтойкоÑть -spell.wizardry:fire_sigil=ÐžÐ³Ð½ÐµÐ½Ð½Ð°Ñ ÐŸÐµÑ‡Ð°Ñ‚ÑŒ -spell.wizardry:fireskin=ÐžÐ³Ð½ÐµÐ½Ð½Ð°Ñ ÐšÐ¾Ð¶Ð° -spell.wizardry:firestorm=Огненный Шторм -spell.wizardry:flame_ray=Дождь ÐžÐ³Ð½Ñ -spell.wizardry:flaming_axe=Огненный Топор -spell.wizardry:flight=Полёт -spell.wizardry:font_of_vitality=ИÑточник Жизненной Силы -spell.wizardry:force_arrow=Ð¡Ð¸Ð»Ð¾Ð²Ð°Ñ Ð¡Ñ‚Ñ€ÐµÐ»Ð° -spell.wizardry:forcefield=Силовое Поле -spell.wizardry:force_orb=Ð¡Ð¸Ð»Ð¾Ð²Ð°Ñ Ð¡Ñ„ÐµÑ€Ð° -spell.wizardry:forests_curse=ПроклÑтие ЛеÑа -spell.wizardry:freeze=Замораживание -spell.wizardry:mind_trick=Обман Разума -spell.wizardry:frost_axe=ЛедÑной Топор -spell.wizardry:frost_ray=ЛедÑной Луч -spell.wizardry:frost_sigil=ЛедÑÐ½Ð°Ñ ÐŸÐµÑ‡Ð°Ñ‚ÑŒ -spell.wizardry:glide=Скольжение -spell.wizardry:greater_heal=Великое ИÑцеление -spell.wizardry:growth_aura=Ðура РоÑта -spell.wizardry:heal=ИÑцеление -spell.wizardry:heal_ally=ИÑцеление Союзника -spell.wizardry:healing_aura=Ðура ИÑÑ†ÐµÐ»ÐµÐ½Ð¸Ñ -spell.wizardry:homing_spark=СамонаводÑщаÑÑÑ Ð˜Ñкра -spell.wizardry:ice_age=Ледниковый Период -spell.wizardry:ice_charge=ЛедÑной ЗарÑд -spell.wizardry:ice_shard=ЛедÑной ОÑколок -spell.wizardry:ice_shroud=ЛедÑÐ½Ð°Ñ ÐšÐ¾Ð¶Ð° -spell.wizardry:ice_statue=ЛедÑÐ½Ð°Ñ Ð¡Ñ‚Ð°Ñ‚ÑƒÑ -spell.wizardry:ignite=ВоÑпламенение -spell.wizardry:invisibility=ÐевидимоÑть -spell.wizardry:invoke_weather=Вызов Погоды -spell.wizardry:ironflesh=Ð–ÐµÐ»ÐµÐ·Ð½Ð°Ñ ÐšÐ¾Ð¶Ð° -spell.wizardry:levitation=Ð›ÐµÐ²Ð¸Ñ‚Ð°Ñ†Ð¸Ñ -spell.wizardry:life_drain=Похищение Жизни -spell.wizardry:light=Свет -spell.wizardry:lightning_arrow=Стрела Молнии -spell.wizardry:lightning_bolt=Удар Молнии -spell.wizardry:lightning_disc=ДиÑк Молнии -spell.wizardry:lightning_hammer=Молот Молнии -spell.wizardry:lightning_ray=Луч Молнии -spell.wizardry:lightning_sigil=Печать Молнии -spell.wizardry:magic_missile=МагичеÑÐºÐ°Ñ Ð Ð°ÐºÐµÑ‚Ð° -spell.wizardry:metamorphosis=Превращение -spell.wizardry:meteor=Метеор -spell.wizardry:mind_control=Контроль Разума -spell.wizardry:none=[ПуÑтой Слот] -spell.wizardry:petrify=Окаменение -spell.wizardry:phase_step=Фазовый Шаг -spell.wizardry:plague_of_darkness=Чума Темноты -spell.wizardry:poison=Отравление -spell.wizardry:poison_bomb=Ð¯Ð´Ð¾Ð²Ð¸Ñ‚Ð°Ñ Ð‘Ð¾Ð¼Ð±Ð° -spell.wizardry:replenish_hunger=ÐаÑыщение -spell.wizardry:ring_of_fire=Кольцо ÐžÐ³Ð½Ñ -spell.wizardry:shadow_ward=Ð¢ÐµÐ½ÐµÐ²Ð°Ñ Ð—Ð°Ñ‰Ð¸Ñ‚Ð° -spell.wizardry:shield=Щит -spell.wizardry:shockwave=Ð£Ð´Ð°Ñ€Ð½Ð°Ñ Ð’Ð¾Ð»Ð½Ð° -spell.wizardry:silverfish_swarm=Рой Чешуйниц -spell.wizardry:slime=Слизь -spell.wizardry:snare=Ловушка -spell.wizardry:snowball=Снежок -spell.wizardry:smoke_bomb=Ð”Ñ‹Ð¼Ð¾Ð²Ð°Ñ Ð‘Ð¾Ð¼Ð±Ð° -spell.wizardry:spark_bomb=Бомба ИÑкр -spell.wizardry:spectral_pathway=Спектральный Путь -spell.wizardry:spider_swarm=Рой Пауков -spell.wizardry:static_aura=СтатичеÑÐºÐ°Ñ Ðура -spell.wizardry:summon_blaze=Призыв Блейза -spell.wizardry:summon_ice_giant=Призыв ЛедÑного Гиганта -spell.wizardry:summon_ice_wraith=Призыв ЛедÑного Призрака -spell.wizardry:summon_iron_golem=Призыв Железного Голема -spell.wizardry:summon_lightning_wraith=Призыв Штормового Призрака -spell.wizardry:summon_phoenix=Призыв ФеникÑа -spell.wizardry:summon_shadow_wraith=Призыв Тёмного Призрака -spell.wizardry:summon_skeleton=Призыв Скелета -spell.wizardry:summon_skeleton_legion=Призыв Легиона Скелета -spell.wizardry:summon_snow_golem=Призыв Снеговика -spell.wizardry:summon_spirit_horse=Призыв Призрачной Лошади -spell.wizardry:summon_spirit_wolf=Призыв Призрачного Волка -spell.wizardry:summon_wither_skeleton=Призыв Скелета-ИÑÑÑƒÑˆÐ¸Ñ‚ÐµÐ»Ñ -spell.wizardry:summon_zombie=Призыв Зомби -spell.wizardry:telekinesis=Телекинез -spell.wizardry:thunderbolt=Штормовой Удар -spell.wizardry:thunderstorm=Гроза -spell.wizardry:tornado=Торнадо -spell.wizardry:transience=БыÑтрота -spell.wizardry:transportation=ТранÑпортировка -spell.wizardry:vanishing_box=ИÑÑ‡ÐµÐ·Ð°ÑŽÑ‰Ð°Ñ ÐšÐ¾Ñ€Ð¾Ð±ÐºÐ° -spell.wizardry:wall_of_frost=Стена Мороза -spell.wizardry:water_breathing=Дыхание Под Водой -spell.wizardry:whirlwind=Вихрь -spell.wizardry:wither=ИÑÑушение -spell.wizardry:wither_skull=Череп ИÑÑÑƒÑˆÐ¸Ñ‚ÐµÐ»Ñ -spell.wizardry:leap=Прыжок -spell.wizardry:pocket_furnace=ÐšÐ°Ñ€Ð¼Ð°Ð½Ð½Ð°Ñ ÐŸÐµÑ‡ÑŒ -spell.wizardry:intimidate=УÑтрашение -spell.wizardry:banish=Изгнание -spell.wizardry:sixth_sense=ШеÑтое ЧувÑтво -spell.wizardry:darkvision=Тёмное Зрение -spell.wizardry:imbue_weapon=Зачарованное Оружие -spell.wizardry:pocket_workbench=Карманный ВерÑтак -spell.wizardry:clairvoyance=ЯÑновидение -spell.wizardry:invigorating_presence=Воодушевление -spell.wizardry:oakflesh=Ð”ÑƒÐ±Ð¾Ð²Ð°Ñ ÐŸÐ»Ð¾Ñ‚ÑŒ -spell.wizardry:flaming_weapon=Пылающее Оружие -spell.wizardry:greater_fireball=Большой Огненный Шар -spell.wizardry:ice_lance=ЛедÑное Копье -spell.wizardry:freezing_weapon=ЛедÑное Оружие -spell.wizardry:ice_spikes=ЛедÑные Шипы -spell.wizardry:lightning_pulse=Ð˜Ð¼Ð¿ÑƒÐ»ÑŒÑ ÐœÐ¾Ð»Ð½Ð¸Ð¸ -spell.wizardry:curse_of_soulbinding=ПроклÑтие СвзÑзанной Души -spell.wizardry:decoy=Приманка -spell.wizardry:arcane_jammer=МагичеÑÐºÐ°Ñ Ð“Ð»ÑƒÑˆÐ¸Ð»ÐºÐ° -spell.wizardry:conjure_armour=ÐŸÑ€Ð¸Ð·Ñ‹Ð²Ð½Ð°Ñ Ð‘Ñ€Ð¾Ð½Ñ -spell.wizardry:group_heal=МаÑÑовое ИÑцеление -spell.wizardry:summon_storm_elemental=Призыв Грозового Ð­Ð»ÐµÐ¼ÐµÐ½Ñ‚Ð°Ð»Ñ -spell.wizardry:lightning_web=Поток Молнии -spell.wizardry:font_of_mana=Купель Маны -spell.wizardry:earthquake=ЗемлетрÑÑение -spell.wizardry:hailstorm=Град +spell.agility=ЛовкоÑть +spell.arc=Дуга +spell.arrow_rain=Дождь Стрел +spell.black_hole=Ð§Ñ‘Ñ€Ð½Ð°Ñ Ð”Ñ‹Ñ€Ð° +spell.blink=Блинк +spell.blizzard=Метель +spell.bubble=Пузыри +spell.chain_lightning=Ð¦ÐµÐ¿Ð½Ð°Ñ ÐœÐ¾Ð»Ð½Ð¸Ñ +spell.conjure_bow=Призвать Лук +spell.conjure_pickaxe=Призвать Кирку +spell.conjure_sword=Призвать Меч +spell.cure_effects=Эффект Ð›ÐµÑ‡ÐµÐ½Ð¸Ñ +spell.darkness_orb=Ð¢Ñ‘Ð¼Ð½Ð°Ñ Ð¡Ñ„ÐµÑ€Ð° +spell.dart=Дротик +spell.decay=Гниение +spell.detonate=Взрыв +spell.diamondflesh=ÐÐ»Ð¼Ð°Ð·Ð½Ð°Ñ ÐšÐ¾Ð¶Ð° +spell.entrapment=Захват +spell.fireball=Огненный Шар +spell.firebolt=Огненный Болт +spell.firebomb=ÐžÐ³ÐµÐ½Ð½Ð°Ñ Ð‘Ð¾Ð¼Ð±Ð° +spell.fire_resistance=ОгеÑтойкоÑть +spell.fire_sigil=ÐžÐ³Ð½ÐµÐ½Ð½Ð°Ñ ÐŸÐµÑ‡Ð°Ñ‚ÑŒ +spell.fireskin=ÐžÐ³Ð½ÐµÐ½Ð½Ð°Ñ ÐšÐ¾Ð¶Ð° +spell.firestorm=Огненный Шторм +spell.flame_ray=Дождь ÐžÐ³Ð½Ñ +spell.flaming_axe=Огненный Топор +spell.flight=Полёт +spell.font_of_vitality=ИÑточник Жизненной Силы +spell.force_arrow=Ð¡Ð¸Ð»Ð¾Ð²Ð°Ñ Ð¡Ñ‚Ñ€ÐµÐ»Ð° +spell.forcefield=Силовое Поле +spell.force_orb=Ð¡Ð¸Ð»Ð¾Ð²Ð°Ñ Ð¡Ñ„ÐµÑ€Ð° +spell.forests_curse=ПроклÑтие ЛеÑа +spell.freeze=Замораживание +spell.frost_axe=ЛедÑной Топор +spell.frost_ray=ЛедÑной Луч +spell.frost_sigil=ЛедÑÐ½Ð°Ñ ÐŸÐµÑ‡Ð°Ñ‚ÑŒ +spell.glide=Скольжение +spell.greater_heal=Великое ИÑцеление +spell.growth_aura=Ðура РоÑта +spell.heal=ИÑцеление +spell.heal_ally=ИÑцеление Союзника +spell.healing_aura=Ðура ИÑÑ†ÐµÐ»ÐµÐ½Ð¸Ñ +spell.homing_spark=СамонаводÑщаÑÑÑ Ð˜Ñкра +spell.ice_age=Ледниковый Период +spell.ice_charge=ЛедÑной ЗарÑд +spell.ice_shard=ЛедÑной ОÑколок +spell.ice_shroud=ЛедÑÐ½Ð°Ñ ÐšÐ¾Ð¶Ð° +spell.ice_statue=ЛедÑÐ½Ð°Ñ Ð¡Ñ‚Ð°Ñ‚ÑƒÑ +spell.ignite=ВоÑпламенение +spell.invisibility=ÐевидимоÑть +spell.invoke_weather=Вызов Погоды +spell.ironflesh=Ð–ÐµÐ»ÐµÐ·Ð½Ð°Ñ ÐšÐ¾Ð¶Ð° +spell.levitation=Ð›ÐµÐ²Ð¸Ñ‚Ð°Ñ†Ð¸Ñ +spell.life_drain=Похищение Жизни +spell.light=Свет +spell.lightning_arrow=Стрела Молнии +spell.lightning_bolt=Удар Молнии +spell.lightning_disc=ДиÑк Молнии +spell.lightning_hammer=Молот Молнии +spell.lightning_ray=Луч Молнии +spell.lightning_sigil=Печать Молнии +spell.magic_missile=МагичеÑÐºÐ°Ñ Ð Ð°ÐºÐµÑ‚Ð° +spell.metamorphosis=Превращение +spell.meteor=Метеор +spell.mind_control=Контроль Разума +spell.none=[ПуÑтой Слот] +spell.petrify=Окаменение +spell.phase_step=Фазовый Шаг +spell.plague_of_darkness=Чума Темноты +spell.poison=Отравление +spell.poison_bomb=Ð¯Ð´Ð¾Ð²Ð¸Ñ‚Ð°Ñ Ð‘Ð¾Ð¼Ð±Ð° +spell.replenish_hunger=ÐаÑыщение +spell.ring_of_fire=Кольцо ÐžÐ³Ð½Ñ +spell.shadow_ward=Ð¢ÐµÐ½ÐµÐ²Ð°Ñ Ð—Ð°Ñ‰Ð¸Ñ‚Ð° +spell.shield=Щит +spell.shockwave=Ð£Ð´Ð°Ñ€Ð½Ð°Ñ Ð’Ð¾Ð»Ð½Ð° +spell.silverfish_swarm=Рой Чешуйниц +spell.slime=Слизь +spell.snare=Ловушка +spell.snowball=Снежок +spell.spark_bomb=Бомба ИÑкр +spell.spectral_pathway=Спектральный Путь +spell.spider_swarm=Рой Пауков +spell.static_aura=СтатичеÑÐºÐ°Ñ Ðура +spell.summon_blaze=Призыв Блейза +spell.summon_ice_giant=Призыв ЛедÑного Гиганта +spell.summon_ice_wraith=Призыв ЛедÑного Призрака +spell.summon_iron_golem=Призыв Железного Голема +spell.summon_lightning_wraith=Призыв Штормового Призрака +spell.summon_phoenix=Призыв ФеникÑа +spell.summon_shadow_wraith=Призыв Тёмного Призрака +spell.summon_skeleton=Призыв Скелета +spell.summon_skeleton_legion=Призыв Легиона Скелета +spell.summon_snow_golem=Призыв Снеговика +spell.summon_spirit_horse=Призыв Призрачной Лошади +spell.summon_spirit_wolf=Призыв Призрачного Волка +spell.summon_wither_skeleton=Призыв Скелета-ИÑÑÑƒÑˆÐ¸Ñ‚ÐµÐ»Ñ +spell.summon_zombie=Призыв Зомби +spell.telekinesis=Телекинез +spell.thunderbolt=Штормовой Удар +spell.thunderstorm=Гроза +spell.tornado=Торнадо +spell.transience=БыÑтрота +spell.transportation=ТранÑпортировка +spell.vanishing_box=ИÑÑ‡ÐµÐ·Ð°ÑŽÑ‰Ð°Ñ ÐšÐ¾Ñ€Ð¾Ð±ÐºÐ° +spell.wall_of_frost=Стена Мороза +spell.water_breathing=Дыхание Под Водой +spell.whirlwind=Вихрь +spell.wither=ИÑÑушение +spell.wither_skull=Череп ИÑÑÑƒÑˆÐ¸Ñ‚ÐµÐ»Ñ +spell.agility.desc=Дает Заклинателю Более Ð’Ñ‹Ñокую СкороÑть ÐŸÐµÑ€ÐµÐ´Ð²Ð¸Ð¶ÐµÐ½Ð¸Ñ Ð˜ Большой Прижок на 30 Секунд. +spell.arc.desc=Ð’Ñ‹Ñтреливает ИÑкрой Молнии Ð’ Цель +spell.arrow_rain.desc="Лучники, огонь!" +spell.black_hole.desc=Разрывай РеальноÑть Ðа ЧаÑти +spell.blink.desc=Телепортирует Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ð’ Любой Блок, Ðа Который Он Указывает, Ð’ Определенном РадиуÑе. +spell.blizzard.desc=Создает Зону Закрученного ЛедÑного Ветра, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð—Ð°Ð¼ÐµÐ´Ð»Ñет И ПоÑтоÑнно Повреждает Ð’Ñе, Что Попало Внутрь. Заклинатель ÐевоÑприимчив К Урону, Ðо Ð’Ñе Еще ЗамедлÑетÑÑ. +spell.bubble.desc=СтрелÑет Потоком Пузырьков, Который Помещает СущеÑтво Ð’ Большой Пузырь, При Это Поднимает Его. Цель Будет Падать Или ПроÑто Получит Урон. +spell.chain_lightning.desc=Ð’Ñ‹Ñтреливает ИÑкру Молнии У Цели, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð—Ð°Ñ‚ÐµÐ¼ ЦеплÑетÑÑ Ðš Дополнительным ЦелÑм До Двух Раз. +spell.conjure_bow.desc=Создает Спектральный Лук С Ðеограниченными Стрелами, Который ДлитÑÑ 30 Секунд. +spell.conjure_pickaxe.desc=Создает Спектральную Кирку Равной Силы Железной Кирке, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð”Ð»Ð¸Ñ‚ÑÑ 30 СÑекунд. +spell.conjure_sword.desc=Создает Спектральный Меч Одинаковой Силы С Железным Мечом, Который ДлитÑÑ 30 Секунд. +spell.cure_effects.desc=УдалÑет Ð’Ñе Эффекты Зелий, Которые Ð’ ÐаÑтоÑщее Ð’Ñ€ÐµÐ¼Ñ Ð’Ð¾Ð·Ð´ÐµÐ¹Ñтвуют Ðа ЗаклинателÑ, Хорошие Или Плохие. +spell.darkness_orb.desc=Ð’Ñ‹Ñтреливает Медленно ПеремещающимÑÑ Ð‘Ð¾Ð»Ñ‚Ð¾Ð¼ Тёмной Энергии Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете, Которое Вызывает Гниение Ð’Ñего, Что Попадает. +spell.dart.desc=Ð’Ñ‹Ñтреливает Дротик Ð’ Том Ðаправлении, Ð’ Котором Ð’Ñ‹ Указываете, Которое ÐаноÑит Урон И ОÑлаблÑет Его Цель. +spell.decay.desc=Создает ПÑтно Гнили Ðа Земле, Которое Заражает Любое СущеÑтво, Которое Его КаÑаетÑÑ, Ð’Ñ‹Ð·Ñ‹Ð²Ð°Ñ Ð”Ð»Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ð¹ Урон Со Временем И РаÑпроÑтранÑÑ Ð‘Ð¾Ð»ÑŒÑˆÐµ Гнили, Где Бы Он Ðи Ходил. +spell.detonate.desc=Вызывает Взрыв, Ð’ Указанном МеÑте, ÐаноÑÑ Ð£Ñ€Ð¾Ð½ Ð’Ñем ÐаходÑщимÑÑ ÐŸÐ¾Ð±Ð»Ð¸Ð·Ð¾Ñти СущеÑтвам, Ð’ÐºÐ»ÑŽÑ‡Ð°Ñ Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ, ЕÑли Они Слишком Близко. +spell.diamondflesh.desc="Твои Стрелы Мне Ðе ПодходÑÑ‚!" +spell.entrapment.desc=Заманивает Цель Ð’ Сферу Темноты, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐŸÐ¾Ð´Ð½Ð¸Ð¼Ð°ÐµÑ‚ Её Вверх И ПоÑтоÑнно Её Повреждает. +spell.fireball.desc=ЗапуÑкает Огненный Шар Ð’ Том Ðаправлении, Ð’ Которое Ð’Ñ‹ Указали. +spell.firebolt.desc=СтрелÑет Ðа Ðебольшом РаÑÑтоÑнии От ВаÑ. +spell.firebomb.desc=БраÑает Зажигательную Бомбу Ð’ Ðаправлении, Которое Ð’Ñ‹ Указываете, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð’Ð·Ñ€Ñ‹Ð²Ð°ÐµÑ‚ÑÑ ÐŸÑ€Ð¸ Ударе, ÐŸÐ¾Ð´Ð¶Ð¸Ð³Ð°Ñ Ð¦ÐµÐ»Ð¸. +spell.fire_resistance.desc=Даёт Сопротивление Огню Ðа 30% +spell.fire_sigil.desc=Помещает МагичеÑкую Ловушку ÐžÐ³Ð½Ñ Ðа Землю, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐаноÑит Урон И Поджигает СущеÑтво, Которое ÐаÑтупило Ðа Ловушку +spell.fireskin.desc=Покрывает Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ ÐžÐ³Ð½Ñ‘Ð¼ Ðа 30 Секунд. ЕÑли Заклинатель Будет Ðтакован, То Враг ЗагоритÑÑ. +spell.firestorm.desc="Я Дракон." +spell.flame_ray.desc=Создает Поток Пламени Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указали, Который Поджигает И ПоÑтоÑнно Повреждает Цели. +spell.flaming_axe.desc=Создает Огненный Топор, Который Поджигает Врагов При Попадании. ДлитÑÑ 30 Секунд. +spell.flight.desc=ПарÑщий, Как Орёл. +spell.font_of_vitality.desc=Это ПотрÑÑающе. +spell.force_arrow.desc=СтрелÑет Стрелой Силы Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете. +spell.forcefield.desc=Создает Силовое Поле Вокруг ЗаклинателÑ, Который Отталкивает СущеÑтв И ОтклонÑет СнарÑды. +spell.force_orb.desc=ЗапуÑкает Сферу Силы, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐаноÑит Урон И ОтбраÑывает Близких СущеÑтв При Ударе. +spell.forests_curse.desc="Как Ты ПоÑмел Войти Ð’ Мой ЛеÑ?!" +spell.freeze.desc=Замораживает Цель Ðа 10 Секунд. Также Заморозит Воду И СоздаÑÑ‚ Снег Ðа Земле. +spell.frost_axe.desc=Создает ЛедÑной Топор, Который Замораживает Врагов При Попадании. ДлитÑÑ 30 Секунд. +spell.frost_ray.desc=Создает Поток Мороза Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете, Который ЗамедлÑет И ПоÑтоÑнно Повреждает Цели. +spell.frost_sigil.desc=Помещает МагичеÑкую ЛедÑную Ловушку Ðа Землю, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐаноÑит Урон И Замораживает СущеÑтво, Которое ÐаÑтупило Ðа Ðеё. +spell.glide.desc=ПозволÑет Заклинателю Скользить Вниз, ÐаходÑÑÑŒ Ð’ Воздухе, Ð£Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°Ñ ÐšÐ½Ð¾Ð¿ÐºÑƒ ИÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐŸÑ€ÐµÐ´Ð¼ÐµÑ‚Ð°. +spell.greater_heal.desc=ВоÑÑтанавливает Заклинателю 4 Сердца. +spell.growth_aura.desc=Выращивает Ð’Ñе Зерновые Культуры РÑдом С Заклинателем. +spell.heal.desc=ИÑцелÑет Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ðа 2 Сердца. +spell.heal_ally.desc=ВоÑÑтанавливает Цели 2 С Половиной Сердца. +spell.healing_aura.desc=Создает Зону ИÑцелÑющей Энергии, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð’Ð¾ÑÑтанавливает Здоровье Кого-либо Внутри Ðего, Кроме Ðежити, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐœÐµÐ´Ð»ÐµÐ½Ð½Ð¾ Получает Урон. +spell.homing_spark.desc=Создает Плавающую ИÑкру, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð”Ð²Ð¸Ð¶ÐµÑ‚ÑÑ Ðš Врагам. +spell.ice_age.desc="Ð’Ñ‹ Замерзнете ÐавÑегда!" +spell.ice_charge.desc=ЗапуÑкает ЗарÑд Льда, Который ВзрываетÑÑ ÐŸÑ€Ð¸ Ударе, Ð—Ð°Ð¼Ð¾Ñ€Ð°Ð¶Ð¸Ð²Ð°Ñ Ð‘Ð»Ð¸Ð·Ð»ÐµÐ¶Ð°Ñ‰Ð¸Ñ… СущеÑтв И ВыпуÑÐºÐ°Ñ ÐžÑколки Во Ð’Ñех ÐаправлениÑÑ…. +spell.ice_shard.desc=Ð’Ñ‹Ñтреливает ЛедÑной ОÑколок Ð’ Том Ðаправлении, Ð’ Котором Ð’Ñ‹ Указали, Который ÐаноÑит Урон И ЗамедлÑет Цель При Попадании. +spell.ice_shroud.desc=Окутывает Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ð’Ð¾ Льду Ðа 30 Секунд, Ð—Ð°Ð¼Ð¾Ñ€Ð°Ð¶Ð¸Ð²Ð°Ñ Ð’Ñе, Что Попадает Или Попадает. +spell.ice_statue.desc=Замораживает Цель Ðа 20 Секунд Или До Тех Пор, Пока Она Ðе ВырветÑÑ Ðаружу. Цель Ðе Может ДвигатьÑÑ Ð˜Ð»Ð¸ Делать Что-либо Ð’ Замороженном СоÑтоÑнии, Ðо Также ÐевоÑприимчива К Любому Урону. +spell.ignite.desc=УÑтанавливает Огонь Ð’ Течение 10 Секунд. Также Работает Как Кремень И Сталь. +spell.invisibility.desc=Делает Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ðевидимым Ð’ Течение 30 Секунд. +spell.invoke_weather.desc=ИзменÑет Погоду Ð’ Мире. +spell.ironflesh.desc=Увеличивает Сопротивление К Оглушению Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ðа 30 Секунд. +spell.levitation.desc=Поднимает Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ð’Ð²ÐµÑ€Ñ… При Ðажатой Кнопке ИÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐŸÑ€ÐµÐ´Ð¼ÐµÑ‚Ð°. Также Будет Ðейтрализован Урон От ПадениÑ, ЕÑли Он ИÑпользуетÑÑ Ð”Ð¾ Удара Об Землю. +spell.life_drain.desc=Создает Поток ИÑÑушающей Энергии Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете, Который ИÑтощает Жизнь Цели И ИÑпользует Её Ð”Ð»Ñ ÐŸÐ¾Ñтепенного ВоÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð—Ð´Ð¾Ñ€Ð¾Ð²ÑŒÑ. +spell.light.desc=Создает МагичеÑкую Точку Света, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐžÑвещает Окружающую ОблаÑть. ДлитÑÑ 30 Секунд. +spell.lightning_arrow.desc=СтрелÑет Стрелой Молнии Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете. +spell.lightning_bolt.desc=ЗаÑтавлÑет Молнию Ударить Туда, Куда Ð’Ñ‹ Указываете. +spell.lightning_disc.desc=ПоÑылает ДиÑк Молнии, ЛетÑщий Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указали И Ищет Цели. +spell.lightning_hammer.desc="Я Поражу Ð¢ÐµÐ±Ñ Ð“Ð½ÐµÐ²Ð¾Ð¼ ÐебеÑ!" +spell.lightning_ray.desc=Создает Поток Молнии Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете, Который ПоÑтоÑнно Повреждает Цели. +spell.lightning_sigil.desc=Помещает МагичеÑкую МолниеноÑную Ловушку Ðа Землю, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐаноÑит Урон СущеÑтву, Которое ÐаÑтупило Ðа Ловушку, И Приковывает Молнии К Другим Близлежащим СущеÑтвам. +spell.magic_missile.desc=Ð’Ñ‹Ñтреливает МагичеÑкий ЗарÑд Ð’ Том Ðаправлении, Ð’ Котором Ð’Ñ‹ Указали. +spell.metamorphosis.desc=ИзменÑет Цель Ð’ Другую Форму. Работает Только Ðа Ðекоторых СущеÑтвах. +spell.meteor.desc=Ðекоторые Волшебники ПроÑто ХотÑÑ‚, Чтобы Мир Горел ... +spell.mind_control.desc=Контролирует Ум Цели, ЗаÑтавлÑÑ Ð•Ñ‘ Ðтаковать Ближайшую Живую Цель, Отличную От ЗаклинателÑ. Когда Это СущеÑтво Будет Убито, Цель ВернетÑÑ Ðš Ðормальной Жизни. +spell.none.desc=Чтобы Получить Книгу Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ð½Ð¸Ñ /give command, иÑпользовать метаданные: /give [player] wizardry:spell_book 1 [spell id] (if you found this book in a chest, some other mod has messed things up). +spell.petrify.desc=Повергает Цель Ð’ Камень До Следующего Заката Или Пока Ðе Будет Разбит. Цель Ðе Может ДвигатьÑÑ Ð˜Ð»Ð¸ Делать Что-либо, Пока Она Окаменела, Ðо Также ÐевоÑприимчива К Любому Урону. +spell.phase_step.desc=Телепортирует Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ð§ÐµÑ€ÐµÐ· Стену Толщиной 1 Блок Перед Ðим. Улучшение ДальноÑти Увеличит Толщину, Через Которую Ð’Ñ‹ Сможете ТелепортироватьÑÑ. +spell.plague_of_darkness.desc=Тьма Поглотит Их Ð’Ñех... +spell.poison.desc=Ð’Ñ‹Ñтреливает Яд Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете. +spell.poison_bomb.desc=БроÑает Ядовитую Бомбу Ð’ Ðаправлении, Которое Ð’Ñ‹ Указываете, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð’Ð·Ñ€Ñ‹Ð²Ð°ÐµÑ‚ÑÑ ÐŸÑ€Ð¸ Ударе, ОтравлÑÑ Ð‘Ð»Ð¸Ð·ÐºÐ¸Ñ… СущеÑтв. +spell.replenish_hunger.desc=ПополнÑет Ð—Ð°Ð¿Ð°Ñ ÐŸÐ¸Ñ‰Ð¸ Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ðа 6 Пунктов Голода. +spell.ring_of_fire.desc=Создает Огненное Кольцо Вокруг ЗаклинателÑ, ÐаноÑÑ Ð£Ñ€Ð¾Ð½ Ð’Ñем Ближайшим Противникам И ÐŸÐ¾Ð´Ð¶Ð¸Ð³Ð°Ñ Ð˜Ñ…. +spell.shadow_ward.desc=Создает Стену Тьмы Перед Заклинателем, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐаноÑит Ðападающему Половину Ð’Ñего ВходÑщего Урона. +spell.shield.desc=Создает Защитный Барьер Силы, Который Блокирует СнарÑды И Магию. Также Дает Заклинателю Слабый Эффект СопротивлениÑ. +spell.shockwave.desc=Бум. +spell.silverfish_swarm.desc="ÐÐÐÐÐ! ИХ ОЧЕÐЬ МÐОГО!" +spell.slime.desc=Охватывает Цель Слизью, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð—Ð°Ð¼ÐµÐ´Ð»Ñет И ПоÑтоÑнно Её Повреждает. Слизь РазрываетÑÑ Ð§ÐµÑ€ÐµÐ· 10 Секунд. +spell.snare.desc=УÑтанавливает Ловушку Ðа Земле, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐаноÑит Урон И Кратко ЗамедлÑет СущеÑтво, Которое ÐаÑтупило Ðа Ловушку. +spell.snowball.desc=Launches a snowball in the direction you are pointing. +spell.spark_bomb.desc=ЗапуÑкает Бомбу ИÑкр Ð’ Том Ðаправлении, Ð’ Котором Ð’Ñ‹ Указываете. ИÑкры ПоÑвлÑÑŽÑ‚ÑÑ Ð£ Ближайших Противников При Ударе. +spell.spectral_pathway.desc=Создает Перед Вами Ðеразрушимый МагичеÑкий МоÑÑ‚, Который ПроÑтираетÑÑ Ðа 15 Блоков. Через 60 Секунд МоÑÑ‚ ИÑчезает. +spell.spider_swarm.desc=Призывает Рой Ядовитых Пауков, Чтобы СражатьÑÑ Ð—Ð° ВаÑ. Пауки ИÑчезнут Через 30 Секунд Или ЕÑли Они Будут Убиты. +spell.static_aura.desc=Окружает Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ ÐœÐ¾Ð»Ð½Ð¸ÐµÐ¹ Ð’ Течение 30 Секунд, СтрелÑет ИÑкрами Молнии Во Ð’Ñе, Что Ударит ВаÑ. +spell.summon_blaze.desc=Призывает Блейза, Чтобы СражатьÑÑ Ð—Ð° ВаÑ. Блейз ИÑчезнет Через 30 Секунд Или ЕÑли Он Будет Убит. +spell.summon_ice_giant.desc="Разбей Их!" +spell.summon_ice_wraith.desc=Призывает ЛедÑного Призрака, Который СражаетÑÑ Ð—Ð° ВаÑ. ЛедÑной Призрак ИÑчезнет Через 30 Секунд Или ЕÑли Он Будет Убит. +spell.summon_iron_golem.desc=ÐвтоматичеÑкий Ðвтономный Ðвтомат. +spell.summon_lightning_wraith.desc=Призывает МолниеноÑного Призрака СражатьÑÑ Ð—Ð° ВаÑ. МолниеноÑный Призрак ИÑчезнет Через 30 Секунд Или ЕÑли Он Будет Убит. +spell.summon_phoenix.desc=Из Пепла... +spell.summon_shadow_wraith.desc=Призывает Тёмного Призрака, Который Будет СражатьÑÑ Ð—Ð° ВаÑ. +spell.summon_skeleton.desc=Призывает Скелета, Который СражаетÑÑ Ð—Ð° ваÑ. Скелет ИÑчезнет Через 30 Секунд Или ЕÑли Он Будет Убит. +spell.summon_skeleton_legion.desc="ВоÑÑтань, ÐÑ€Ð¼Ð¸Ñ Ðежети!" +spell.summon_snow_golem.desc=Создает Снежного Голема, Который СражаетÑÑ Ð—Ð° ВаÑ. ДлитÑÑ Ð”Ð¾ Тех Пор, Пока Ðе Умрет Снежный Голем. +spell.summon_spirit_horse.desc=Призывает Ð”Ð»Ñ Ð’Ð°Ñ Ð’ÐµÑ€Ñ…Ð¾Ð²ÑƒÑŽ Лошадь. ÐŸÑ€Ð¸Ð·Ñ€Ð°Ñ‡Ð½Ð°Ñ Ð›Ð¾ÑˆÐ°Ð´ÑŒ ИÑчезнет Через Ðекоторое Ð’Ñ€ÐµÐ¼Ñ ÐŸÐ¾Ñле Того, Как Ð’Ñ‹ С Ðеё Слезите, Или Ð’Ñ‹ Можете Убрать Её С Помощью Жезла - Щелкните Правой Кнопкой Мыши Ðа Ðей. +spell.summon_spirit_wolf.desc=Призывает Спутника Духа Волка, Который СражаетÑÑ Ð—Ð° ВаÑ. Призрачный Волк ИÑчезнет, Только ЕÑли Его Убьют, Или Ð’Ñ‹ Можете Его Убрать, Щелкнув Правой Кнопкой Мыши Ðа Ðём С Помощью Жезла. +spell.summon_wither_skeleton.desc=Призывает Скелета-ИÑÑушителÑ, Который СражаетÑÑ Ð—Ð° ВаÑ. Скелет-ИÑÑушитель ИÑчезнет Через 30 Секунд Или ЕÑли Он Будет Убит. +spell.summon_zombie.desc=Призывает Зомби, Который СражаетÑÑ Ð—Ð° ВаÑ. Зомби ИÑчезнет Через 30 Секунд Или ЕÑли Он Будет Убит. +spell.telekinesis.desc=Перемещает Объект Или Другой Маленький Объект К Себе Или Щелкает Правой Кнопкой Мыши Ðа Блоке,Ðа Который Ð’Ñ‹ Смотрите. +spell.thunderbolt.desc=СтрелÑет Громом, Который ОтбраÑывает Цели. +spell.thunderstorm.desc="МУХÐÐ¥ÐÐ¥ÐÐ¥ÐÐ¥!" +spell.tornado.desc=РазвÑзывает Торнадо Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете, Который БроÑает Что-либо Ðа Своем Пути Ð’ Ðебо. +spell.transience.desc=Делает Переход Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ðа 20 Секунд. Заклинатель ÐевоÑприимчив Ко Ð’Ñему Урону Ð’ Переходный Период, Ðо Ðе Может Сломать Или ПомеÑтить Блоки Или ÐанеÑти Какой-либо Урон. +spell.transportation.desc=ТранÑпортирует Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ð’ Запомненный Каменный Круг. Чтобы ИÑпользовать Это Заклинание, Сделайте Круг Камней ТранÑпортировки, Затем Щелкните Правой Кнопкой Мыши С Помощью Жезла. +spell.vanishing_box.desc=Grants the caster access to their ender chest storage. +spell.wall_of_frost.desc=Зима У Ð’Ð°Ñ ÐŸÐ¾Ð´ Рукой. +spell.water_breathing.desc=ПозволÑет Заклинателю Дышать Под Водой Ð’ Течение 60 Секунд. +spell.whirlwind.desc=ЗаÑтавлÑет Цель Взлететь Вверх Далеко От Ð’Ð°Ñ Ðа СкороÑти. +spell.wither.desc=СтрелÑет Лучом Тьмы, Который УвÑдает Ð’ÑÑ‘, К Чему Он ПрикаÑаетÑÑ. +spell.wither_skull.desc=ЗапуÑкает Череп ИÑÑÑƒÑˆÐ¸Ñ‚ÐµÐ»Ñ Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете. +spell.invoke_weather.sun=Дождь Ðачинает ОÑтанавливатьÑÑ ... +spell.invoke_weather.rain=ÐебеÑа ОткрываютÑÑ ... +spell.transportation.missing=Ваш Запомненный Каменный Круг ОтÑутÑтвует Или Затруднен ... +spell.transportation.undefined=Ð’Ñ‹ Должны Сначала Запомнить МеÑтоположение Каменного Круга! +spell.transportation.wrongdimension=Ваш Запомненный Каменный Круг ÐаходитÑÑ Ð’ Другом Измерении ... - -spell.wizardry:agility.desc=Дает Заклинателю Более Ð’Ñ‹Ñокую СкороÑть ÐŸÐµÑ€ÐµÐ´Ð²Ð¸Ð¶ÐµÐ½Ð¸Ñ Ð˜ Большой Прыжок на 30 Секунд. -spell.wizardry:hailstorm.desc=Именно во Ð²Ñ€ÐµÐ¼Ñ Ð’ÐµÐ»Ð¸ÐºÐ¾Ð¹ зимы третьего века маги льда открыли Ñвою иÑтинную Ñилу. -spell.wizardry:earthquake.desc=ÐаÑтоÑщий маÑтер магии земли может двигать горы. -spell.wizardry:font_of_mana.desc="Мы были наполнены интенÑивной магичеÑкой Ñнергией, поÑвлÑющейÑÑ Ð¸Ð· центра...- ВыпиÑка из дневника забытого мага; оÑÑ‚Ð°Ð»ÑŒÐ½Ð°Ñ Ñ‡Ð°Ñть Ñтраницы Ñгорела. -spell.wizardry:lightning_web.desc="СфокуÑируйтеÑÑŒ. Ðаправьте шторм в вашем разуме через вашу палочку и дайте волю Ñвоей ÑроÑти." -spell.wizardry:summon_storm_elemental.desc="Грозовой Элементаль: древнее проÑвление Ñлементов, он врÑд ли может Ñодержать грубую Ñилу, ÑбивающуюÑÑ Ð²Ð½ÑƒÑ‚Ñ€Ð¸ него."- РуководÑтво маÑтера по тайным ÑущеÑтвам, том I_i -spell.wizardry:group_heal.desc=ВоÑÑтанавливает 3 Ñердца заклинателю и вÑем близлежащим Ñоюзникам и призванным ÑущеÑтвам. -spell.wizardry:conjure_armour.desc=Создаёт Ñпектральную броню вокруг Ð·Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ñ€Ð°Ð²Ð½ÑƒÑŽ по защите железной. Заклинание длитÑÑ 60 Ñекунд. Заклинатель должен иметь пуÑтой Ñлот Ð´Ð»Ñ Ð±Ñ€Ð¾Ð½Ð¸. -spell.wizardry:arcane_jammer.desc=Запрещает иÑпользовать магию цели в течение 15 Ñекунд. -spell.wizardry:decoy.desc=Создает иллюзорный клон заклинателÑ, который заÑтавлÑет мобов атаковать его. Приманка иÑчезнет через 30 Ñекунд. -spell.wizardry:curse_of_soulbinding.desc=СвÑзывает души Ð·Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ð¸ ÑущеÑтва в ÑледÑтвии чего ÑущеÑтво получает тот же урон, что и заклинатель. ДлитÑÑ Ð´Ð¾ тех пор, пока ÑущеÑтво или заклинатель не умрёт. -spell.wizardry:lightning_pulse.desc=ЗарÑжает землю вокруг Ð·Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ð¼Ð¾Ð»Ð½Ð¸ÐµÐ¹, Ð¿Ð¾Ð²Ñ€ÐµÐ¶Ð´Ð°Ñ Ð¸ Ð¾Ñ‚Ñ‚Ð°Ð»ÐºÐ¸Ð²Ð°Ñ Ð±Ð»Ð¸Ð·Ð»ÐµÐ¶Ð°Ñ‰Ð¸Ñ… ÑущеÑтв. -spell.wizardry:ice_spikes.desc=Призывает бритвенно-оÑтрые ледÑные шипы из-под земли в точке вашего курÑора, которые впиваютÑÑ Ð² любых ÑущеÑтв и Ñдерживают их. -spell.wizardry:freezing_weapon.desc=Временно наполнÑет первое оружие на панели Ð·Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ñилой льда, заÑтавлÑÑ ÐµÐ³Ð¾ замораживать Ñвоих жертв. ÐœÐ°Ð³Ð¸Ñ Ð¸Ñчезает через 45 Ñекунд. -spell.wizardry:ice_lance.desc=СтрелÑет большим копьём льда в направлении вашего курÑора,которе замедлÑет врага и наноÑит урон. -spell.wizardry:greater_fireball.desc=ЗапуÑкает большой огненный шар в направлении вашего курÑора, который взрываетÑÑ Ð¿Ñ€Ð¸ ударе. -spell.wizardry:flaming_weapon.desc=Временно наполнÑет первое оружие панели Ð·Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ñилой пламени, заÑтавлÑÑ ÐµÐ³Ð¾ поджигать Ñвоих жертв. ÐœÐ°Ð³Ð¸Ñ Ð¸Ñчезает через 45 Ñекунд. -spell.wizardry:oakflesh.desc=Улучшает Ñопротивление Ð·Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ð² течение 30 Ñекунд. -spell.wizardry:invigorating_presence.desc=Дарует заклинателю и вÑем ближайшим Ñоюзникам повышенную Ñилу в течение 45 Ñекунд. -spell.wizardry:clairvoyance.desc=Показывает путь к запоминающемуÑÑ Ð¼ÐµÑтоположению. Когда заклинание выбрано, приÑеÑть-Ð¿Ñ€Ð°Ð²Ð°Ñ ÐºÐ½Ð¾Ð¿ÐºÐ° мыши на блок, чтобы уÑтановить меÑтоположение. ИÑпользуйте заклинание, чтобы показать путь. Путь иÑчезнет через 90 Ñекунд. -spell.wizardry:pocket_workbench.desc=ПозволÑет заклинателю Ñоздавать предметы, так же как и в верÑтаке. -spell.wizardry:imbue_weapon.desc=Временно наполнÑет магией первое оружие на панели заклинателÑ, Ð´ÐµÐ»Ð°Ñ ÐµÐ³Ð¾ более Ñффективным. ÐœÐ°Ð³Ð¸Ñ Ð¸Ñчезает через 45 Ñекунд. -spell.wizardry:darkvision.desc=Дает заклинателю ночное зрение в течение 45 Ñекунд. -spell.wizardry:sixth_sense.desc=ПозволÑет заклинателю ощущать раÑположение близлежащих ÑущеÑтв, даже через Ñтены, в течение 20 Ñекунд. -spell.wizardry:banish.desc=Телепортирует цель против Ñвоей воли в Ñлучайное меÑто в пределах определенного диапазона. -spell.wizardry:arc.desc=Ð’Ñ‹Ñтреливает ИÑкрой Молнии Ð’ Цель -spell.wizardry:intimidate.desc=ИÑпуÑкает уÑтрашающее рычание, которое заÑтавлÑет близлежащих ÑущеÑтв убегать в Ñтрахе. Страх пораженных ÑущеÑтв воÑÑтановитÑÑ Ñ‡ÐµÑ€ÐµÐ· 30 Ñекунд. -spell.wizardry:arrow_rain.desc="Лучники, огонь!" -spell.wizardry:leap.desc=ЗаÑтавлÑет Ð·Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ð¿Ñ€Ñ‹Ð³Ð°Ñ‚ÑŒ вверх на неÑколько блоков и немного вперед. -spell.wizardry:black_hole.desc=Разрывай РеальноÑть Ðа ЧаÑти -spell.wizardry:blink.desc=Телепортирует Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ð’ Любой Блок, Ðа Который Он Указывает, Ð’ Определенном РадиуÑе. -spell.wizardry:blizzard.desc=Создает Зону Закрученного ЛедÑного Ветра, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð—Ð°Ð¼ÐµÐ´Ð»Ñет И ПоÑтоÑнно Повреждает Ð’Ñе, Что Попало Внутрь. Заклинатель ÐевоÑприимчив К Урону, Ðо Ð’Ñе Еще ЗамедлÑетÑÑ. -spell.wizardry:bubble.desc=СтрелÑет Потоком Пузырьков, Который Помещает СущеÑтво Ð’ Большой Пузырь, При Это Поднимает Его. Цель Будет Падать Или ПроÑто Получит Урон. -spell.wizardry:chain_lightning.desc=Ð’Ñ‹Ñтреливает ИÑкру Молнии У Цели, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð—Ð°Ñ‚ÐµÐ¼ ЦеплÑетÑÑ Ðš Дополнительным ЦелÑм До Двух Раз. -spell.wizardry:conjure_bow.desc=Создает Спектральный Лук С Ðеограниченными Стрелами, Который ДлитÑÑ 30 Секунд. -spell.wizardry:conjure_pickaxe.desc=Создает Спектральную Кирку Равной Силы Железной Кирке, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð”Ð»Ð¸Ñ‚ÑÑ 30 СÑекунд. -spell.wizardry:conjure_sword.desc=Создает Спектральный Меч Одинаковой Силы С Железным Мечом, Который ДлитÑÑ 30 Секунд. -spell.wizardry:cure_effects.desc=УдалÑет Ð’Ñе Эффекты Зелий, Которые Ð’ ÐаÑтоÑщее Ð’Ñ€ÐµÐ¼Ñ Ð’Ð¾Ð·Ð´ÐµÐ¹Ñтвуют Ðа ЗаклинателÑ, Хорошие Или Плохие. -spell.wizardry:darkness_orb.desc=Ð’Ñ‹Ñтреливает Медленно ПеремещающимÑÑ Ð‘Ð¾Ð»Ñ‚Ð¾Ð¼ Тёмной Энергии Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете, Которое Вызывает Гниение Ð’Ñего, Что Попадает. -spell.wizardry:dart.desc=Ð’Ñ‹Ñтреливает Дротик Ð’ Том Ðаправлении, Ð’ Котором Ð’Ñ‹ Указываете, Которое ÐаноÑит Урон И ОÑлаблÑет Его Цель. -spell.wizardry:decay.desc=Создает ПÑтно Гнили Ðа Земле, Которое Заражает Любое СущеÑтво, Которое Его КаÑаетÑÑ, Ð’Ñ‹Ð·Ñ‹Ð²Ð°Ñ Ð”Ð»Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ñ‹Ð¹ Урон Со Временем И РаÑпроÑтранÑÑ Ð‘Ð¾Ð»ÑŒÑˆÐµ Гнили, Где Бы Он Ðи Ходил. -spell.wizardry:detonate.desc=Вызывает Взрыв, Ð’ Указанном МеÑте, ÐаноÑÑ Ð£Ñ€Ð¾Ð½ Ð’Ñем ÐаходÑщимÑÑ ÐŸÐ¾Ð±Ð»Ð¸Ð·Ð¾Ñти СущеÑтвам, Ð’ÐºÐ»ÑŽÑ‡Ð°Ñ Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ, ЕÑли Они Слишком Близко. -spell.wizardry:diamondflesh.desc="Твои Стрелы Мне Ðе ПодходÑÑ‚!" -spell.wizardry:smoke_bomb.desc=ЗапуÑкает дымовую бомбу в направлении вашего курÑора, ÐºÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð²Ð·Ñ€Ñ‹Ð²Ð°ÐµÑ‚ÑÑ Ð²Ñ‹Ð¿ÑƒÐºÐ°Ñ Ð´Ñ‹Ð¼ и оÑлеплÑÑ Ð±Ð»Ð¸Ð·Ð»ÐµÐ¶Ð°Ñ‰Ð¸Ñ… ÑущеÑтв на короткое времÑ. -spell.wizardry:entrapment.desc=Заманивает Цель Ð’ Сферу Темноты, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐŸÐ¾Ð´Ð½Ð¸Ð¼Ð°ÐµÑ‚ Её Вверх И ПоÑтоÑнно Её Повреждает. -spell.wizardry:fireball.desc=ЗапуÑкает Огненный Шар Ð’ Том Ðаправлении, Ð’ Которое Ð’Ñ‹ Указали. -spell.wizardry:firebolt.desc=СтрелÑет Ðа Ðебольшом РаÑÑтоÑнии От ВаÑ. -spell.wizardry:firebomb.desc=БраÑает Зажигательную Бомбу Ð’ Ðаправлении, Которое Ð’Ñ‹ Указываете, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð’Ð·Ñ€Ñ‹Ð²Ð°ÐµÑ‚ÑÑ ÐŸÑ€Ð¸ Ударе, ÐŸÐ¾Ð´Ð¶Ð¸Ð³Ð°Ñ Ð¦ÐµÐ»Ð¸. -spell.wizardry:fire_resistance.desc=Даёт Сопротивление Огню Ðа 30% -spell.wizardry:fire_sigil.desc=Помещает МагичеÑкую Ловушку ÐžÐ³Ð½Ñ Ðа Землю, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐаноÑит Урон И Поджигает СущеÑтво, Которое ÐаÑтупило Ðа Ловушку -spell.wizardry:fireskin.desc=Покрывает Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ ÐžÐ³Ð½Ñ‘Ð¼ Ðа 30 Секунд. ЕÑли Заклинатель Будет Ðтакован, То Враг ЗагоритÑÑ. -spell.wizardry:firestorm.desc="Я Дракон." -spell.wizardry:flame_ray.desc=Создает Поток Пламени Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указали, Который Поджигает И ПоÑтоÑнно Повреждает Цели. -spell.wizardry:flaming_axe.desc=Создает Огненный Топор, Который Поджигает Врагов При Попадании. ДлитÑÑ 30 Секунд. -spell.wizardry:flight.desc=ПарÑщий, Как Орёл. -spell.wizardry:font_of_vitality.desc=Это ПотрÑÑающе. -spell.wizardry:force_arrow.desc=СтрелÑет Стрелой Силы Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете. -spell.wizardry:forcefield.desc=Создает Силовое Поле Вокруг ЗаклинателÑ, Который Отталкивает СущеÑтв И ОтклонÑет СнарÑды. -spell.wizardry:force_orb.desc=ЗапуÑкает Сферу Силы, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐаноÑит Урон И ОтбраÑывает Близких СущеÑтв При Ударе. -spell.wizardry:forests_curse.desc="Как Ты ПоÑмел Войти Ð’ Мой ЛеÑ?!" -spell.wizardry:freeze.desc=Замораживает Цель Ðа 10 Секунд. Также Заморозит Воду И СоздаÑÑ‚ Снег Ðа Земле. -spell.wizardry:frost_axe.desc=Создает ЛедÑной Топор, Который Замораживает Врагов При Попадании. ДлитÑÑ 30 Секунд. -spell.wizardry:frost_ray.desc=Создает Поток Мороза Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете, Который ЗамедлÑет И ПоÑтоÑнно Повреждает Цели. -spell.wizardry:frost_sigil.desc=Помещает МагичеÑкую ЛедÑную Ловушку Ðа Землю, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐаноÑит Урон И Замораживает СущеÑтво, Которое ÐаÑтупило Ðа Ðеё. -spell.wizardry:glide.desc=ПозволÑет Заклинателю Скользить Вниз, ÐаходÑÑÑŒ Ð’ Воздухе, Ð£Ð´ÐµÑ€Ð¶Ð¸Ð²Ð°Ñ ÐšÐ½Ð¾Ð¿ÐºÑƒ ИÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐŸÑ€ÐµÐ´Ð¼ÐµÑ‚Ð°. -spell.wizardry:greater_heal.desc=ВоÑÑтанавливает Заклинателю 4 Сердца. -spell.wizardry:growth_aura.desc=Выращивает Ð’Ñе Зерновые Культуры РÑдом С Заклинателем. -spell.wizardry:heal.desc=ИÑцелÑет Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ðа 2 Сердца. -spell.wizardry:heal_ally.desc=ВоÑÑтанавливает Цели 2 С Половиной Сердца. -spell.wizardry:healing_aura.desc=Создает Зону ИÑцелÑющей Энергии, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð’Ð¾ÑÑтанавливает Здоровье Кого-либо Внутри Ðего, Кроме Ðежити, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐœÐµÐ´Ð»ÐµÐ½Ð½Ð¾ Получает Урон. -spell.wizardry:homing_spark.desc=Создает Плавающую ИÑкру, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð”Ð²Ð¸Ð¶ÐµÑ‚ÑÑ Ðš Врагам. -spell.wizardry:ice_age.desc="Ð’Ñ‹ Замерзнете ÐавÑегда!" -spell.wizardry:ice_charge.desc=ЗапуÑкает ЗарÑд Льда, Который ВзрываетÑÑ ÐŸÑ€Ð¸ Ударе, Ð—Ð°Ð¼Ð¾Ñ€Ð°Ð¶Ð¸Ð²Ð°Ñ Ð‘Ð»Ð¸Ð·Ð»ÐµÐ¶Ð°Ñ‰Ð¸Ñ… СущеÑтв И ВыпуÑÐºÐ°Ñ ÐžÑколки Во Ð’Ñех ÐаправлениÑÑ…. -spell.wizardry:ice_shard.desc=Ð’Ñ‹Ñтреливает ЛедÑной ОÑколок Ð’ Том Ðаправлении, Ð’ Котором Ð’Ñ‹ Указали, Который ÐаноÑит Урон И ЗамедлÑет Цель При Попадании. -spell.wizardry:ice_shroud.desc=Окутывает Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ð’Ð¾ Льду Ðа 30 Секунд, Ð—Ð°Ð¼Ð¾Ñ€Ð°Ð¶Ð¸Ð²Ð°Ñ Ð’Ñе, Что Попадает Или Попадает. -spell.wizardry:ice_statue.desc=Замораживает Цель Ðа 20 Секунд Или До Тех Пор, Пока Она Ðе ВырветÑÑ Ðаружу. Цель Ðе Может ДвигатьÑÑ Ð˜Ð»Ð¸ Делать Что-либо Ð’ Замороженном СоÑтоÑнии, Ðо Также ÐевоÑприимчива К Любому Урону. -spell.wizardry:ignite.desc=УÑтанавливает Огонь Ð’ Течение 10 Секунд. Также Работает Как Кремень И Сталь. -spell.wizardry:invisibility.desc=Делает Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ðевидимым Ð’ Течение 30 Секунд. -spell.wizardry:invoke_weather.desc=ИзменÑет Погоду Ð’ Мире. -spell.wizardry:ironflesh.desc=Увеличивает Сопротивление К Оглушению Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ðа 30 Секунд. -spell.wizardry:levitation.desc=Поднимает Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ð’Ð²ÐµÑ€Ñ… При Ðажатой Кнопке ИÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÐŸÑ€ÐµÐ´Ð¼ÐµÑ‚Ð°. Также Будет Ðейтрализован Урон От ПадениÑ, ЕÑли Он ИÑпользуетÑÑ Ð”Ð¾ Удара Об Землю. -spell.wizardry:life_drain.desc=Создает Поток ИÑÑушающей Энергии Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете, Который ИÑтощает Жизнь Цели И ИÑпользует Её Ð”Ð»Ñ ÐŸÐ¾Ñтепенного ВоÑÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð—Ð´Ð¾Ñ€Ð¾Ð²ÑŒÑ. -spell.wizardry:light.desc=Создает МагичеÑкую Точку Света, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐžÑвещает Окружающую ОблаÑть. ДлитÑÑ 30 Секунд. -spell.wizardry:lightning_arrow.desc=СтрелÑет Стрелой Молнии Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете. -spell.wizardry:lightning_bolt.desc=ЗаÑтавлÑет Молнию Ударить Туда, Куда Ð’Ñ‹ Указываете. -spell.wizardry:lightning_disc.desc=ПоÑылает ДиÑк Молнии, ЛетÑщий Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указали И Ищет Цели. -spell.wizardry:lightning_hammer.desc="Я Поражу Ð¢ÐµÐ±Ñ Ð“Ð½ÐµÐ²Ð¾Ð¼ ÐебеÑ!" -spell.wizardry:lightning_ray.desc=Создает Поток Молнии Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете, Который ПоÑтоÑнно Повреждает Цели. -spell.wizardry:lightning_sigil.desc=Помещает МагичеÑкую МолниеноÑную Ловушку Ðа Землю, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐаноÑит Урон СущеÑтву, Которое ÐаÑтупило Ðа Ловушку, И Приковывает Молнии К Другим Близлежащим СущеÑтвам. -spell.wizardry:magic_missile.desc=Ð’Ñ‹Ñтреливает МагичеÑкий ЗарÑд Ð’ Том Ðаправлении, Ð’ Котором Ð’Ñ‹ Указали. -spell.wizardry:metamorphosis.desc=ИзменÑет Цель Ð’ Другую Форму. Работает Только Ðа Ðекоторых СущеÑтвах. -spell.wizardry:meteor.desc=Ðекоторые Волшебники ПроÑто ХотÑÑ‚, Чтобы Мир Горел ... -spell.wizardry:mind_control.desc=Контролирует Ум Цели, ЗаÑтавлÑÑ Ð•Ñ‘ Ðтаковать Ближайшую Живую Цель, Отличную От ЗаклинателÑ. Когда Это СущеÑтво Будет Убито, Цель ВернетÑÑ Ðš Ðормальной Жизни. -spell.wizardry:none.desc=Чтобы Получить Книгу Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ð½Ð¸Ñ /give command, иÑпользовать метаданные: /give [player] wizardry:spell_book 1 [spell id] (if you found this book in a chest, some other mod has messed things up). -spell.wizardry:petrify.desc=Повергает Цель Ð’ Камень До Следующего Заката Или Пока Ðе Будет Разбит. Цель Ðе Может ДвигатьÑÑ Ð˜Ð»Ð¸ Делать Что-либо, Пока Она Окаменела, Ðо Также ÐевоÑприимчива К Любому Урону. -spell.wizardry:phase_step.desc=Телепортирует Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ð§ÐµÑ€ÐµÐ· Стену Толщиной 1 Блок Перед Ðим. Улучшение ДальноÑти Увеличит Толщину, Через Которую Ð’Ñ‹ Сможете ТелепортироватьÑÑ. -spell.wizardry:plague_of_darkness.desc=Тьма Поглотит Их Ð’Ñех... -spell.wizardry:pocket_furnace.desc=ПереплавлÑет до 5 предметов в инвентаре заклинателÑ. Предметы на панели переплавлÑÑŽÑ‚ÑÑ Ð¿ÐµÑ€Ð²Ñ‹Ðµ. -spell.wizardry:poison.desc=Ð’Ñ‹Ñтреливает Яд Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете. -spell.wizardry:poison_bomb.desc=БроÑает Ядовитую Бомбу Ð’ Ðаправлении, Которое Ð’Ñ‹ Указываете, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð’Ð·Ñ€Ñ‹Ð²Ð°ÐµÑ‚ÑÑ ÐŸÑ€Ð¸ Ударе, ОтравлÑÑ Ð‘Ð»Ð¸Ð·ÐºÐ¸Ñ… СущеÑтв. -spell.wizardry:replenish_hunger.desc=ПополнÑет Ð—Ð°Ð¿Ð°Ñ ÐŸÐ¸Ñ‰Ð¸ Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ðа 6 Пунктов Голода. -spell.wizardry:ring_of_fire.desc=Создает Огненное Кольцо Вокруг ЗаклинателÑ, ÐаноÑÑ Ð£Ñ€Ð¾Ð½ Ð’Ñем Ближайшим Противникам И ÐŸÐ¾Ð´Ð¶Ð¸Ð³Ð°Ñ Ð˜Ñ…. -spell.wizardry:shadow_ward.desc=Создает Стену Тьмы Перед Заклинателем, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐаноÑит Ðападающему Половину Ð’Ñего ВходÑщего Урона. -spell.wizardry:shield.desc=Создает Защитный Барьер Силы, Который Блокирует СнарÑды И Магию. Также Дает Заклинателю Слабый Эффект СопротивлениÑ. -spell.wizardry:shockwave.desc=Бум. -spell.wizardry:silverfish_swarm.desc="ÐÐÐÐÐ! ИХ ОЧЕÐЬ МÐОГО!" -spell.wizardry:slime.desc=Охватывает Цель Слизью, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ Ð—Ð°Ð¼ÐµÐ´Ð»Ñет И ПоÑтоÑнно Её Повреждает. Слизь РазрываетÑÑ Ð§ÐµÑ€ÐµÐ· 10 Секунд. -spell.wizardry:snare.desc=УÑтанавливает Ловушку Ðа Земле, ÐšÐ¾Ñ‚Ð¾Ñ€Ð°Ñ ÐаноÑит Урон И Кратко ЗамедлÑет СущеÑтво, Которое ÐаÑтупило Ðа Ловушку. -spell.wizardry:snowball.desc=Launches a snowball in the direction you are pointing. -spell.wizardry:spark_bomb.desc=ЗапуÑкает Бомбу ИÑкр Ð’ Том Ðаправлении, Ð’ Котором Ð’Ñ‹ Указываете. ИÑкры ПоÑвлÑÑŽÑ‚ÑÑ Ð£ Ближайших Противников При Ударе. -spell.wizardry:spectral_pathway.desc=Создает Перед Вами Ðеразрушимый МагичеÑкий МоÑÑ‚, Который ПроÑтираетÑÑ Ðа 15 Блоков. Через 60 Секунд МоÑÑ‚ ИÑчезает. -spell.wizardry:spider_swarm.desc=Призывает Рой Ядовитых Пауков, Чтобы СражатьÑÑ Ð—Ð° ВаÑ. Пауки ИÑчезнут Через 30 Секунд Или ЕÑли Они Будут Убиты. -spell.wizardry:static_aura.desc=Окружает Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ ÐœÐ¾Ð»Ð½Ð¸ÐµÐ¹ Ð’ Течение 30 Секунд, СтрелÑет ИÑкрами Молнии Во Ð’Ñе, Что Ударит ВаÑ. -spell.wizardry:summon_blaze.desc=Призывает Блейза, Чтобы СражатьÑÑ Ð—Ð° ВаÑ. Блейз ИÑчезнет Через 30 Секунд Или ЕÑли Он Будет Убит. -spell.wizardry:summon_ice_giant.desc="Разбей Их!" -spell.wizardry:summon_ice_wraith.desc=Призывает ЛедÑного Призрака, Который СражаетÑÑ Ð—Ð° ВаÑ. ЛедÑной Призрак ИÑчезнет Через 30 Секунд Или ЕÑли Он Будет Убит. -spell.wizardry:summon_iron_golem.desc=ÐвтоматичеÑкий Ðвтономный Ðвтомат. -spell.wizardry:summon_lightning_wraith.desc=Призывает МолниеноÑного Призрака СражатьÑÑ Ð—Ð° ВаÑ. МолниеноÑный Призрак ИÑчезнет Через 30 Секунд Или ЕÑли Он Будет Убит. -spell.wizardry:summon_phoenix.desc=Из Пепла... -spell.wizardry:summon_shadow_wraith.desc=Призывает Тёмного Призрака, Который Будет СражатьÑÑ Ð—Ð° ВаÑ. -spell.wizardry:summon_skeleton.desc=Призывает Скелета, Который СражаетÑÑ Ð—Ð° ваÑ. Скелет ИÑчезнет Через 30 Секунд Или ЕÑли Он Будет Убит. -spell.wizardry:summon_skeleton_legion.desc="ВоÑÑтань, ÐÑ€Ð¼Ð¸Ñ Ðежети!" -spell.wizardry:summon_snow_golem.desc=Создает Снежного Голема, Который СражаетÑÑ Ð—Ð° ВаÑ. ДлитÑÑ Ð”Ð¾ Тех Пор, Пока Ðе Умрет Снежный Голем. -spell.wizardry:summon_spirit_horse.desc=Призывает Ð”Ð»Ñ Ð’Ð°Ñ Ð’ÐµÑ€Ñ…Ð¾Ð²ÑƒÑŽ Лошадь. ÐŸÑ€Ð¸Ð·Ñ€Ð°Ñ‡Ð½Ð°Ñ Ð›Ð¾ÑˆÐ°Ð´ÑŒ ИÑчезнет Через Ðекоторое Ð’Ñ€ÐµÐ¼Ñ ÐŸÐ¾Ñле Того, Как Ð’Ñ‹ С Ðеё Слезите, Или Ð’Ñ‹ Можете Убрать Её С Помощью Жезла - Щелкните Правой Кнопкой Мыши Ðа Ðей. -spell.wizardry:summon_spirit_wolf.desc=Призывает Спутника Духа Волка, Который СражаетÑÑ Ð—Ð° ВаÑ. Призрачный Волк ИÑчезнет, Только ЕÑли Его Убьют, Или Ð’Ñ‹ Можете Его Убрать, Щелкнув Правой Кнопкой Мыши Ðа Ðём С Помощью Жезла. -spell.wizardry:summon_wither_skeleton.desc=Призывает Скелета-ИÑÑушителÑ, Который СражаетÑÑ Ð—Ð° ВаÑ. Скелет-ИÑÑушитель ИÑчезнет Через 30 Секунд Или ЕÑли Он Будет Убит. -spell.wizardry:summon_zombie.desc=Призывает Зомби, Который СражаетÑÑ Ð—Ð° ВаÑ. Зомби ИÑчезнет Через 30 Секунд Или ЕÑли Он Будет Убит. -spell.wizardry:telekinesis.desc=Перемещает Объект Или Другой Маленький Объект К Себе Или Щелкает Правой Кнопкой Мыши Ðа Блоке,Ðа Который Ð’Ñ‹ Смотрите. -spell.wizardry:thunderbolt.desc=СтрелÑет Громом, Который ОтбраÑывает Цели. -spell.wizardry:thunderstorm.desc="МУХÐÐ¥ÐÐ¥ÐÐ¥ÐÐ¥!" -spell.wizardry:tornado.desc=РазвÑзывает Торнадо Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете, Который БроÑает Что-либо Ðа Своем Пути Ð’ Ðебо. -spell.wizardry:transience.desc=Делает Переход Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ðа 20 Секунд. Заклинатель ÐевоÑприимчив Ко Ð’Ñему Урону Ð’ Переходный Период, Ðо Ðе Может Сломать Или ПомеÑтить Блоки Или ÐанеÑти Какой-либо Урон. -spell.wizardry:transportation.desc=ТранÑпортирует Ð—Ð°ÐºÐ»Ð¸Ð½Ð°Ñ‚ÐµÐ»Ñ Ð’ Запомненный Каменный Круг. Чтобы ИÑпользовать Это Заклинание, Сделайте Круг Камней ТранÑпортировки, Затем Щелкните Правой Кнопкой Мыши С Помощью Жезла. -spell.wizardry:vanishing_box.desc=Grants the caster access to their ender chest storage. -spell.wizardry:wall_of_frost.desc=Зима У Ð’Ð°Ñ ÐŸÐ¾Ð´ Рукой. -spell.wizardry:water_breathing.desc=ПозволÑет Заклинателю Дышать Под Водой Ð’ Течение 60 Секунд. -spell.wizardry:whirlwind.desc=ЗаÑтавлÑет Цель Взлететь Вверх Далеко От Ð’Ð°Ñ Ðа СкороÑти. -spell.wizardry:wither.desc=СтрелÑет Лучом Тьмы, Который УвÑдает Ð’ÑÑ‘, К Чему Он ПрикаÑаетÑÑ. -spell.wizardry:wither_skull.desc=ЗапуÑкает Череп ИÑÑÑƒÑˆÐ¸Ñ‚ÐµÐ»Ñ Ð’ Ðаправлении, Ðа Которое Ð’Ñ‹ Указываете. -spell.wizardry:mind_trick.desc=Путает и дезориентирует цель в течение 15 Ñекунд, что делает его не в ÑоÑтоÑнии атаковать. Эффект будет раÑÑеÑн, еÑли цель получит урон. - -spell.wizardry:invoke_weather.sun=Дождь Ðачинает ОÑтанавливатьÑÑ ... -spell.wizardry:invoke_weather.rain=ÐебеÑа ОткрываютÑÑ ... -spell.wizardry:transportation.missing=Ваш Запомненный Каменный Круг ОтÑутÑтвует Или Затруднен ... -spell.wizardry:transportation.undefined=Ð’Ñ‹ Должны Сначала Запомнить МеÑтоположение Каменного Круга! -spell.wizardry:transportation.wrongdimension=Ваш Запомненный Каменный Круг ÐаходитÑÑ Ð’ Другом Измерении ... -spell.wizardry:clairvoyance.searching=ПоиÑк... -spell.wizardry:clairvoyance.confirm=Путь, показанный при иÑпользовании Ð·Ð°ÐºÐ»Ð¸Ð½Ð°Ð½Ð¸Ñ %1$s теперь приведёт к Ñтой точке -spell.wizardry:clairvoyance.outofrange=Ваше запоминающееÑÑ Ð¼ÐµÑтоположение Ñлишком далеко или недоÑтупно... -spell.wizardry:clairvoyance.undefined=Ð’Ñ‹ должны запомнить первое меÑтоположение! -spell.wizardry:clairvoyance.wrongdimension=Ваше запоминающееÑÑ Ð¼ÐµÑтоположение находитÑÑ Ð² другом измерении... - -potion.wizardry:frost=Отморожение -potion.wizardry:fireskin=ÐžÐ³Ð½ÐµÐ½Ð½Ð°Ñ ÐšÐ¾Ð¶Ð° -potion.wizardry:ice_shroud=ЛедÑÐ½Ð°Ñ ÐšÐ¾Ð¶Ð° -potion.wizardry:static_aura=СтатичеÑÐºÐ°Ñ Ðура -potion.wizardry:transience=БыÑтрота -potion.wizardry:decay=Гниение -potion.wizardry:mind_trick=Обман Разума -potion.wizardry:sixth_sense=ШеÑтое ЧувÑтво -potion.wizardry:font_of_mana=Купель Маны +potion.frost=Отморожение +potion.fireskin=ÐžÐ³Ð½ÐµÐ½Ð½Ð°Ñ ÐšÐ¾Ð¶Ð° +potion.ice_shroud=ЛедÑÐ½Ð°Ñ ÐšÐ¾Ð¶Ð° +potion.static_aura=СтатичеÑÐºÐ°Ñ Ðура +potion.transience=БыÑтрота +potion.decay=Гниение key.categories.wizardry=Wizardry -death.attack.wizardry_magic=%1$s был убит %2$s иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¼Ð°Ð³Ð¸ÑŽ -death.attack.indirect_wizardry_magic=%1$s был убит %2$s иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¼Ð°Ð³Ð¸ÑŽ +death.attack.wizardryMagic=%1$s был убит %2$s иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¼Ð°Ð³Ð¸ÑŽ +death.attack.indirectWizardryMagic=%1$s был убит %2$s иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð¼Ð°Ð³Ð¸ÑŽ -config.wizardry.title.general=Mod Options -config.wizardry.title.spells=Spell Configuration -config.wizardry.subtitle.spells=Set a spell to false to disable it. +config.title.general=Mod Options +config.title.spells=Spell Configuration +config.subtitle.spells=Set a spell to false to disable it. -config.wizardry.tower_rarity=Tower Rarity -config.wizardry.ore_dimensions=Ore Dimensions -config.wizardry.flower_dimensions=Flower Dimensions -config.wizardry.tower_dimensions=Tower Dimensions -config.wizardry.spell_book_drop_chance=Spell Book Drop Chance -config.wizardry.generate_loot=Generate Loot -config.wizardry.firebomb_is_craftable=Firebomb Is Craftable -config.wizardry.poison_bomb_is_craftable=Poison Bomb Is Craftable -config.wizardry.use_alternate_scroll_recipe=Use Alternate Scroll Recipe -config.wizardry.teleport_through_unbreakable_blocks=Teleport Through Unbreakable Blocks -config.wizardry.show_summoned_creature_names=Show Summoned Creature Names -config.wizardry.spell_hud_position=Spell HUD Position +config.tower_rarity=Tower Rarity +config.ore_dimensions=Ore Dimensions +config.flower_dimensions=Flower Dimensions +config.tower_dimensions=Tower Dimensions +config.spell_book_drop_chance=Spell Book Drop Chance +config.generate_loot=Generate Loot +config.firebomb_is_craftable=Firebomb Is Craftable +config.poison_bomb_is_craftable=Poison Bomb Is Craftable +config.use_alternate_scroll_recipe=Use Alternate Scroll Recipe +config.teleport_through_unbreakable_blocks=Teleport Through Unbreakable Blocks +config.show_summoned_creature_names=Show Summoned Creature Names +config.spell_hud_position=Spell HUD Position +config.frost_potion_id=Frost Potion ID +config.transience_potion_id=Transience Potion ID +config.fireskin_potion_id=Fireskin Potion ID +config.ice_shroud_potion_id=Ice Shroud Potion ID +config.static_aura_potion_id=Static Aura Potion ID +config.decay_potion_id=Decay Potion ID -config.wizardry.category.spells=Configure Spells -config.wizardry.category.spells.tooltip=Select which spells are enabled. \ No newline at end of file +config.category.spells=Configure Spells +config.category.spells.tooltip=Select which spells are enabled. \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/loot_tables/chests/dungeon_additions.json b/src/main/resources/assets/wizardry/loot_tables/chests/dungeon_additions.json deleted file mode 100644 index 59c4bf30..00000000 --- a/src/main/resources/assets/wizardry/loot_tables/chests/dungeon_additions.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "pools": [ - { - "name": "wizardry", - "rolls": { - "min": 3, - "max": 7 - }, - "entries": [ - { - "type": "loot_table", - "name": "wizardry:subsets/novice_wands", - "weight": 3 - }, - { - "type": "loot_table", - "name": "wizardry:subsets/wizard_armour", - "weight": 6 - }, - { - "type": "loot_table", - "name": "wizardry:subsets/arcane_tomes", - "weight": 6 - }, - { - "type": "loot_table", - "name": "wizardry:subsets/wand_upgrades", - "weight": 2 - }, - { - "type": "item", - "name": "wizardry:magic_crystal", - "weight": 5, - "functions": [ - { - "function": "set_count", - "count": { - "min": 1, - "max": 4 - } - } - ] - }, - { - "type": "item", - "name": "wizardry:spell_book", - "weight": 20, - "functions": [ - { - "function": "wizardry:random_spell" - } - ] - }, - { - "type": "item", - "name": "wizardry:scroll", - "weight": 10, - "functions": [ - { - "function": "wizardry:random_spell" - } - ] - }, - { - "type": "item", - "name": "wizardry:armour_upgrade", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:identification_scroll", - "weight": 3 - }, - { - "type": "item", - "name": "wizardry:firebomb", - "weight": 4 - }, - { - "type": "item", - "name": "wizardry:poison_bomb", - "weight": 4 - }, - { - "type": "item", - "name": "wizardry:smoke_bomb", - "weight": 4 - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/loot_tables/chests/wizard_tower.json b/src/main/resources/assets/wizardry/loot_tables/chests/wizard_tower.json deleted file mode 100644 index f7bba6ea..00000000 --- a/src/main/resources/assets/wizardry/loot_tables/chests/wizard_tower.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "pools": [ - { - "name": "wizardry", - "rolls": { - "min": 3, - "max": 7 - }, - "entries": [ - { - "type": "loot_table", - "name": "wizardry:subsets/novice_wands", - "weight": 3 - }, - { - "type": "loot_table", - "name": "wizardry:subsets/wizard_armour", - "weight": 6 - }, - { - "type": "loot_table", - "name": "wizardry:subsets/arcane_tomes", - "weight": 6 - }, - { - "type": "loot_table", - "name": "wizardry:subsets/wand_upgrades", - "weight": 2 - }, - { - "type": "item", - "name": "wizardry:magic_crystal", - "weight": 5, - "functions": [ - { - "function": "set_count", - "count": { - "min": 1, - "max": 4 - } - } - ] - }, - { - "type": "item", - "name": "wizardry:spell_book", - "weight": 20, - "functions": [ - { - "function": "wizardry:random_spell" - } - ] - }, - { - "type": "item", - "name": "wizardry:scroll", - "weight": 10, - "functions": [ - { - "function": "wizardry:random_spell" - } - ] - }, - { - "type": "item", - "name": "wizardry:armour_upgrade", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:identification_scroll", - "weight": 3 - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/loot_tables/entities/evil_wizard.json b/src/main/resources/assets/wizardry/loot_tables/entities/evil_wizard.json deleted file mode 100644 index 8723be6f..00000000 --- a/src/main/resources/assets/wizardry/loot_tables/entities/evil_wizard.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "pools": [ - { - "name": "common", - "rolls": 1, - "entries": [ - { - "type": "item", - "name": "wizardry:magic_crystal", - "weight": 1, - "functions": [ - { - "function": "set_count", - "count": { - "min": 3, - "max": 5 - }, - "function": "looting_enchant", - "count": { - "min": 0, - "max": 1 - } - } - ] - } - ] - }, - { - "name": "rare", - "conditions": [ - { - "condition": "killed_by_player" - }, - { - "condition": "random_chance_with_looting", - "chance": 0.05, - "looting_multiplier": 0.01 - } - ], - "rolls": 1, - "entries": [ - { - "type": "item", - "name": "wizardry:spell_book", - "weight": 1, - "functions": [ - { - "function": "wizardry:wizard_spell" - } - ] - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/loot_tables/entities/mob_additions.json b/src/main/resources/assets/wizardry/loot_tables/entities/mob_additions.json deleted file mode 100644 index dc872ac7..00000000 --- a/src/main/resources/assets/wizardry/loot_tables/entities/mob_additions.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "pools": [ - { - "conditions": [ - { - "condition": "killed_by_player" - }, - { - "condition": "random_chance_with_looting", - "chance": 0.02, - "looting_multiplier": 0.01 - } - ], - "rolls": 1, - "entries": [ - { - "type": "item", - "name": "wizardry:spell_book", - "weight": 1, - "functions": [ - { - "function": "wizardry:random_spell" - } - ] - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/loot_tables/subsets/arcane_tomes.json b/src/main/resources/assets/wizardry/loot_tables/subsets/arcane_tomes.json deleted file mode 100644 index 14ca2ad4..00000000 --- a/src/main/resources/assets/wizardry/loot_tables/subsets/arcane_tomes.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "pools": [ - { - "name": "tomes", - "rolls": 1, - "entries": [ - { - "type": "item", - "entryName": "apprentice_tome", - "name": "wizardry:arcane_tome", - "weight": 3, - "functions": [ - { - "function": "set_data", - "data": 1 - } - ] - }, - { - "type": "item", - "entryName": "advanced_tome", - "name": "wizardry:arcane_tome", - "weight": 2, - "functions": [ - { - "function": "set_data", - "data": 2 - } - ] - }, - { - "type": "item", - "entryName": "master_tome", - "name": "wizardry:arcane_tome", - "weight": 1, - "functions": [ - { - "function": "set_data", - "data": 3 - } - ] - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/loot_tables/subsets/novice_wands.json b/src/main/resources/assets/wizardry/loot_tables/subsets/novice_wands.json deleted file mode 100644 index 01f5c608..00000000 --- a/src/main/resources/assets/wizardry/loot_tables/subsets/novice_wands.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "pools": [ - { - "name": "wands", - "rolls": 1, - "entries": [ - { - "type": "item", - "name": "wizardry:magic_wand", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:basic_fire_wand", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:basic_ice_wand", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:basic_lightning_wand", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:basic_necromancy_wand", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:basic_earth_wand", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:basic_sorcery_wand", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:basic_healing_wand", - "weight": 1 - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/loot_tables/subsets/wand_upgrades.json b/src/main/resources/assets/wizardry/loot_tables/subsets/wand_upgrades.json deleted file mode 100644 index 4ce76637..00000000 --- a/src/main/resources/assets/wizardry/loot_tables/subsets/wand_upgrades.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "pools": [ - { - "name": "upgrades", - "rolls": 1, - "entries": [ - { - "type": "item", - "name": "wizardry:condenser_upgrade", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:siphon_upgrade", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:storage_upgrade", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:range_upgrade", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:duration_upgrade", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:cooldown_upgrade", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:blast_upgrade", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:attunement_upgrade", - "weight": 1 - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/loot_tables/subsets/wizard_armour.json b/src/main/resources/assets/wizardry/loot_tables/subsets/wizard_armour.json deleted file mode 100644 index 95f8ac07..00000000 --- a/src/main/resources/assets/wizardry/loot_tables/subsets/wizard_armour.json +++ /dev/null @@ -1,170 +0,0 @@ -{ - "pools": [ - { - "name": "armour", - "rolls": 1, - "entries": [ - { - "type": "item", - "name": "wizardry:wizard_hat", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_hat_fire", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_hat_ice", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_hat_lightning", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_hat_necromancy", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_hat_earth", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_hat_sorcery", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_hat_healing", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_robe", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_robe_fire", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_robe_ice", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_robe_lightning", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_robe_necromancy", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_robe_earth", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_robe_sorcery", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_robe_healing", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_leggings", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_leggings_fire", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_leggings_ice", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_leggings_lightning", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_leggings_necromancy", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_leggings_earth", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_leggings_sorcery", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_leggings_healing", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_boots", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_boots_fire", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_boots_ice", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_boots_lightning", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_boots_necromancy", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_boots_earth", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_boots_sorcery", - "weight": 1 - }, - { - "type": "item", - "name": "wizardry:wizard_boots_healing", - "weight": 1 - } - ] - } - ] -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/block/arcane_workbench.json b/src/main/resources/assets/wizardry/models/block/arcane_workbench.json deleted file mode 100644 index 8a545d1c..00000000 --- a/src/main/resources/assets/wizardry/models/block/arcane_workbench.json +++ /dev/null @@ -1,21 +0,0 @@ -{ "parent": "block/block", - "textures": { - "particle": "wizardry:blocks/arcane_workbench_bottom", - "bottom": "wizardry:blocks/arcane_workbench_bottom", - "top": "wizardry:blocks/arcane_workbench_top", - "side": "wizardry:blocks/arcane_workbench_side" - }, - "elements": [ - { "from": [ 0, 0, 0 ], - "to": [ 16, 12, 16 ], - "faces": { - "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom", "cullface": "down" }, - "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, - "north": { "uv": [ 0, 4, 16, 16 ], "texture": "#side", "cullface": "north" }, - "south": { "uv": [ 0, 4, 16, 16 ], "texture": "#side", "cullface": "south" }, - "west": { "uv": [ 0, 4, 16, 16 ], "texture": "#side", "cullface": "west" }, - "east": { "uv": [ 0, 4, 16, 16 ], "texture": "#side", "cullface": "east" } - } - } - ] -} diff --git a/src/main/resources/assets/wizardry/models/block/crystal_block.json b/src/main/resources/assets/wizardry/models/block/crystal_block.json deleted file mode 100644 index 898d595a..00000000 --- a/src/main/resources/assets/wizardry/models/block/crystal_block.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "wizardry:blocks/crystal_block" - } -} diff --git a/src/main/resources/assets/wizardry/models/block/crystal_flower.json b/src/main/resources/assets/wizardry/models/block/crystal_flower.json deleted file mode 100644 index 90f2f653..00000000 --- a/src/main/resources/assets/wizardry/models/block/crystal_flower.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cross", - "textures": { - "cross": "wizardry:blocks/crystal_flower" - } -} diff --git a/src/main/resources/assets/wizardry/models/block/crystal_ore.json b/src/main/resources/assets/wizardry/models/block/crystal_ore.json deleted file mode 100644 index 80b71f13..00000000 --- a/src/main/resources/assets/wizardry/models/block/crystal_ore.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "wizardry:blocks/crystal_ore" - } -} diff --git a/src/main/resources/assets/wizardry/models/block/ice_statue.json b/src/main/resources/assets/wizardry/models/block/ice_statue.json deleted file mode 100644 index b7f5c4ad..00000000 --- a/src/main/resources/assets/wizardry/models/block/ice_statue.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "block/ice" -} diff --git a/src/main/resources/assets/wizardry/models/block/magic_light.json b/src/main/resources/assets/wizardry/models/block/magic_light.json deleted file mode 100644 index 1f4f2185..00000000 --- a/src/main/resources/assets/wizardry/models/block/magic_light.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "parent": "block/block", - "elements": [ - { "from": [ 0, 0, 0 ], - "to": [ 0, 0, 0 ], - "faces": { - "down": { "texture": "#down", "cullface": "down" }, - "up": { "texture": "#up", "cullface": "up" }, - "north": { "texture": "#north", "cullface": "north" }, - "south": { "texture": "#south", "cullface": "south" }, - "west": { "texture": "#west", "cullface": "west" }, - "east": { "texture": "#east", "cullface": "east" } - } - } - ] -} diff --git a/src/main/resources/assets/wizardry/models/block/meteor.json b/src/main/resources/assets/wizardry/models/block/meteor.json deleted file mode 100644 index 52676102..00000000 --- a/src/main/resources/assets/wizardry/models/block/meteor.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "wizardry:blocks/meteor" - } -} diff --git a/src/main/resources/assets/wizardry/models/block/petrified_stone.json b/src/main/resources/assets/wizardry/models/block/petrified_stone.json deleted file mode 100644 index 9ecdfbf2..00000000 --- a/src/main/resources/assets/wizardry/models/block/petrified_stone.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "parent": "block/block", - "textures": { - "all": "blocks/stone", - "particle": "blocks/stone" - }, - "elements": [ - { "from": [ 0, 0, 0 ], - "to": [ 0, 0, 0 ], - "faces": { - "down": { "texture": "#down", "cullface": "down" }, - "up": { "texture": "#up", "cullface": "up" }, - "north": { "texture": "#north", "cullface": "north" }, - "south": { "texture": "#south", "cullface": "south" }, - "west": { "texture": "#west", "cullface": "west" }, - "east": { "texture": "#east", "cullface": "east" } - } - } - ] -} diff --git a/src/main/resources/assets/wizardry/models/block/snare.json b/src/main/resources/assets/wizardry/models/block/snare.json deleted file mode 100644 index 52b4fbd9..00000000 --- a/src/main/resources/assets/wizardry/models/block/snare.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "ambientocclusion": false, - "textures": { - "particle": "wizardry:blocks/snare", - "texture": "wizardry:blocks/snare" - }, - "elements": [ - { "from": [ 0, 0.25, 0 ], - "to": [ 16, 0.25, 16 ], - "faces": { - "down": { "uv": [ 16, 16, 0, 0 ], "texture": "#texture"}, - "up": { "uv": [ 16, 0, 0, 16 ], "texture": "#texture"} - } - } - ] -} diff --git a/src/main/resources/assets/wizardry/models/block/spectral_block.json b/src/main/resources/assets/wizardry/models/block/spectral_block.json deleted file mode 100644 index fd4a9d44..00000000 --- a/src/main/resources/assets/wizardry/models/block/spectral_block.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cube_all", - "textures": { - "all": "wizardry:blocks/spectral_block" - } -} diff --git a/src/main/resources/assets/wizardry/models/block/transportation_stone.json b/src/main/resources/assets/wizardry/models/block/transportation_stone.json deleted file mode 100644 index 9e235690..00000000 --- a/src/main/resources/assets/wizardry/models/block/transportation_stone.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "parent": "block/block", - "textures": { - "all": "wizardry:blocks/transportation_stone", - "particle": "wizardry:blocks/transportation_stone" - }, - "elements": [ - { "from": [ 5, 0, 5 ], - "to": [ 11, 6, 11 ], - "faces": { - "down": { "texture": "#all", "cullface": "down" }, - "up": { "texture": "#all"}, - "north": { "texture": "#all"}, - "south": { "texture": "#all"}, - "west": { "texture": "#all"}, - "east": { "texture": "#all"} - } - } - ] -} diff --git a/src/main/resources/assets/wizardry/models/block/vanishing_cobweb.json b/src/main/resources/assets/wizardry/models/block/vanishing_cobweb.json deleted file mode 100644 index f8865a41..00000000 --- a/src/main/resources/assets/wizardry/models/block/vanishing_cobweb.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "block/cross", - "textures": { - "cross": "blocks/web" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/advanced_earth_wand.json b/src/main/resources/assets/wizardry/models/item/advanced_earth_wand.json deleted file mode 100644 index 3f23fbc6..00000000 --- a/src/main/resources/assets/wizardry/models/item/advanced_earth_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_advanced_earth" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/advanced_fire_wand.json b/src/main/resources/assets/wizardry/models/item/advanced_fire_wand.json deleted file mode 100644 index beb8fc84..00000000 --- a/src/main/resources/assets/wizardry/models/item/advanced_fire_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_advanced_fire" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/advanced_healing_wand.json b/src/main/resources/assets/wizardry/models/item/advanced_healing_wand.json deleted file mode 100644 index bba06e50..00000000 --- a/src/main/resources/assets/wizardry/models/item/advanced_healing_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_advanced_healing" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/advanced_ice_wand.json b/src/main/resources/assets/wizardry/models/item/advanced_ice_wand.json deleted file mode 100644 index 35dadf70..00000000 --- a/src/main/resources/assets/wizardry/models/item/advanced_ice_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_advanced_ice" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/advanced_lightning_wand.json b/src/main/resources/assets/wizardry/models/item/advanced_lightning_wand.json deleted file mode 100644 index 7c96d092..00000000 --- a/src/main/resources/assets/wizardry/models/item/advanced_lightning_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_advanced_lightning" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/advanced_necromancy_wand.json b/src/main/resources/assets/wizardry/models/item/advanced_necromancy_wand.json deleted file mode 100644 index db36e099..00000000 --- a/src/main/resources/assets/wizardry/models/item/advanced_necromancy_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_advanced_necromancy" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/advanced_sorcery_wand.json b/src/main/resources/assets/wizardry/models/item/advanced_sorcery_wand.json deleted file mode 100644 index 127415e7..00000000 --- a/src/main/resources/assets/wizardry/models/item/advanced_sorcery_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_advanced_sorcery" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/advanced_wand.json b/src/main/resources/assets/wizardry/models/item/advanced_wand.json deleted file mode 100644 index bee14a76..00000000 --- a/src/main/resources/assets/wizardry/models/item/advanced_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_advanced" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/apprentice_earth_wand.json b/src/main/resources/assets/wizardry/models/item/apprentice_earth_wand.json deleted file mode 100644 index 1ec46893..00000000 --- a/src/main/resources/assets/wizardry/models/item/apprentice_earth_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_apprentice_earth" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/apprentice_fire_wand.json b/src/main/resources/assets/wizardry/models/item/apprentice_fire_wand.json deleted file mode 100644 index 0aa6cf8e..00000000 --- a/src/main/resources/assets/wizardry/models/item/apprentice_fire_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_apprentice_fire" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/apprentice_healing_wand.json b/src/main/resources/assets/wizardry/models/item/apprentice_healing_wand.json deleted file mode 100644 index 118d72d0..00000000 --- a/src/main/resources/assets/wizardry/models/item/apprentice_healing_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_apprentice_healing" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/apprentice_ice_wand.json b/src/main/resources/assets/wizardry/models/item/apprentice_ice_wand.json deleted file mode 100644 index 25bbce5c..00000000 --- a/src/main/resources/assets/wizardry/models/item/apprentice_ice_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_apprentice_ice" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/apprentice_lightning_wand.json b/src/main/resources/assets/wizardry/models/item/apprentice_lightning_wand.json deleted file mode 100644 index 2f508113..00000000 --- a/src/main/resources/assets/wizardry/models/item/apprentice_lightning_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_apprentice_lightning" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/apprentice_necromancy_wand.json b/src/main/resources/assets/wizardry/models/item/apprentice_necromancy_wand.json deleted file mode 100644 index eb662348..00000000 --- a/src/main/resources/assets/wizardry/models/item/apprentice_necromancy_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_apprentice_necromancy" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/apprentice_sorcery_wand.json b/src/main/resources/assets/wizardry/models/item/apprentice_sorcery_wand.json deleted file mode 100644 index 4ac8e0da..00000000 --- a/src/main/resources/assets/wizardry/models/item/apprentice_sorcery_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_apprentice_sorcery" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/apprentice_wand.json b/src/main/resources/assets/wizardry/models/item/apprentice_wand.json deleted file mode 100644 index 57a642e0..00000000 --- a/src/main/resources/assets/wizardry/models/item/apprentice_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_apprentice" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/arcane_tome.json b/src/main/resources/assets/wizardry/models/item/arcane_tome.json deleted file mode 100644 index 9737284c..00000000 --- a/src/main/resources/assets/wizardry/models/item/arcane_tome.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/arcane_tome" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/arcane_workbench.json b/src/main/resources/assets/wizardry/models/item/arcane_workbench.json deleted file mode 100644 index 35acd55b..00000000 --- a/src/main/resources/assets/wizardry/models/item/arcane_workbench.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "wizardry:block/arcane_workbench" -} diff --git a/src/main/resources/assets/wizardry/models/item/armour_upgrade.json b/src/main/resources/assets/wizardry/models/item/armour_upgrade.json deleted file mode 100644 index 08fd6606..00000000 --- a/src/main/resources/assets/wizardry/models/item/armour_upgrade.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/armour_upgrade" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/attunement_upgrade.json b/src/main/resources/assets/wizardry/models/item/attunement_upgrade.json deleted file mode 100644 index 927fd9fe..00000000 --- a/src/main/resources/assets/wizardry/models/item/attunement_upgrade.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/upgrade_attunement" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/basic_earth_wand.json b/src/main/resources/assets/wizardry/models/item/basic_earth_wand.json deleted file mode 100644 index ddbccfee..00000000 --- a/src/main/resources/assets/wizardry/models/item/basic_earth_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_basic_earth" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/basic_fire_wand.json b/src/main/resources/assets/wizardry/models/item/basic_fire_wand.json deleted file mode 100644 index e323c2df..00000000 --- a/src/main/resources/assets/wizardry/models/item/basic_fire_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_basic_fire" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/basic_healing_wand.json b/src/main/resources/assets/wizardry/models/item/basic_healing_wand.json deleted file mode 100644 index 80d6b33c..00000000 --- a/src/main/resources/assets/wizardry/models/item/basic_healing_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_basic_healing" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/basic_ice_wand.json b/src/main/resources/assets/wizardry/models/item/basic_ice_wand.json deleted file mode 100644 index 8bd95b41..00000000 --- a/src/main/resources/assets/wizardry/models/item/basic_ice_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_basic_ice" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/basic_lightning_wand.json b/src/main/resources/assets/wizardry/models/item/basic_lightning_wand.json deleted file mode 100644 index 2307f1a7..00000000 --- a/src/main/resources/assets/wizardry/models/item/basic_lightning_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_basic_lightning" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/basic_necromancy_wand.json b/src/main/resources/assets/wizardry/models/item/basic_necromancy_wand.json deleted file mode 100644 index 0727fa69..00000000 --- a/src/main/resources/assets/wizardry/models/item/basic_necromancy_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_basic_necromancy" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/basic_sorcery_wand.json b/src/main/resources/assets/wizardry/models/item/basic_sorcery_wand.json deleted file mode 100644 index 1a399976..00000000 --- a/src/main/resources/assets/wizardry/models/item/basic_sorcery_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_basic_sorcery" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/blank_scroll.json b/src/main/resources/assets/wizardry/models/item/blank_scroll.json deleted file mode 100644 index a6a86d05..00000000 --- a/src/main/resources/assets/wizardry/models/item/blank_scroll.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/scroll" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/blast_upgrade.json b/src/main/resources/assets/wizardry/models/item/blast_upgrade.json deleted file mode 100644 index 3f085c0a..00000000 --- a/src/main/resources/assets/wizardry/models/item/blast_upgrade.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/upgrade_blast" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/condenser_upgrade.json b/src/main/resources/assets/wizardry/models/item/condenser_upgrade.json deleted file mode 100644 index 42a4c63f..00000000 --- a/src/main/resources/assets/wizardry/models/item/condenser_upgrade.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/upgrade_condenser" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/cooldown_upgrade.json b/src/main/resources/assets/wizardry/models/item/cooldown_upgrade.json deleted file mode 100644 index 23addd92..00000000 --- a/src/main/resources/assets/wizardry/models/item/cooldown_upgrade.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/upgrade_cooldown" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/crystal_block.json b/src/main/resources/assets/wizardry/models/item/crystal_block.json deleted file mode 100644 index 290f0923..00000000 --- a/src/main/resources/assets/wizardry/models/item/crystal_block.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "wizardry:block/crystal_block" -} diff --git a/src/main/resources/assets/wizardry/models/item/crystal_flower.json b/src/main/resources/assets/wizardry/models/item/crystal_flower.json deleted file mode 100644 index b71cf4d6..00000000 --- a/src/main/resources/assets/wizardry/models/item/crystal_flower.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:blocks/crystal_flower" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/crystal_ore.json b/src/main/resources/assets/wizardry/models/item/crystal_ore.json deleted file mode 100644 index f288786d..00000000 --- a/src/main/resources/assets/wizardry/models/item/crystal_ore.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "wizardry:block/crystal_ore" -} diff --git a/src/main/resources/assets/wizardry/models/item/duration_upgrade.json b/src/main/resources/assets/wizardry/models/item/duration_upgrade.json deleted file mode 100644 index 5acea158..00000000 --- a/src/main/resources/assets/wizardry/models/item/duration_upgrade.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/upgrade_duration" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/firebomb.json b/src/main/resources/assets/wizardry/models/item/firebomb.json deleted file mode 100644 index a1c8a29f..00000000 --- a/src/main/resources/assets/wizardry/models/item/firebomb.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/firebomb" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/flaming_axe.json b/src/main/resources/assets/wizardry/models/item/flaming_axe.json deleted file mode 100644 index 104d511f..00000000 --- a/src/main/resources/assets/wizardry/models/item/flaming_axe.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/flaming_axe" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/frost_axe.json b/src/main/resources/assets/wizardry/models/item/frost_axe.json deleted file mode 100644 index 1204aac7..00000000 --- a/src/main/resources/assets/wizardry/models/item/frost_axe.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/frost_axe" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/ice_statue.json b/src/main/resources/assets/wizardry/models/item/ice_statue.json deleted file mode 100644 index a3cfbe68..00000000 --- a/src/main/resources/assets/wizardry/models/item/ice_statue.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "wizardry:block/ice_statue" -} diff --git a/src/main/resources/assets/wizardry/models/item/identification_scroll.json b/src/main/resources/assets/wizardry/models/item/identification_scroll.json deleted file mode 100644 index 4c39a408..00000000 --- a/src/main/resources/assets/wizardry/models/item/identification_scroll.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/identification_scroll" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/magic_crystal.json b/src/main/resources/assets/wizardry/models/item/magic_crystal.json deleted file mode 100644 index 1aae8ddb..00000000 --- a/src/main/resources/assets/wizardry/models/item/magic_crystal.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/magic_crystal" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/magic_light.json b/src/main/resources/assets/wizardry/models/item/magic_light.json deleted file mode 100644 index c5a50b1a..00000000 --- a/src/main/resources/assets/wizardry/models/item/magic_light.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "wizardry:block/sea_lantern" -} diff --git a/src/main/resources/assets/wizardry/models/item/magic_silk.json b/src/main/resources/assets/wizardry/models/item/magic_silk.json deleted file mode 100644 index cec4cb55..00000000 --- a/src/main/resources/assets/wizardry/models/item/magic_silk.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/magic_silk" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/magic_wand.json b/src/main/resources/assets/wizardry/models/item/magic_wand.json deleted file mode 100644 index 1bb79f4f..00000000 --- a/src/main/resources/assets/wizardry/models/item/magic_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_basic" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/mana_flask.json b/src/main/resources/assets/wizardry/models/item/mana_flask.json deleted file mode 100644 index f898986f..00000000 --- a/src/main/resources/assets/wizardry/models/item/mana_flask.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/mana_flask" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/master_earth_wand.json b/src/main/resources/assets/wizardry/models/item/master_earth_wand.json deleted file mode 100644 index a880c440..00000000 --- a/src/main/resources/assets/wizardry/models/item/master_earth_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_master_earth" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/master_fire_wand.json b/src/main/resources/assets/wizardry/models/item/master_fire_wand.json deleted file mode 100644 index f2da76dc..00000000 --- a/src/main/resources/assets/wizardry/models/item/master_fire_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_master_fire" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/master_healing_wand.json b/src/main/resources/assets/wizardry/models/item/master_healing_wand.json deleted file mode 100644 index 17c1dd41..00000000 --- a/src/main/resources/assets/wizardry/models/item/master_healing_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_master_healing" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/master_ice_wand.json b/src/main/resources/assets/wizardry/models/item/master_ice_wand.json deleted file mode 100644 index 79f80cb6..00000000 --- a/src/main/resources/assets/wizardry/models/item/master_ice_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_master_ice" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/master_lightning_wand.json b/src/main/resources/assets/wizardry/models/item/master_lightning_wand.json deleted file mode 100644 index 03e5f0ca..00000000 --- a/src/main/resources/assets/wizardry/models/item/master_lightning_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_master_lightning" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/master_necromancy_wand.json b/src/main/resources/assets/wizardry/models/item/master_necromancy_wand.json deleted file mode 100644 index 5cc36467..00000000 --- a/src/main/resources/assets/wizardry/models/item/master_necromancy_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_master_necromancy" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/master_sorcery_wand.json b/src/main/resources/assets/wizardry/models/item/master_sorcery_wand.json deleted file mode 100644 index 67cf62ec..00000000 --- a/src/main/resources/assets/wizardry/models/item/master_sorcery_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_master_sorcery" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/master_wand.json b/src/main/resources/assets/wizardry/models/item/master_wand.json deleted file mode 100644 index e7875627..00000000 --- a/src/main/resources/assets/wizardry/models/item/master_wand.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/wand_master" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/meteor.json b/src/main/resources/assets/wizardry/models/item/meteor.json deleted file mode 100644 index 14bb6068..00000000 --- a/src/main/resources/assets/wizardry/models/item/meteor.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "wizardry:block/meteor" -} diff --git a/src/main/resources/assets/wizardry/models/item/petrified_stone.json b/src/main/resources/assets/wizardry/models/item/petrified_stone.json deleted file mode 100644 index 68982f03..00000000 --- a/src/main/resources/assets/wizardry/models/item/petrified_stone.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "block/stone" -} diff --git a/src/main/resources/assets/wizardry/models/item/poison_bomb.json b/src/main/resources/assets/wizardry/models/item/poison_bomb.json deleted file mode 100644 index d4c0d24a..00000000 --- a/src/main/resources/assets/wizardry/models/item/poison_bomb.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/poison_bomb" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/range_upgrade.json b/src/main/resources/assets/wizardry/models/item/range_upgrade.json deleted file mode 100644 index 10896bb2..00000000 --- a/src/main/resources/assets/wizardry/models/item/range_upgrade.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/upgrade_range" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/scroll.json b/src/main/resources/assets/wizardry/models/item/scroll.json deleted file mode 100644 index a6a86d05..00000000 --- a/src/main/resources/assets/wizardry/models/item/scroll.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/scroll" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/siphon_upgrade.json b/src/main/resources/assets/wizardry/models/item/siphon_upgrade.json deleted file mode 100644 index eec82d86..00000000 --- a/src/main/resources/assets/wizardry/models/item/siphon_upgrade.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/upgrade_siphon" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/smoke_bomb.json b/src/main/resources/assets/wizardry/models/item/smoke_bomb.json deleted file mode 100644 index 0fffc501..00000000 --- a/src/main/resources/assets/wizardry/models/item/smoke_bomb.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/smoke_bomb" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/snare.json b/src/main/resources/assets/wizardry/models/item/snare.json deleted file mode 100644 index ec41cce6..00000000 --- a/src/main/resources/assets/wizardry/models/item/snare.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:blocks/snare" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/spawn_wizard.json b/src/main/resources/assets/wizardry/models/item/spawn_wizard.json deleted file mode 100644 index 908f7fa0..00000000 --- a/src/main/resources/assets/wizardry/models/item/spawn_wizard.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "items/spawn_egg", - "layer1": "items/spawn_egg_overlay" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/spectral_block.json b/src/main/resources/assets/wizardry/models/item/spectral_block.json deleted file mode 100644 index 9d577615..00000000 --- a/src/main/resources/assets/wizardry/models/item/spectral_block.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "wizardry:block/spectral_block" -} diff --git a/src/main/resources/assets/wizardry/models/item/spectral_boots.json b/src/main/resources/assets/wizardry/models/item/spectral_boots.json deleted file mode 100644 index e21ea294..00000000 --- a/src/main/resources/assets/wizardry/models/item/spectral_boots.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/spectral_boots" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/spectral_bow.json b/src/main/resources/assets/wizardry/models/item/spectral_bow.json deleted file mode 100644 index 649b7409..00000000 --- a/src/main/resources/assets/wizardry/models/item/spectral_bow.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/spectral_bow_standby" - }, - "display": { - "thirdperson_righthand": { - "rotation": [ -80, 260, -40 ], - "translation": [ -1, -2, 2.5 ], - "scale": [ 0.9, 0.9, 0.9 ] - }, - "thirdperson_lefthand": { - "rotation": [ -80, -280, 40 ], - "translation": [ -1, -2, 2.5 ], - "scale": [ 0.9, 0.9, 0.9 ] - }, - "firstperson_righthand": { - "rotation": [ 0, -90, 25 ], - "translation": [ 1.13, 3.2, 1.13], - "scale": [ 0.68, 0.68, 0.68 ] - }, - "firstperson_lefthand": { - "rotation": [ 0, 90, -25 ], - "translation": [ 1.13, 3.2, 1.13], - "scale": [ 0.68, 0.68, 0.68 ] - } - }, - "overrides": [ - { - "predicate": { - "pulling": 1 - }, - "model": "wizardry:item/spectral_bow_pulling_0" - }, - { - "predicate": { - "pulling": 1, - "pull": 0.65 - }, - "model": "wizardry:item/spectral_bow_pulling_1" - }, - { - "predicate": { - "pulling": 1, - "pull": 0.9 - }, - "model": "wizardry:item/spectral_bow_pulling_2" - } - ] -} diff --git a/src/main/resources/assets/wizardry/models/item/spectral_bow_pulling_0.json b/src/main/resources/assets/wizardry/models/item/spectral_bow_pulling_0.json deleted file mode 100644 index 94e5d474..00000000 --- a/src/main/resources/assets/wizardry/models/item/spectral_bow_pulling_0.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/bow", - "textures": { - "layer0": "wizardry:items/spectral_bow_pulling_0" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/spectral_bow_pulling_1.json b/src/main/resources/assets/wizardry/models/item/spectral_bow_pulling_1.json deleted file mode 100644 index 1c711fa3..00000000 --- a/src/main/resources/assets/wizardry/models/item/spectral_bow_pulling_1.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/bow", - "textures": { - "layer0": "wizardry:items/spectral_bow_pulling_1" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/spectral_bow_pulling_2.json b/src/main/resources/assets/wizardry/models/item/spectral_bow_pulling_2.json deleted file mode 100644 index b4762523..00000000 --- a/src/main/resources/assets/wizardry/models/item/spectral_bow_pulling_2.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/bow", - "textures": { - "layer0": "wizardry:items/spectral_bow_pulling_2" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/spectral_chestplate.json b/src/main/resources/assets/wizardry/models/item/spectral_chestplate.json deleted file mode 100644 index 33de309e..00000000 --- a/src/main/resources/assets/wizardry/models/item/spectral_chestplate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/spectral_chestplate" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/spectral_helmet.json b/src/main/resources/assets/wizardry/models/item/spectral_helmet.json deleted file mode 100644 index 5a8a9433..00000000 --- a/src/main/resources/assets/wizardry/models/item/spectral_helmet.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/spectral_helmet" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/spectral_leggings.json b/src/main/resources/assets/wizardry/models/item/spectral_leggings.json deleted file mode 100644 index e55f9c23..00000000 --- a/src/main/resources/assets/wizardry/models/item/spectral_leggings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/spectral_leggings" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/spectral_pickaxe.json b/src/main/resources/assets/wizardry/models/item/spectral_pickaxe.json deleted file mode 100644 index 45347c00..00000000 --- a/src/main/resources/assets/wizardry/models/item/spectral_pickaxe.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/spectral_pickaxe" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/spectral_sword.json b/src/main/resources/assets/wizardry/models/item/spectral_sword.json deleted file mode 100644 index 4e88c159..00000000 --- a/src/main/resources/assets/wizardry/models/item/spectral_sword.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/handheld", - "textures": { - "layer0": "wizardry:items/spectral_sword" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/spell_book.json b/src/main/resources/assets/wizardry/models/item/spell_book.json deleted file mode 100644 index 5a3d2fdb..00000000 --- a/src/main/resources/assets/wizardry/models/item/spell_book.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/spell_book" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/storage_upgrade.json b/src/main/resources/assets/wizardry/models/item/storage_upgrade.json deleted file mode 100644 index 3673fa43..00000000 --- a/src/main/resources/assets/wizardry/models/item/storage_upgrade.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/upgrade_storage" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/transportation_stone.json b/src/main/resources/assets/wizardry/models/item/transportation_stone.json deleted file mode 100644 index 2b0a1e09..00000000 --- a/src/main/resources/assets/wizardry/models/item/transportation_stone.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "parent": "wizardry:block/transportation_stone" -} diff --git a/src/main/resources/assets/wizardry/models/item/vanishing_cobweb.json b/src/main/resources/assets/wizardry/models/item/vanishing_cobweb.json deleted file mode 100644 index 1fe6d579..00000000 --- a/src/main/resources/assets/wizardry/models/item/vanishing_cobweb.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "blocks/web" - } -} diff --git a/src/main/resources/assets/wizardry/models/item/wizard_boots.json b/src/main/resources/assets/wizardry/models/item/wizard_boots.json deleted file mode 100644 index 39685945..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_boots.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_boots" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_boots_earth.json b/src/main/resources/assets/wizardry/models/item/wizard_boots_earth.json deleted file mode 100644 index 9ee903af..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_boots_earth.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_boots_earth" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_boots_fire.json b/src/main/resources/assets/wizardry/models/item/wizard_boots_fire.json deleted file mode 100644 index a1e664d0..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_boots_fire.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_boots_fire" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_boots_healing.json b/src/main/resources/assets/wizardry/models/item/wizard_boots_healing.json deleted file mode 100644 index 57c5b635..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_boots_healing.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_boots_healing" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_boots_ice.json b/src/main/resources/assets/wizardry/models/item/wizard_boots_ice.json deleted file mode 100644 index be14210e..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_boots_ice.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_boots_ice" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_boots_lightning.json b/src/main/resources/assets/wizardry/models/item/wizard_boots_lightning.json deleted file mode 100644 index d6904206..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_boots_lightning.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_boots_lightning" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_boots_necromancy.json b/src/main/resources/assets/wizardry/models/item/wizard_boots_necromancy.json deleted file mode 100644 index 65abcd7b..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_boots_necromancy.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_boots_necromancy" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_boots_sorcery.json b/src/main/resources/assets/wizardry/models/item/wizard_boots_sorcery.json deleted file mode 100644 index ffbf448b..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_boots_sorcery.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_boots_sorcery" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_handbook.json b/src/main/resources/assets/wizardry/models/item/wizard_handbook.json deleted file mode 100644 index c302b6b6..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_handbook.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_handbook" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_hat.json b/src/main/resources/assets/wizardry/models/item/wizard_hat.json deleted file mode 100644 index 7f1dad7a..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_hat.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_hat" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_hat_earth.json b/src/main/resources/assets/wizardry/models/item/wizard_hat_earth.json deleted file mode 100644 index 95273a7f..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_hat_earth.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_hat_earth" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_hat_fire.json b/src/main/resources/assets/wizardry/models/item/wizard_hat_fire.json deleted file mode 100644 index abecf19d..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_hat_fire.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_hat_fire" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_hat_healing.json b/src/main/resources/assets/wizardry/models/item/wizard_hat_healing.json deleted file mode 100644 index 0c453f01..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_hat_healing.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_hat_healing" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_hat_ice.json b/src/main/resources/assets/wizardry/models/item/wizard_hat_ice.json deleted file mode 100644 index 98430ed6..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_hat_ice.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_hat_ice" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_hat_lightning.json b/src/main/resources/assets/wizardry/models/item/wizard_hat_lightning.json deleted file mode 100644 index 408eae50..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_hat_lightning.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_hat_lightning" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_hat_necromancy.json b/src/main/resources/assets/wizardry/models/item/wizard_hat_necromancy.json deleted file mode 100644 index 8c62b1dd..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_hat_necromancy.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_hat_necromancy" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_hat_sorcery.json b/src/main/resources/assets/wizardry/models/item/wizard_hat_sorcery.json deleted file mode 100644 index 3cb674bb..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_hat_sorcery.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_hat_sorcery" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_leggings.json b/src/main/resources/assets/wizardry/models/item/wizard_leggings.json deleted file mode 100644 index 02aed97c..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_leggings.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_leggings" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_leggings_earth.json b/src/main/resources/assets/wizardry/models/item/wizard_leggings_earth.json deleted file mode 100644 index 8fcec98f..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_leggings_earth.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_leggings_earth" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_leggings_fire.json b/src/main/resources/assets/wizardry/models/item/wizard_leggings_fire.json deleted file mode 100644 index bcb63bac..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_leggings_fire.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_leggings_fire" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_leggings_healing.json b/src/main/resources/assets/wizardry/models/item/wizard_leggings_healing.json deleted file mode 100644 index 16c90a84..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_leggings_healing.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_leggings_healing" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_leggings_ice.json b/src/main/resources/assets/wizardry/models/item/wizard_leggings_ice.json deleted file mode 100644 index c1424913..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_leggings_ice.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_leggings_ice" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_leggings_lightning.json b/src/main/resources/assets/wizardry/models/item/wizard_leggings_lightning.json deleted file mode 100644 index f8e4824c..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_leggings_lightning.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_leggings_lightning" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_leggings_necromancy.json b/src/main/resources/assets/wizardry/models/item/wizard_leggings_necromancy.json deleted file mode 100644 index 9c97d209..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_leggings_necromancy.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_leggings_necromancy" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_leggings_sorcery.json b/src/main/resources/assets/wizardry/models/item/wizard_leggings_sorcery.json deleted file mode 100644 index 3ac6dd52..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_leggings_sorcery.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_leggings_sorcery" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_robe.json b/src/main/resources/assets/wizardry/models/item/wizard_robe.json deleted file mode 100644 index 7f8e266e..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_robe.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_robe" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_robe_earth.json b/src/main/resources/assets/wizardry/models/item/wizard_robe_earth.json deleted file mode 100644 index 66ed7826..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_robe_earth.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_robe_earth" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_robe_fire.json b/src/main/resources/assets/wizardry/models/item/wizard_robe_fire.json deleted file mode 100644 index 6ab282f2..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_robe_fire.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_robe_fire" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_robe_healing.json b/src/main/resources/assets/wizardry/models/item/wizard_robe_healing.json deleted file mode 100644 index 54cba900..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_robe_healing.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_robe_healing" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_robe_ice.json b/src/main/resources/assets/wizardry/models/item/wizard_robe_ice.json deleted file mode 100644 index 45398f00..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_robe_ice.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_robe_ice" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_robe_lightning.json b/src/main/resources/assets/wizardry/models/item/wizard_robe_lightning.json deleted file mode 100644 index ce513b4a..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_robe_lightning.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_robe_lightning" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_robe_necromancy.json b/src/main/resources/assets/wizardry/models/item/wizard_robe_necromancy.json deleted file mode 100644 index c3ff763a..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_robe_necromancy.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_robe_necromancy" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/models/item/wizard_robe_sorcery.json b/src/main/resources/assets/wizardry/models/item/wizard_robe_sorcery.json deleted file mode 100644 index 2b5224eb..00000000 --- a/src/main/resources/assets/wizardry/models/item/wizard_robe_sorcery.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "item/generated", - "textures": { - "layer0": "wizardry:items/wizard_robe_sorcery" - } -} \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/sounds.json b/src/main/resources/assets/wizardry/sounds.json index 857b9a40..9111e00c 100644 --- a/src/main/resources/assets/wizardry/sounds.json +++ b/src/main/resources/assets/wizardry/sounds.json @@ -1,39 +1,38 @@ { "arc": {"category": "player","sounds": [ - {"name": "wizardry:arc1","stream": false}, - {"name": "wizardry:arc1","stream": false}, - {"name": "wizardry:arc3","stream": false} + {"name": "arc1","stream": false}, + {"name": "arc1","stream": false}, + {"name": "arc3","stream": false} ]}, - "aura": {"category": "player","sounds": [{"name": "wizardry:aura","stream": false}]}, - "boom": {"category": "player","sounds": [{"name": "wizardry:boom","stream": false}]}, - "crackle": {"category": "player","sounds": [{"name": "wizardry:crackle","stream": false}]}, + "aura": {"category": "player","sounds": [{"name": "aura","stream": false}]}, + "boom": {"category": "player","sounds": [{"name": "boom","stream": false}]}, + "crackle": {"category": "player","sounds": [{"name": "crackle","stream": false}]}, "darkaura": {"category": "player","sounds": [ - {"name": "wizardry:darkaura1","stream": false}, - {"name": "wizardry:darkaura2","stream": false} + {"name": "darkaura1","stream": false}, + {"name": "darkaura2","stream": false} ]}, "effect": {"category": "player","sounds": [ - {"name": "wizardry:effect1","stream": false}, - {"name": "wizardry:effect2","stream": false} + {"name": "effect1","stream": false}, + {"name": "effect2","stream": false} ]}, - "electricitya": {"category": "player","sounds": [{"name": "wizardry:electricitya","stream": false}]}, - "electricityb": {"category": "player","sounds": [{"name": "wizardry:electricityb","stream": false}]}, + "electricitya": {"category": "player","sounds": [{"name": "electricitya","stream": false}]}, + "electricityb": {"category": "player","sounds": [{"name": "electricityb","stream": false}]}, - "flameray": {"category": "player","sounds": [{"name": "wizardry:flameray2","stream": false}]}, - "force": {"category": "player","sounds": [{"name": "wizardry:force","stream": false}]}, + "flameray": {"category": "player","sounds": [{"name": "flameray2","stream": false}]}, - "freeze": {"category": "player","sounds": [{"name": "wizardry:freeze","stream": false}]}, - "frostray": {"category": "player","sounds": [{"name": "wizardry:frostray","stream": false}]}, - "heal": {"category": "player","sounds": [{"name": "wizardry:heal","stream": false}]}, - "ice": {"category": "player","sounds": [{"name": "wizardry:ice","stream": false}]}, - "largeaura": {"category": "player","sounds": [{"name": "wizardry:largeaura","stream": false}]}, + "freeze": {"category": "player","sounds": [{"name": "freeze","stream": false}]}, + "frostray": {"category": "player","sounds": [{"name": "frostray","stream": false}]}, + "heal": {"category": "player","sounds": [{"name": "heal","stream": false}]}, + "ice": {"category": "player","sounds": [{"name": "ice","stream": false}]}, + "largeaura": {"category": "player","sounds": [{"name": "largeaura","stream": false}]}, - "magic": {"category": "player","sounds": [{"name": "wizardry:magic1","stream": false}]}, + "magic": {"category": "player","sounds": [{"name": "magic1","stream": false}]}, - "sparkle": {"category": "player","sounds": [{"name": "wizardry:sparkle","stream": false}]}, - "wind": {"category": "player","sounds": [{"name": "wizardry:wind","stream": false}]}, - "rumble": {"category": "player","sounds": [{"name": "wizardry:rumble","stream": false}]} + "sparkle": {"category": "player","sounds": [{"name": "sparkle","stream": false}]}, + "wind": {"category": "player","sounds": [{"name": "wind","stream": false}]}, + "rumble": {"category": "player","sounds": [{"name": "rumble","stream": false}]} } \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/sounds/force.ogg b/src/main/resources/assets/wizardry/sounds/force.ogg deleted file mode 100644 index 0da336b2..00000000 Binary files a/src/main/resources/assets/wizardry/sounds/force.ogg and /dev/null differ diff --git a/src/main/resources/assets/wizardry/texts/handbook_en_GB.txt b/src/main/resources/assets/wizardry/texts/handbook_en_GB.txt index b2c9d08a..a5e68aec 100644 --- a/src/main/resources/assets/wizardry/texts/handbook_en_GB.txt +++ b/src/main/resources/assets/wizardry/texts/handbook_en_GB.txt @@ -199,7 +199,7 @@ Credits -------------------- Electroblob's Wizardry Version VERSION -For Minecraft 1.10.2 +For Minecraft 1.7.10 Designed, coded and textured by Electroblob @@ -212,6 +212,5 @@ In addition, I'd like to thank the following individuals for their contributions Translations: - Russian: VilagVil -- Spanish and Mexican Spanish: MadWrist Lightning ray sound effect from OhhWowProductions \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/texts/handbook_en_US.txt b/src/main/resources/assets/wizardry/texts/handbook_en_US.txt index 95746130..d950d3f1 100644 --- a/src/main/resources/assets/wizardry/texts/handbook_en_US.txt +++ b/src/main/resources/assets/wizardry/texts/handbook_en_US.txt @@ -199,7 +199,7 @@ Credits -------------------- Electroblob's Wizardry Version VERSION -For Minecraft 1.10.2 +For Minecraft 1.7.10 Designed, coded and textured by Electroblob @@ -212,6 +212,5 @@ In addition, I'd like to thank the following individuals for their contributions Translations: - Russian: VilagVil -- Spanish and Mexican Spanish: MadWrist Lightning ray sound effect from OhhWowProductions \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/texts/handbook_es_ES.txt b/src/main/resources/assets/wizardry/texts/handbook_es_ES.txt index 9747dc36..80549c4a 100644 --- a/src/main/resources/assets/wizardry/texts/handbook_es_ES.txt +++ b/src/main/resources/assets/wizardry/texts/handbook_es_ES.txt @@ -293,7 +293,7 @@ Creditos -------------------- Electroblob's Wizardry Version VERSION -Para Minecraft 1.10.2 +Para Minecraft 1.7.10 Disenado, codificado y texturizado por Electroblob @@ -306,6 +306,5 @@ In addition, I'd like to thank the following individuals for their contributions Translations: - Russian: VilagVil -- Spanish and Mexican Spanish: MadWrist Lightning ray sound effect from OhhWowProductions \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/texts/handbook_es_MX.txt b/src/main/resources/assets/wizardry/texts/handbook_es_MX.txt index 9747dc36..80549c4a 100644 --- a/src/main/resources/assets/wizardry/texts/handbook_es_MX.txt +++ b/src/main/resources/assets/wizardry/texts/handbook_es_MX.txt @@ -293,7 +293,7 @@ Creditos -------------------- Electroblob's Wizardry Version VERSION -Para Minecraft 1.10.2 +Para Minecraft 1.7.10 Disenado, codificado y texturizado por Electroblob @@ -306,6 +306,5 @@ In addition, I'd like to thank the following individuals for their contributions Translations: - Russian: VilagVil -- Spanish and Mexican Spanish: MadWrist Lightning ray sound effect from OhhWowProductions \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/texts/handbook_ru_RU.txt b/src/main/resources/assets/wizardry/texts/handbook_ru_RU.txt index 81d2fcb9..e85bfdbb 100644 --- a/src/main/resources/assets/wizardry/texts/handbook_ru_RU.txt +++ b/src/main/resources/assets/wizardry/texts/handbook_ru_RU.txt @@ -204,7 +204,7 @@ Credits ------------------------------ Electroblob's Wizardry Version VERSION -For Minecraft 1.10.2 +For Minecraft 1.7.10 Designed, coded and textured by Electroblob @@ -217,6 +217,5 @@ In addition, I'd like to thank the following individuals for their contributions Translations: - Russian: VilagVil -- Spanish and Mexican Spanish: MadWrist Lightning ray sound effect from OhhWowProductions \ No newline at end of file diff --git a/src/main/resources/assets/wizardry/textures/gui/arcane_workbench.png b/src/main/resources/assets/wizardry/textures/gui/arcane_workbench.png index 02a43a70..d73fb803 100644 Binary files a/src/main/resources/assets/wizardry/textures/gui/arcane_workbench.png and b/src/main/resources/assets/wizardry/textures/gui/arcane_workbench.png differ diff --git a/src/main/resources/assets/wizardry/textures/gui/element_icon_earth.png b/src/main/resources/assets/wizardry/textures/gui/element_icon_earth.png deleted file mode 100644 index 9413854f..00000000 Binary files a/src/main/resources/assets/wizardry/textures/gui/element_icon_earth.png and /dev/null differ diff --git a/src/main/resources/assets/wizardry/textures/gui/element_icon_fire.png b/src/main/resources/assets/wizardry/textures/gui/element_icon_fire.png deleted file mode 100644 index 37cb27c6..00000000 Binary files a/src/main/resources/assets/wizardry/textures/gui/element_icon_fire.png and /dev/null differ diff --git a/src/main/resources/assets/wizardry/textures/gui/element_icon_healing.png b/src/main/resources/assets/wizardry/textures/gui/element_icon_healing.png deleted file mode 100644 index 4225f1d2..00000000 Binary files a/src/main/resources/assets/wizardry/textures/gui/element_icon_healing.png and /dev/null differ diff --git a/src/main/resources/assets/wizardry/textures/gui/element_icon_ice.png b/src/main/resources/assets/wizardry/textures/gui/element_icon_ice.png deleted file mode 100644 index d9079b6f..00000000 Binary files a/src/main/resources/assets/wizardry/textures/gui/element_icon_ice.png and /dev/null differ diff --git a/src/main/resources/assets/wizardry/textures/gui/element_icon_lightning.png b/src/main/resources/assets/wizardry/textures/gui/element_icon_lightning.png deleted file mode 100644 index 287483d3..00000000 Binary files a/src/main/resources/assets/wizardry/textures/gui/element_icon_lightning.png and /dev/null differ diff --git a/src/main/resources/assets/wizardry/textures/gui/element_icon_necromancy.png b/src/main/resources/assets/wizardry/textures/gui/element_icon_necromancy.png deleted file mode 100644 index 38bcbc45..00000000 Binary files a/src/main/resources/assets/wizardry/textures/gui/element_icon_necromancy.png and /dev/null differ diff --git a/src/main/resources/assets/wizardry/textures/gui/element_icon_simple.png b/src/main/resources/assets/wizardry/textures/gui/element_icon_simple.png deleted file mode 100644 index 9531eb9a..00000000 Binary files a/src/main/resources/assets/wizardry/textures/gui/element_icon_simple.png and /dev/null differ diff --git a/src/main/resources/assets/wizardry/textures/gui/element_icon_sorcery.png b/src/main/resources/assets/wizardry/textures/gui/element_icon_sorcery.png deleted file mode 100644 index 3900024f..00000000 Binary files a/src/main/resources/assets/wizardry/textures/gui/element_icon_sorcery.png and /dev/null differ diff --git a/src/main/resources/assets/wizardry/textures/gui/empty_slot_crystal.png b/src/main/resources/assets/wizardry/textures/gui/empty_slot_crystal.png deleted file mode 100644 index a4893196..00000000 Binary files a/src/main/resources/assets/wizardry/textures/gui/empty_slot_crystal.png and /dev/null differ diff --git a/src/main/resources/assets/wizardry/textures/gui/empty_slot_upgrade.png b/src/main/resources/assets/wizardry/textures/gui/empty_slot_upgrade.png deleted file mode 100644 index 22939c7e..00000000 Binary files a/src/main/resources/assets/wizardry/textures/gui/empty_slot_upgrade.png and /dev/null differ diff --git a/src/main/resources/assets/wizardry/textures/gui/sixth_sense_overlay.png b/src/main/resources/assets/wizardry/textures/gui/sixth_sense_overlay.png index ba327477..8791893f 100644 Binary files a/src/main/resources/assets/wizardry/textures/gui/sixth_sense_overlay.png and b/src/main/resources/assets/wizardry/textures/gui/sixth_sense_overlay.png differ diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 015fbd16..b11683b0 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -2,7 +2,7 @@ { "modid" : "wizardry", "name" : "Electroblob's Wizardry", - "version" : "2.1.2", + "version" : "1.1.5", "url" : "https://minecraft.curseforge.com/projects/electroblobs-wizardry", "credits" : "Made by Electroblob", "authors" : [