Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 339ec69a72 | |||
| b2cb717aa3 | |||
| cf4a02f37f | |||
| 84304dd7ce | |||
| e3b44eb194 | |||
| 2cbb0a590f | |||
| 6b9c864890 | |||
| c15a0763d5 | |||
| 4a23d88f30 | |||
| 286705c79b | |||
| 3895f5c531 | |||
| c51e0bd218 | |||
| 766570aeb2 | |||
| 4e91b0d19d | |||
| 65f7630546 | |||
| 8cf7572041 | |||
| db057a5ca9 |
+3
-2
@@ -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
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||

|
||||
|
||||
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
@@ -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
|
||||
|
||||
@@ -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": [
|
||||
|
||||
Reference in New Issue
Block a user