Compare commits

...

6 Commits

14 changed files with 197 additions and 9 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
{
"homepage": "https://www.curseforge.com/minecraft/mc-mods/electroblobs-wizardry",
"promos": {
"1.12.2-latest": "4.3.10",
"1.12.2-recommended": "4.3.10"
"1.12.2-latest": "4.3.11",
"1.12.2-recommended": "4.3.11"
}
}
+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.3.10"
version = "4.3.11"
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "ElectroblobsWizardry"
@@ -198,6 +198,13 @@ public final class Settings {
public boolean playerBlockDamage = true;
/** <b>[Server-only]</b> Whether spells cast by dispensers can destroy blocks in the world. */
public boolean dispenserBlockDamage = true;
/** <b>[Server-only]</b> Whether damage should be registered with the old system (wizardry_magic/indirect_wizardry_magic) prefixed damage with the elements like
* necromancy_indirect_wizardry_magic, necromancy_wizardry_magic*/
public boolean damageTypePerElement = false;
/** <b>[Server-only]</b> Whether spell books are consumed when they are bound to a wand.*/
public boolean singleUseSpellBooks = false;
/** <b>[Server-only]</b> Whether to prevent binding the same spell to a wand multiple times*/
public boolean preventBindingSameSpellTwiceToWands = false;
/** <b>[Server-only]</b> Whether to revert to the old wand upgrade system, which only requires tomes of arcana. */
public boolean legacyWandLevelling = false;
/** <b>[Server-only]</b> Whether to tweak the blindness effect to reduce follow distance when used on non-players. */
@@ -625,6 +632,29 @@ public final class Settings {
dispenserBlockDamage = property.getBoolean();
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "damageTypePerElement", false,
"Whether damage should be registered with the old system (wizardry_magic/indirect_wizardry_magic) prefixed damage with the elements like "
+ "necromancy_indirect_wizardry_magic, necromancy_wizardry_magic. This is disabled by default to not break existing modpacks."
+ "The intention of this setting is to allow differentiating various damage types for e.g. the Distinct Damage Descriptions mod");
property.setLanguageKey("config." + Wizardry.MODID + ".damage_type_per_element");
Wizardry.proxy.setToNamedBooleanEntry(property);
damageTypePerElement = property.getBoolean();
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "singleUseSpellBooks", false,
"Whether spell books are consumed when they are bound to a wand.");
property.setLanguageKey("config." + Wizardry.MODID + ".single_use_spell_books");
Wizardry.proxy.setToNamedBooleanEntry(property);
singleUseSpellBooks = property.getBoolean();
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "preventBindingSameSpellTwiceToWands", false,
"Whether to prevent binding the same spell to a wand multiple times");
property.setLanguageKey("config." + Wizardry.MODID + ".prevent_binding_same_spell_twice_to_wands");
Wizardry.proxy.setToNamedBooleanEntry(property);
preventBindingSameSpellTwiceToWands = property.getBoolean();
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "playersMoveEachOther", true,
"Whether to allow players to move other players around using magic.");
property.setLanguageKey("config." + Wizardry.MODID + ".players_move_each_other");
@@ -82,7 +82,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.3.10";
public static final String VERSION = "4.3.11";
/**
* Json file used by Forge's built-in <a href="https://mcforge.readthedocs.io/en/1.12.x/gettingstarted/autoupdate/">update checker</a>.
@@ -93,6 +93,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
private ContainerArcaneWorkbench arcaneWorkbenchContainer;
private GuiButton applyBtn;
private GuiButton clearBtn;
private GuiButton[] sortButtons = new GuiButton[3];
private GuiTextField searchField;
@@ -126,6 +127,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
this.buttonList.clear();
this.buttonList.add(this.applyBtn = new GuiButtonApply(0, this.width / 2 + 64, this.height / 2 + 3));
this.buttonList.add(this.clearBtn = new GuiButtonClear(0, this.width / 2 + 64, this.height / 2 - 16));
this.buttonList.add(sortButtons[0] = new GuiButtonSpellSort(1, this.guiLeft - 44, this.guiTop + 8, ISpellSortable.SortType.TIER, arcaneWorkbenchContainer, this));
this.buttonList.add(sortButtons[1] = new GuiButtonSpellSort(2, this.guiLeft - 31, this.guiTop + 8, ISpellSortable.SortType.ELEMENT, arcaneWorkbenchContainer, this));
this.buttonList.add(sortButtons[2] = new GuiButtonSpellSort(3, this.guiLeft - 18, this.guiTop + 8, ISpellSortable.SortType.ALPHABETICAL, arcaneWorkbenchContainer, this));
@@ -205,6 +207,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
// Show/hide the relevant gui elements
this.applyBtn.enabled = centreSlot.getHasStack();
this.clearBtn.enabled = centreSlot.getHasStack() && centreSlot.getStack().getItem() instanceof IWorkbenchItem && ((IWorkbenchItem) centreSlot.getStack().getItem()).isClearable();
for(GuiButton button : this.sortButtons) button.visible = arcaneWorkbenchContainer.hasBookshelves();
this.searchField.setVisible(arcaneWorkbenchContainer.hasBookshelves());
@@ -444,6 +447,17 @@ public class GuiArcaneWorkbench extends GuiContainer {
animationTimer = 20;
}
if(button == clearBtn){
// Packet building
IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.CLEAR_BUTTON);
WizardryPacketHandler.net.sendToServer(msg);
// Sound
Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(
WizardrySounds.BLOCK_ARCANE_WORKBENCH_SPELLBIND, 0.8f));
// Animation
animationTimer = 20;
}
if(button instanceof GuiButtonSpellSort) this.arcaneWorkbenchContainer.setSortType(((GuiButtonSpellSort)button).sortType);
}
}
@@ -1006,4 +1020,36 @@ public class GuiArcaneWorkbench extends GuiContainer {
}
}
private static class GuiButtonClear extends GuiButton {
public GuiButtonClear(int id, int x, int y){
super(id, x, y, 16, 16, I18n.format("container." + Wizardry.MODID + ":arcane_workbench.clear"));
}
@Override
public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
// Whether the button is highlighted
this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
int k = 72;
int l = 236;
//int colour = 14737632;
if(this.enabled){
if(this.hovered){
k += this.width * 2;
//colour = 16777120;
}
}else{
k += this.width;
//colour = 10526880;
}
DrawingUtils.drawTexturedRect(this.x, this.y, k, l, this.width, this.height, TEXTURE_WIDTH, TEXTURE_HEIGHT);
//this.drawCenteredString(minecraft.fontRenderer, this.displayString, this.x + this.width / 2,
// this.y + (this.height - 8) / 2, colour);
}
}
}
@@ -452,6 +452,24 @@ public class ContainerArcaneWorkbench extends Container implements ISpellSortabl
}
}
/**
* Called (via {@link electroblob.wizardry.packet.PacketControlInput PacketControlInput}) when the clear button in
* the arcane workbench GUI is pressed.
*/
// As of 2.1, for the sake of events and neatness of code, this was moved here from TileEntityArcaneWorkbench.
// As of 4.2, the spell binding/charging/upgrading code was delegated (via IWorkbenchItem) to the items themselves.
public void onClearButtonPressed(EntityPlayer player){
Slot centre = this.getSlot(CENTRE_SLOT);
if(centre.getStack().getItem() instanceof IWorkbenchItem){ // Should always be true, but no harm in checking.
Slot[] spellBooks = this.inventorySlots.subList(0, 8).toArray(new Slot[8]);
((IWorkbenchItem) centre.getStack().getItem()).onClearButtonPressed(player, centre, this.getSlot(CRYSTAL_SLOT), this.getSlot(UPGRADE_SLOT), spellBooks);
}
}
/** Scrolls to the given row number. */
public void scrollTo(int row){
this.scroll = row;
@@ -55,6 +55,26 @@ public interface IWorkbenchItem {
*/
boolean onApplyButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks);
/**
* Called when this item is in the central slot of an arcane workbench and the apply clear is pressed. Items must
* implement this method to define what happens when the apply button is pressed.
* @param player The player that pressed the apply button.
* @param centre The central slot in the arcane workbench. This slot will always contain a stack of the implementing
* item, or in other words, <i>it is guaranteed that</i> {@code this == centre.getStack().getItem()}.
* @param crystals The magic crystal slot of the arcane workbench.
* @param upgrade The upgrade slot of the arcane workbench.
* @param spellBooks An array of the <i>active</i> (visible) spell book slots in the arcane workbench. The length of
* the array will be equal to the value returned by {@link IWorkbenchItem#getSpellSlotCount(ItemStack)}.
* */
default void onClearButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks){};
/**
* Must be overridden in the item class to make the clear button in the Arcane Workbench clickable.
* */
default boolean isClearable() {
return false;
}
/**
* Returns whether the tooltip (dark grey box) should be drawn when this item is in an arcane workbench. Only
* called client-side.
@@ -28,6 +28,7 @@ import net.minecraft.inventory.Slot;
import net.minecraft.item.EnumAction;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.*;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
@@ -45,6 +46,7 @@ import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
@@ -842,8 +844,19 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
Spell spell = Spell.byMetadata(spellBooks[i].getStack().getItemDamage());
// If the wand is powerful enough for the spell, it's not already bound to that slot and it's enabled for wands
if(!(spell.getTier().level > this.tier.level) && spells[i] != spell && spell.isEnabled(SpellProperties.Context.WANDS)){
// Decide if we can bind this multiple times
if (Wizardry.settings.preventBindingSameSpellTwiceToWands && Arrays.stream(spells).anyMatch(s -> s == spell)) {
continue;
}
spells[i] = spell;
changed = true;
// setting to consume books upon use
if (Wizardry.settings.singleUseSpellBooks) {
spellBooks[i].getStack().shrink(1);
}
}
}
}
@@ -881,6 +894,19 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
return changed;
}
@Override
public void onClearButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks){
ItemStack stack = centre.getStack();
if (stack.hasTagCompound() && stack.getTagCompound().hasKey(WandHelper.SPELL_ARRAY_KEY)) {
NBTTagCompound nbt = stack.getTagCompound();
nbt.removeTag(WandHelper.SPELL_ARRAY_KEY);
stack.setTagCompound(nbt);
}
}
@Override
public boolean isClearable() { return true; }
// hitEntity is only called server-side, so we'll have to use events
@SubscribeEvent
public static void onAttackEntityEvent(AttackEntityEvent event){
@@ -51,6 +51,17 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
break;
case CLEAR_BUTTON:
if(!(player.openContainer instanceof ContainerArcaneWorkbench)){
Wizardry.logger.warn("Received a PacketControlInput, but the player that sent it was not " +
"currently using an arcane workbench. This should not happen!");
}else{
((ContainerArcaneWorkbench)player.openContainer).onClearButtonPressed(player);
}
break;
case NEXT_SPELL_KEY:
if(wand.getItem() instanceof ISpellCastingItem){
@@ -133,7 +144,7 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
}
public enum ControlType {
APPLY_BUTTON, NEXT_SPELL_KEY, PREVIOUS_SPELL_KEY, RESURRECT_BUTTON, CANCEL_RESURRECT, POSSESSION_PROJECTILE
APPLY_BUTTON, NEXT_SPELL_KEY, PREVIOUS_SPELL_KEY, RESURRECT_BUTTON, CANCEL_RESURRECT, POSSESSION_PROJECTILE, CLEAR_BUTTON
}
public static class Message implements IMessage {
@@ -201,7 +201,7 @@ public final class AllyDesignationSystem {
// Owned entities inherit their owner's allies
if(allyOf instanceof IEntityOwnable){
Entity owner = ((IEntityOwnable)allyOf).getOwner();
if(owner instanceof EntityLivingBase && isAllied((EntityLivingBase)owner, possibleAlly)) return true;
if(owner instanceof EntityLivingBase && (owner == possibleAlly || isAllied((EntityLivingBase)owner, possibleAlly))) return true;
}
if(allyOf instanceof EntityPlayer && possibleAlly instanceof EntityPlayer
@@ -1,5 +1,7 @@
package electroblob.wizardry.util;
import electroblob.wizardry.Settings;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.living.*;
import net.minecraft.entity.Entity;
import net.minecraft.entity.boss.EntityDragon;
@@ -195,7 +197,7 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage
* @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);
return new MagicDamage(getDirectDamageNameForType(type), caster, type, isRetaliatory);
}
/**
@@ -241,7 +243,15 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage
*/
public static DamageSource causeIndirectMagicDamage(Entity magic, Entity caster, DamageType type,
boolean isRetaliatory){
return new IndirectMagicDamage(INDIRECT_MAGIC_DAMAGE, magic, caster, type, isRetaliatory);
return new IndirectMagicDamage(getIndirectDamageNameForType(type), magic, caster, type, isRetaliatory);
}
public static String getIndirectDamageNameForType(DamageType type) {
return Wizardry.settings.damageTypePerElement ? type.name().toLowerCase() + "_" + INDIRECT_MAGIC_DAMAGE : INDIRECT_MAGIC_DAMAGE;
}
public static String getDirectDamageNameForType(DamageType type) {
return Wizardry.settings.damageTypePerElement ? type.name().toLowerCase() + "_" + DIRECT_MAGIC_DAMAGE : DIRECT_MAGIC_DAMAGE;
}
@Override
@@ -882,6 +882,7 @@ container.ebwizardry\:arcane_workbench.sort_tier=Sort by Tier
container.ebwizardry\:arcane_workbench.sort_element=Sort by Element
container.ebwizardry\:arcane_workbench.sort_alphabetical=Sort Alphabetically
container.ebwizardry\:arcane_workbench.search_tooltip=%1$sSearch Tips\n\ntier=%2$s, %1$st=%2$s: match tiers\n%1$selement=%2$s, %1$se=%2$s: match elements\n%1$stype=%2$s, %1$sp=%2$s: match spell types\n%1$sdiscovered=true/false%2$s, %1$sd=t/f%2$s: include only (un)discovered\n%1$smodid=%2$s, %1$sm=%2$s: match mod IDs\n\nSeparate multiple values with %1$s,%2$s\nSeparate multiple criteria with %1$s;
container.ebwizardry\:arcane_workbench.clear=Clear Spell Slots
container.ebwizardry\:bookshelf=Bookshelf
@@ -1370,6 +1371,7 @@ forfeit.ebwizardry\:bury_self=The ground collapses beneath you!
forfeit.ebwizardry\:spill_inventory=Your items spill themselves everywhere!
forfeit.ebwizardry\:teleport_self=You are instantly teleported somewhere!
forfeit.ebwizardry\:teleport_self_large_distance=You are instantly teleported somewhere far away!
forfeit.ebwizardry\:levitate_self=You begin to float upwards helplessly!
forfeit.ebwizardry\:vex_horde=A horde of vexes materializes around you!
forfeit.ebwizardry\:black_hole=A swirling vortex appears in front of you!
@@ -1446,6 +1448,25 @@ key.ebwizardry.spell_8=Spell Slot 8
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.magic_wizardry_magic=%1$s was killed by %2$s using magic
death.attack.magic_indirect_wizardry_magic=%1$s was killed by %2$s using magic
death.attack.fire_wizardry_magic=%1$s was killed by %2$s using fire magic
death.attack.fire_indirect_wizardry_magic=%1$s was killed by %2$s using fire magic
death.attack.frost_wizardry_magic=%1$s was killed by %2$s using frost magic
death.attack.frost_indirect_wizardry_magic=%1$s was killed by %2$s using frost magic
death.attack.shock_wizardry_magic=%1$s was killed by %2$s using a shock magic
death.attack.shock_indirect_wizardry_magic=%1$s was killed by %2$s using shock magic
death.attack.wither_wizardry_magic=%1$s was killed by %2$s using withering magic
death.attack.wither_indirect_wizardry_magic=%1$s was killed by %2$s withering magic
death.attack.poison_wizardry_magic=%1$s was killed by %2$s using poison magic
death.attack.poison_indirect_wizardry_magic=%1$s was killed by %2$s poison magic
death.attack.force_wizardry_magic=%1$s was killed by %2$s using a magical force
death.attack.force_indirect_wizardry_magic=%1$s was killed by %2$s using magical force
death.attack.blast_wizardry_magic=%1$s was killed by %2$s using a magical blast
death.attack.blast_indirect_wizardry_magic=%1$s was killed by %2$s using magical blast
death.attack.radiant_wizardry_magic=%1$s was killed by %2$s using radiant magic
death.attack.radiant_indirect_wizardry_magic=%1$s was killed by %2$s using radiant magic
soundCategory.ebwizardry_spells=Spells
@@ -1514,6 +1535,12 @@ config.ebwizardry.player_block_damage.true=Yes - kaboom!
config.ebwizardry.player_block_damage.false=No - activate anti-grief (TM)
config.ebwizardry.dispenser_block_damage=Dispenser Block Damage
config.ebwizardry.dispenser_block_damage.tooltip=Whether spells cast by dispensers can destroy blocks in the world. Wizardry makes every attempt to respect protection mods and plugins, but cannot guarantee it will work in all cases for every mod. If you need absolutely watertight anti-grief, disable this setting.
config.ebwizardry.damage_type_per_element=Damage Type Per Element
config.ebwizardry.damage_type_per_element.tooltip=Whether damage should be registered with the old system (wizardry_magic/indirect_wizardry_magic) prefixed damage with the elements like necromancy_indirect_wizardry_magic, necromancy_wizardry_magic. This is disabled by default to not break existing modpacks. The intention of this setting is to allow differentiating various damage types for e.g. the Distinct Damage Descriptions mod
config.ebwizardry.single_use_spell_books=Spell Books Are Consumed By Wands
config.ebwizardry.single_use_spell_books.tooltip=Whether spell books are consumed when they are bound to a wand.
config.ebwizardry.prevent_binding_same_spell_twice_to_wands=Prevent Binding The Same Spell To A Wand Multiple Times
config.ebwizardry.prevent_binding_same_spell_twice_to_wands.tooltip=Whether to prevent binding the same spell to a wand multiple times
config.ebwizardry.telekinetic_disarmament=Telekinetic Disarmament
config.ebwizardry.telekinetic_disarmament.tooltip=Whether to allow players to disarm other players using the telekinesis spell. Disable to prevent stealing of items.
config.ebwizardry.telekinetic_disarmament.true=Yes - let people steal things
Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 33 KiB

+1 -1
View File
@@ -5,7 +5,7 @@
"version" : "4.3.7",
"mcversion" : "1.12.2",
"url" : "https://minecraft.curseforge.com/projects/electroblobs-wizardry",
"credits" : "\nDesigned, coded and textured by Electroblob.\nDiscord Moderators: FavouriteDragon, WinDanesz\nCode contributed by: Corail31, 12foo, Shadows-of-Fire, Tora-B, Avatair, Aeronica, UltraHex, Azim-Palmer, raoulvdberge, rafasoares, xinyuan-liu, SettingDust, Aralu115.\nTranslators: Alsentar (Spanish), MadWrist (Mexican Spanish), VilagVil, kellixon, bigenergy, MugGod2 & DrHesperus (Russian), Hahdrim & Crowller (French), lorrampi (Brazilian Portuguese), ZHENGLOC, dragon-evol, Hokorizero, TUsama & Determancer (Chinese - Simplified), shejery, rewi_wire, 방통 & red1854th (Korean), Trozuu & Olej (Polish), BirdyDragon & Lemopav (German), chesterccj305 (Chinese - Traditional), Bombadil (Hungarian).\nSound Effects: OhhWowProductions, fredzed, deleted_user_3277771, DiscoveryME, OGSoundFX, leosalom, juskiddink",
"credits" : "\nDesigned, coded and textured by Electroblob.\nDiscord Moderators: FavouriteDragon, WinDanesz\nCode contributed by: Corail31, 12foo, Shadows-of-Fire, Tora-B, Avatair, Aeronica, UltraHex, Azim-Palmer, raoulvdberge, rafasoares, xinyuan-liu, SettingDust, Aralu115, WinDanesz, ZettaSword.\nTranslators: Alsentar (Spanish), MadWrist (Mexican Spanish), VilagVil, kellixon, bigenergy, MugGod2 & DrHesperus (Russian), Hahdrim & Crowller (French), lorrampi (Brazilian Portuguese), ZHENGLOC, dragon-evol, Hokorizero, TUsama & Determancer (Chinese - Simplified), shejery, rewi_wire, 방통 & red1854th (Korean), Trozuu & Olej (Polish), BirdyDragon & Lemopav (German), chesterccj305 (Chinese - Traditional), Bombadil (Hungarian).\nSound Effects: OhhWowProductions, fredzed, deleted_user_3277771, DiscoveryME, OGSoundFX, leosalom, juskiddink",
"authorList" : [
"Electroblob"
],