Compare commits

..

17 Commits

Author SHA1 Message Date
Electroblob 339ec69a72 Update version number 2018-04-14 15:53:51 +01:00
Electroblob b2cb717aa3 Cleanup 2018-04-14 15:47:31 +01:00
Electroblob cf4a02f37f Fix crash related to creative tab sorting with HQM installed 2018-04-14 15:28:19 +01:00
Electroblob 84304dd7ce Prevent possible server crash with static initialiser block 2018-04-14 15:26:47 +01:00
Electroblob e3b44eb194 Make entities attacked by summoned creatures revenge-target the summoned creature rather than its summoner 2018-04-14 14:09:16 +01:00
Electroblob 2cbb0a590f Correct position of spell cooldown bar when spell HUD is at top of screen; fixes #14 2018-04-14 13:22:53 +01:00
Electroblob 6b9c864890 Move target position references inside null checks; fixes #13 2018-04-14 13:19:17 +01:00
Electroblob c15a0763d5 Merge branch '1.12.2' of https://github.com/Electroblob77/Wizardry into 1.12.2 2018-04-10 16:04:35 +01:00
Electroblob 4a23d88f30 Add obfuscated names to reflective field access 2018-04-10 16:03:23 +01:00
Electroblob 286705c79b Update README.md 2018-04-09 23:11:23 +01:00
Electroblob 3895f5c531 Cleanup 2018-04-09 17:29:41 +01:00
Electroblob c51e0bd218 Fix mods list logo 2018-04-09 17:29:18 +01:00
Electroblob 766570aeb2 Fix spell book for crystals trade not working 2018-04-09 17:28:59 +01:00
Electroblob 4e91b0d19d Fix broken lang key in config GUI 2018-04-08 00:04:35 +01:00
Electroblob 65f7630546 Update minecraft version number in wizard's handbook 2018-04-08 00:04:06 +01:00
Electroblob 8cf7572041 Update mcmod.info 2018-04-08 00:03:39 +01:00
Electroblob db057a5ca9 Update credits 2018-04-08 00:03:15 +01:00
21 changed files with 253 additions and 69 deletions
+3 -2
View File
@@ -1,8 +1,8 @@
# Credits
Electroblob's Wizardry
Version 3.1.0
For Minecraft 1.11.2
Version 4.1.0
For Minecraft 1.12.2
Designed, coded and textured by Electroblob
@@ -15,6 +15,7 @@ In addition, I'd like to thank the following individuals for their contributions
#### Code
- Corail31
- 12foo
#### Translations
+1 -1
View File
@@ -2,7 +2,7 @@
![Image not found](https://media-elerium.cursecdn.com/attachments/203/387/banner7.png)
Source code for Electroblob's Wizardry, a Minecraft mod currently for versions 1.7.10, 1.10.2 and 1.11.2. Wizardry adds an RPG-style system of magic spells to Minecraft with the aim of being as playable as possible. No crazy constructs, no perk trees, no complex recipes - simply find spell books, cast spells, and master the arcane!
Source code for Electroblob's Wizardry, a Minecraft mod currently for versions 1.7.10, 1.10.2, 1.11.2, and 1.12.2. Wizardry adds an RPG-style system of magic spells to Minecraft with the aim of being as playable as possible. No crazy constructs, no perk trees, no complex recipes - simply find spell books, cast spells, and master the arcane!
Please read the [guide for contributing](guide_for_contributing.md) before submitting an issue or a PR.
+1 -1
View File
@@ -11,7 +11,7 @@ apply plugin: 'net.minecraftforge.gradle.forge'
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
version = " 4.1.0 - MC 1.12.2"
version = " 4.1.1 - MC 1.12.2"
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "Electroblob's Wizardry "
@@ -35,8 +35,6 @@ import net.minecraftforge.fml.common.registry.GameRegistry;
public class Wizardry {
/** Wizardry's mod ID. */
// This is going to have to change for 1.12 or it'll conflict with the other wizardry mod.
// They were there first, it's only fair... although I wonder if that will have unintended side-effects?
public static final String MODID = "ebwizardry";
/** Wizardry's mod name, in readable form. */
public static final String NAME = "Electroblob's Wizardry";
@@ -50,7 +48,7 @@ public class Wizardry {
* 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 = "4.1.0";
public static final String VERSION = "4.1.1";
// 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
@@ -28,7 +28,7 @@ public class GuiConfigWizardry extends GuiConfig {
configList.add(new DummyCategoryElement("spellsConfig", "config." + Wizardry.MODID + ".category." + Settings.SPELLS_CATEGORY,
SpellsCategory.class));
configList.add(new DummyCategoryElement("resistancesConfig",
"config.wizardry.category." + Settings.RESISTANCES_CATEGORY, ResistancesCategory.class));
"config." + Wizardry.MODID + ".category." + Settings.RESISTANCES_CATEGORY, ResistancesCategory.class));
configList.addAll(new ConfigElement(Wizardry.settings.getConfigCategory(Configuration.CATEGORY_GENERAL))
.getChildElements());
return configList;
@@ -135,11 +135,11 @@ public class GuiSpellDisplay extends Gui {
// Cooldown bar
if(cooldown > 0){
this.drawTexturedModalRect(mirror ? left + 5 : left + 41, height - 8, 128, 6, 82, 6);
this.drawTexturedModalRect(mirror ? left + 5 : left + 41, top + 28, 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);
this.drawTexturedModalRect(mirror ? left + 5 : left + 41, top + 28, 128, 0, l, 6);
}
// Spell illustration
@@ -365,7 +365,7 @@ public class GuiWizardHandbook extends GuiScreen {
paragraph = paragraph.replaceAll("SORCERY_COLOUR", Element.SORCERY.getFormattingCode());
paragraph = paragraph.replaceAll("HEALING_COLOUR", Element.HEALING.getFormattingCode());
paragraph = paragraph.replaceAll("RESET_COLOUR", "\u00A70");
paragraph = paragraph.replaceAll("MCVERSION", "1.11.2");
paragraph = paragraph.replaceAll("MCVERSION", "1.12.2");
paragraph = paragraph.replaceAll("VERSION", Wizardry.VERSION);
int linesInParagraph = this.fontRenderer
@@ -1,5 +1,7 @@
package electroblob.wizardry.client;
import java.lang.reflect.Field;
import org.lwjgl.opengl.GL11;
import electroblob.wizardry.WizardData;
@@ -9,6 +11,7 @@ import electroblob.wizardry.item.ItemSpectralBow;
import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.packet.PacketControlInput;
import electroblob.wizardry.packet.WizardryPacketHandler;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.spell.Flight;
import electroblob.wizardry.spell.ShadowWard;
@@ -17,19 +20,27 @@ import electroblob.wizardry.tileentity.ContainerArcaneWorkbench;
import electroblob.wizardry.util.WandHelper;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiMerchant;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityArmorStand;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.village.MerchantRecipe;
import net.minecraftforge.client.event.FOVUpdateEvent;
import net.minecraftforge.client.event.GuiContainerEvent;
import net.minecraftforge.client.event.MouseEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderLivingEvent;
@@ -39,7 +50,9 @@ 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.ReflectionHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
/**
* Event handler responsible for all client-side only events, mostly rendering.
@@ -47,6 +60,7 @@ import net.minecraftforge.fml.relauncher.Side;
* @author Electroblob
* @since Wizardry 1.0
*/
@SideOnly(Side.CLIENT)
@Mod.EventBusSubscriber(Side.CLIENT)
public final class WizardryClientEventHandler {
@@ -59,6 +73,12 @@ public final class WizardryClientEventHandler {
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 Field ITEM_RENDERER;
static {
ITEM_RENDERER = ReflectionHelper.findField(GuiScreen.class, "itemRender", "field_146296_j");
}
@SubscribeEvent
public static void onTextureStitchEvent(TextureStitchEvent.Pre event){
event.getMap().registerSprite(ContainerArcaneWorkbench.EMPTY_SLOT_CRYSTAL);
@@ -115,6 +135,66 @@ public final class WizardryClientEventHandler {
event.setNewfov(event.getFov() * 1.0F - maxUseSeconds * 0.15F);
}
}
// Brute-force fix for crystals not showing up when a wizard is given a spell book in the trade GUI.
@SubscribeEvent
public static void onGuiDrawForegroundEvent(GuiContainerEvent.DrawForeground event){
if(event.getGuiContainer() instanceof GuiMerchant){
GuiMerchant gui = (GuiMerchant)event.getGuiContainer();
// Note that gui.getMerchant() returns an NpcMerchant, not an EntityWizard.
// Using == the specific item rather than instanceof because that's how trades do it.
if(gui.inventorySlots.getSlot(0).getStack().getItem() == WizardryItems.spell_book
|| gui.inventorySlots.getSlot(1).getStack().getItem() == WizardryItems.spell_book){
for(MerchantRecipe trade : gui.getMerchant().getRecipes(Minecraft.getMinecraft().player)){
if(trade.getItemToBuy().getItem() == WizardryItems.spell_book && trade.getSecondItemToBuy().isEmpty()){
Slot slot = gui.inventorySlots.getSlot(2);
// Uses reflection to draw the itemstack
// It still doesn't look quite right because the slot highlight is behind the item, but it'll do
// until/unless I find a better solution.
renderItemAndTooltip(gui, trade.getItemToSell(), slot.xPos, slot.yPos, event.getMouseX(), event.getMouseY(),
gui.getSlotUnderMouse() == slot);
}
}
}
}
}
private static void renderItemAndTooltip(GuiContainer gui, ItemStack stack, int x, int y, int mouseX, int mouseY, boolean tooltip){
try {
RenderItem renderItem = (RenderItem)ITEM_RENDERER.get(gui);
GlStateManager.pushMatrix();
RenderHelper.enableGUIStandardItemLighting();
GlStateManager.disableLighting();
GlStateManager.enableRescaleNormal();
GL11.glEnable(GL11.GL_COLOR_MATERIAL);
GlStateManager.enableLighting();
renderItem.zLevel = 100.0F;
if(!stack.isEmpty()){
renderItem.renderItemAndEffectIntoGUI(stack, x, y);
renderItem.renderItemOverlays(Minecraft.getMinecraft().fontRenderer, stack, x, y);
if(tooltip){
gui.drawHoveringText(gui.getItemToolTip(stack), mouseX + gui.getXSize()/2 - gui.width/2,
mouseY + gui.getYSize()/2 - gui.height/2);
}
}
GlStateManager.popMatrix();
GlStateManager.enableLighting();
GL11.glEnable(GL11.GL_DEPTH_TEST);
RenderHelper.enableStandardItemLighting();
} catch (Exception e){
e.printStackTrace();
}
}
// Third person
@SubscribeEvent
@@ -23,6 +23,7 @@ import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WandHelper;
import electroblob.wizardry.util.WildcardTradeList;
import electroblob.wizardry.util.WizardryParticleType;
import electroblob.wizardry.util.WizardryUtilities;
import io.netty.buffer.ByteBuf;
@@ -91,6 +92,7 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
* are overriding something, in which case it should be fine). */
// Extending EntityVillager turned out to be a pretty neat thing to do, since now zombies will attack wizards
// TODO: Perhaps we should be implementing IMerchant now instead?
private EntityAIAttackSpell spellCastingAI = new EntityAIAttackSpell(this, 0.5D, 14.0F, 30, 50);
@@ -369,7 +371,7 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
if(nbt.hasKey("trades")){
NBTTagCompound nbttagcompound1 = nbt.getCompoundTag("trades");
this.trades = new MerchantRecipeList(nbttagcompound1);
this.trades = new WildcardTradeList(nbttagcompound1);
}
this.setElement(Element.values()[nbt.getInteger("element")]);
@@ -428,7 +430,7 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
if(this.trades == null){
this.trades = new MerchantRecipeList();
this.trades = new WildcardTradeList();
// All wizards will buy spell books
ItemStack anySpellBook = new ItemStack(WizardryItems.spell_book, 1, OreDictionary.WILDCARD_VALUE);
@@ -509,7 +511,7 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
Collections.shuffle(merchantrecipelist);
if(this.trades == null){
this.trades = new MerchantRecipeList();
this.trades = new WildcardTradeList();
}
for(int j1 = 0; j1 < merchantrecipelist.size(); ++j1){
@@ -362,11 +362,18 @@ public interface ISummonedCreature extends IEntityAdditionalSpawnData {
if(event.getSource().isFireDamage()) newSource.setFireDamage();
if(event.getSource().isProjectile()) newSource.setProjectile();
// For some reason Minecraft calculates knockback relative to DamageSource#getEntity. In vanilla this
// For some reason Minecraft calculates knockback relative to DamageSource#getTrueSource. In vanilla this
// is unnoticeable, but it looks a bit weird with summoned creatures involved - so this fixes that.
if(WizardryUtilities.attackEntityWithoutKnockback(event.getEntity(), newSource, event.getAmount())){
// Using event.getSource().getTrueSource() as this means the target is knocked back from the minion
WizardryUtilities.applyStandardKnockback(event.getSource().getTrueSource(), event.getEntityLiving());
((ISummonedCreature)event.getSource().getTrueSource()).onSuccessfulAttack(event.getEntityLiving());
// If the target revenge-targeted the summoner, make it revenge-target the minion instead
// (if it didn't revenge-target, do nothing)
if(event.getEntityLiving().getRevengeTarget() == summoner
&& event.getSource().getTrueSource() instanceof EntityLivingBase){
event.getEntityLiving().setRevengeTarget((EntityLivingBase)event.getSource().getTrueSource());
}
}
}
@@ -5,8 +5,6 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.google.common.collect.Ordering;
import electroblob.wizardry.item.ItemScroll;
import electroblob.wizardry.item.ItemSpellBook;
import electroblob.wizardry.spell.Spell;
@@ -44,6 +42,7 @@ public final class WizardryTabs {
Collections.sort(items, itemSorter);
}
};
public static final CreativeTabs SPELLS = new CreativeTabs("ebwizardryspells"){
@Override
@@ -103,7 +102,14 @@ public final class WizardryTabs {
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(ItemStack::getItem);
itemSorter = (stack1, stack2) -> {
// Neither stack is in the creative tab
if(!orderedItemList.contains(stack1.getItem()) && !orderedItemList.contains(stack2.getItem())) return 0;
if(!orderedItemList.contains(stack1.getItem())) return 1; // Only stack 2 is in the creative tab
if(!orderedItemList.contains(stack2.getItem())) return -1; // Only stack 1 is in the creative tab
// Both stacks are in the creative tab
return orderedItemList.indexOf(stack1.getItem()) - orderedItemList.indexOf(stack2.getItem());
};
spellItemSorter = (stack1, stack2) -> {
@@ -79,36 +79,41 @@ public class FlameRay extends Spell {
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){
Vec3d vec = new Vec3d(target.posX - caster.posX, target.posY - caster.posY, target.posZ - caster.posZ).normalize();
target.setFire(10);
WizardryUtilities.attackEntityWithoutKnockback(target,
MagicDamage.causeDirectMagicDamage(caster, DamageType.FIRE),
3.0f * modifiers.get(SpellModifiers.DAMAGE));
}
if(world.isRemote){
for(int i = 0; i < 20; i++){
double x1 = caster.posX + vec.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.y * i / 2 + world.rand.nextFloat() / 5
- 0.1f;
double z1 = caster.posZ + vec.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
Wizardry.proxy.spawnParticle(WizardryParticleType.MAGIC_FIRE, world, x1, y1, z1,
vec.x * modifiers.get(WizardryItems.range_upgrade),
vec.y * modifiers.get(WizardryItems.range_upgrade),
vec.z * modifiers.get(WizardryItems.range_upgrade), 0);
Wizardry.proxy.spawnParticle(WizardryParticleType.MAGIC_FIRE, world, x1, y1, z1,
vec.x * modifiers.get(WizardryItems.range_upgrade),
vec.y * modifiers.get(WizardryItems.range_upgrade),
vec.z * modifiers.get(WizardryItems.range_upgrade), 0);
if(world.isRemote){
for(int i = 0; i < 20; i++){
double x1 = caster.posX + vec.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.y * i / 2 + world.rand.nextFloat() / 5
- 0.1f;
double z1 = caster.posZ + vec.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
Wizardry.proxy.spawnParticle(WizardryParticleType.MAGIC_FIRE, world, x1, y1, z1,
vec.x * modifiers.get(WizardryItems.range_upgrade),
vec.y * modifiers.get(WizardryItems.range_upgrade),
vec.z * modifiers.get(WizardryItems.range_upgrade), 0);
Wizardry.proxy.spawnParticle(WizardryParticleType.MAGIC_FIRE, world, x1, y1, z1,
vec.x * modifiers.get(WizardryItems.range_upgrade),
vec.y * modifiers.get(WizardryItems.range_upgrade),
vec.z * modifiers.get(WizardryItems.range_upgrade), 0);
}
}
if(ticksInUse % 16 == 0){
if(ticksInUse == 0) caster.playSound(SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
caster.playSound(WizardrySounds.SPELL_LOOP_FIRE, 0.5F, 1.0f);
}
return true;
}
if(ticksInUse % 16 == 0){
if(ticksInUse == 0) caster.playSound(SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
caster.playSound(WizardrySounds.SPELL_LOOP_FIRE, 0.5F, 1.0f);
}
return true;
return false;
}
@Override
@@ -72,39 +72,43 @@ public class LifeDrain extends Spell {
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){
Vec3d vec = new Vec3d(target.posX - caster.posX, target.posY - caster.posY, target.posZ - caster.posZ).normalize();
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.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.y * i / 2 + world.rand.nextFloat() / 5
- 0.1f;
double z1 = caster.posZ + vec.z * 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);
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.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.y * i / 2 + world.rand.nextFloat() / 5
- 0.1f;
double z1 = caster.posZ + vec.z * 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.x * i,
-0.05 * vec.y * i, -0.05 * vec.z * i, 8 + world.rand.nextInt(6), 0.5f, 0.0f, 0.0f);
}
Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, -0.05 * vec.x * i,
-0.05 * vec.y * i, -0.05 * vec.z * 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);
}
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;
return true;
}
return false;
}
@Override
@@ -364,8 +364,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
}
}
// ================================================ Static methods
// ==================================================
// ================================================ Static methods ==================================================
/**
* Returns the total number of registered spells, excluding the 'None' spell. Returns the same number that would be
@@ -0,0 +1,57 @@
package electroblob.wizardry.util;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.village.MerchantRecipe;
import net.minecraft.village.MerchantRecipeList;
import net.minecraftforge.oredict.OreDictionary;
/** Custom version of {@link MerchantRecipeList} which allows wildcard recipes (i.e. trades which accept items with any
* damage value). Function is otherwise identical. For some reason this feature was removed in 1.11.
* @author Electroblob
* @since Wizardry 4.1 */
@SuppressWarnings("serial")
public class WildcardTradeList extends MerchantRecipeList {
public WildcardTradeList(){
super();
}
public WildcardTradeList(NBTTagCompound tag){
super(tag);
}
@Override
public MerchantRecipe canRecipeBeUsed(ItemStack offer1, ItemStack offer2, int index){
if(index > 0 && index < this.size()){
MerchantRecipe merchantrecipe1 = (MerchantRecipe)this.get(index);
return !this.areItemStacksExactlyEqual(offer1, merchantrecipe1.getItemToBuy()) || (!offer2.isEmpty() || merchantrecipe1.hasSecondItemToBuy()) && (!merchantrecipe1.hasSecondItemToBuy() || !this.areItemStacksExactlyEqual(offer2, merchantrecipe1.getSecondItemToBuy())) || offer1.getCount() < merchantrecipe1.getItemToBuy().getCount() || merchantrecipe1.hasSecondItemToBuy() && offer2.getCount() < merchantrecipe1.getSecondItemToBuy().getCount() ? null : merchantrecipe1;
}else{
for(int i = 0; i < this.size(); ++i){
MerchantRecipe merchantrecipe = (MerchantRecipe)this.get(i);
if (this.areItemStacksExactlyEqual(offer1, merchantrecipe.getItemToBuy()) && offer1.getCount() >= merchantrecipe.getItemToBuy().getCount() && (!merchantrecipe.hasSecondItemToBuy() && offer2.isEmpty() || merchantrecipe.hasSecondItemToBuy() && this.areItemStacksExactlyEqual(offer2, merchantrecipe.getSecondItemToBuy()) && offer2.getCount() >= merchantrecipe.getSecondItemToBuy().getCount())){
return merchantrecipe;
}
}
return null;
}
}
private boolean areItemStacksExactlyEqual(ItemStack stack1, ItemStack stack2){
// Added to allow wildcards; this line is the only actual change.
if((stack1.getItemDamage() == OreDictionary.WILDCARD_VALUE || stack2.getItemDamage() == OreDictionary.WILDCARD_VALUE)
// Can't use ItemStack.areItemsEqualIgnoreDurability because that only works for items with durability, not subtypes.
&& stack1.getItem() == stack2.getItem()) return true;
return ItemStack.areItemsEqual(stack1, stack2) && (!stack2.hasTagCompound() || stack1.hasTagCompound() && NBTUtil.areNBTEquals(stack2.getTagCompound(), stack1.getTagCompound(), false));
}
}
@@ -209,6 +209,11 @@ Thanks also to the Minecraft modding community, which always has an answer to my
In addition, I'd like to thank the following individuals for their contributions to the mod:
Code:
- Corail31
- 12foo
Translations:
- Russian: VilagVil
@@ -209,6 +209,11 @@ Thanks also to the Minecraft modding community, which always has an answer to my
In addition, I'd like to thank the following individuals for their contributions to the mod:
Code:
- Corail31
- 12foo
Translations:
- Russian: VilagVil
@@ -303,6 +303,11 @@ Gracias tambien a la comunidad de Minecraft que crea mods, la cual siempre tiene
In addition, I'd like to thank the following individuals for their contributions to the mod:
Code:
- Corail31
- 12foo
Translations:
- Russian: VilagVil
@@ -303,6 +303,11 @@ Gracias tambien a la comunidad de Minecraft que crea mods, la cual siempre tiene
In addition, I'd like to thank the following individuals for their contributions to the mod:
Code:
- Corail31
- 12foo
Translations:
- Russian: VilagVil
@@ -214,6 +214,11 @@ Thanks also to the Minecraft modding community, which always has an answer to my
In addition, I'd like to thank the following individuals for their contributions to the mod:
Code:
- Corail31
- 12foo
Translations:
- Russian: VilagVil
+3 -3
View File
@@ -2,14 +2,14 @@
{
"modid" : "ebwizardry",
"name" : "Electroblob's Wizardry",
"version" : "4.1.0",
"version" : "4.1.1",
"url" : "https://minecraft.curseforge.com/projects/electroblobs-wizardry",
"credits" : "Made by Electroblob",
"credits" : "Designed, coded and textured by Electroblob. Code contributed to 1.11 and 1.12 updates by Corail31 and 12foo. Translators: MadWrist (Spanish, Mexican Spanish), VilagVil (Russian).",
"authors" : [
"Electroblob"
],
"description" : "Electroblob's Wizardry adds an rpg-style system of magic spells to Minecraft with the aim of being as playable as possible. No crazy constructs, no perk trees, no complex recipes - simply find spell books, cast spells, and master the arcane!",
"logoFile" : "assets/wizardry/textures/gui/logo.png",
"logoFile" : "assets/ebwizardry/textures/gui/logo.png",
"updateUrl" : "",
"parent" : "",
"screenshots": [