Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bbe4634535 | |||
| e7b8f7681c | |||
| 64168d103d | |||
| 600a321f49 | |||
| e753f4df32 | |||
| cbe7353122 | |||
| de5682a960 | |||
| b451399323 | |||
| e547aa32ca | |||
| 3fe9d762da | |||
| 20b53596e2 |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"homepage": "https://www.curseforge.com/minecraft/mc-mods/electroblobs-wizardry",
|
"homepage": "https://www.curseforge.com/minecraft/mc-mods/electroblobs-wizardry",
|
||||||
"promos": {
|
"promos": {
|
||||||
"1.12.2-latest": "4.3.15",
|
"1.12.2-latest": "4.3.16",
|
||||||
"1.12.2-recommended": "4.3.15"
|
"1.12.2-recommended": "4.3.16"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ apply plugin: org.ajoberstar.grgit.gradle.GrgitPlugin
|
|||||||
apply plugin: 'wtf.gofancy.fancygradle'
|
apply plugin: 'wtf.gofancy.fancygradle'
|
||||||
|
|
||||||
|
|
||||||
version = "4.3.15"
|
version = "4.3.16"
|
||||||
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||||
archivesBaseName = "ElectroblobsWizardry"
|
archivesBaseName = "ElectroblobsWizardry"
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,10 @@ public class CommonProxy {
|
|||||||
|
|
||||||
public void registerRenderers(){}
|
public void registerRenderers(){}
|
||||||
|
|
||||||
|
public void registerItemColorHandlers(){}
|
||||||
|
|
||||||
|
public void registerModelProperties(){}
|
||||||
|
|
||||||
public void initialiseLayers(){}
|
public void initialiseLayers(){}
|
||||||
|
|
||||||
public void initialiseAnimations(){}
|
public void initialiseAnimations(){}
|
||||||
@@ -175,6 +179,8 @@ public class CommonProxy {
|
|||||||
|
|
||||||
public void handleConquerShrinePacket(PacketConquerShrine.Message message){}
|
public void handleConquerShrinePacket(PacketConquerShrine.Message message){}
|
||||||
|
|
||||||
|
public void handleBombExplosionPacket(PacketBombExplosion.Message message){}
|
||||||
|
|
||||||
// SECTION Misc
|
// SECTION Misc
|
||||||
// ===============================================================================================================
|
// ===============================================================================================================
|
||||||
|
|
||||||
|
|||||||
@@ -355,6 +355,8 @@ public final class Settings {
|
|||||||
* velocity-based one.
|
* velocity-based one.
|
||||||
*/
|
*/
|
||||||
public boolean replaceVanillaFallDamage = true;
|
public boolean replaceVanillaFallDamage = true;
|
||||||
|
/** <b>[Synchronised]</b> Whether spell book colors are only shown when the player has the Archivist's Eyeglass equipped. */
|
||||||
|
public boolean spellBookColorsRequireArchivistsEyeglass = false;
|
||||||
/** <b>[Synchronised]</b> Chance of 'misreading' an undiscovered spell and triggering a forfeit instead. */
|
/** <b>[Synchronised]</b> Chance of 'misreading' an undiscovered spell and triggering a forfeit instead. */
|
||||||
public double forfeitChance = 0.2;
|
public double forfeitChance = 0.2;
|
||||||
/** <b>[Synchronised]</b> Progression requirements for upgrading a wand to each tier. */
|
/** <b>[Synchronised]</b> Progression requirements for upgrading a wand to each tier. */
|
||||||
@@ -461,6 +463,8 @@ public final class Settings {
|
|||||||
public static final String DEFAULT_HUD_SKIN_KEY = "default"; // Defined here so it's not in a client-only class.
|
public static final String DEFAULT_HUD_SKIN_KEY = "default"; // Defined here so it's not in a client-only class.
|
||||||
/** <b>[Client-only]</b> The string identifier of the skin used for the spell HUD. */
|
/** <b>[Client-only]</b> The string identifier of the skin used for the spell HUD. */
|
||||||
public String spellHUDSkin = DEFAULT_HUD_SKIN_KEY;
|
public String spellHUDSkin = DEFAULT_HUD_SKIN_KEY;
|
||||||
|
/** <b>[Client-only]</b> Whether to show elemental colors on spell books for discovered spells. */
|
||||||
|
public boolean spellBookColors = true;
|
||||||
|
|
||||||
/** Set of constants for each of the eight positions that the spell HUD can be in. */
|
/** Set of constants for each of the eight positions that the spell HUD can be in. */
|
||||||
public enum GuiPosition {
|
public enum GuiPosition {
|
||||||
@@ -1103,6 +1107,13 @@ public final class Settings {
|
|||||||
replaceVanillaFallDamage = property.getBoolean();
|
replaceVanillaFallDamage = property.getBoolean();
|
||||||
propOrder.add(property.getName());
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
|
property = config.get(TWEAKS_CATEGORY, "spellBookColorsRequireArchivistsEyeglass", false,
|
||||||
|
"If true, spell book colors are only shown when the player has the charm of spell discovery equipped.");
|
||||||
|
property.setLanguageKey("config." + Wizardry.MODID + ".spell_book_colors_require_charm");
|
||||||
|
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||||
|
spellBookColorsRequireArchivistsEyeglass = property.getBoolean();
|
||||||
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
property = config.get(TWEAKS_CATEGORY, "blindnessTweak", true,
|
property = config.get(TWEAKS_CATEGORY, "blindnessTweak", true,
|
||||||
"Whether to tweak the blindness effect to reduce follow distance when used on non-players. This automatically disables itself in favour of Potion Core's implementation if installed.");
|
"Whether to tweak the blindness effect to reduce follow distance when used on non-players. This automatically disables itself in favour of Potion Core's implementation if installed.");
|
||||||
property.setLanguageKey("config." + Wizardry.MODID + ".blindness_tweak");
|
property.setLanguageKey("config." + Wizardry.MODID + ".blindness_tweak");
|
||||||
@@ -1213,7 +1224,7 @@ public final class Settings {
|
|||||||
bookshelfSearchRadius = property.getInt();
|
bookshelfSearchRadius = property.getInt();
|
||||||
propOrder.add(property.getName());
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
property = config.get(TWEAKS_CATEGORY, "currencyItems", new String[]{"gold_ingot 3", "emerald 6"}, "List of registry names of items which wizard trades can use as currency (in the first slot; the second slot is unaffected). Each entry in this list should consist of an item registry name, followed by a single space, then an integer which defines the 'value' of the item. Higher values mean fewer of that currency item are required for a given trade.",
|
property = config.get(TWEAKS_CATEGORY, "currencyItems", new String[]{"gold_ingot 3", "emerald 6"}, "List of registry names of items which wizard trades can use as currency (in the first slot; the second slot is unaffected). Each entry in this list should consist of an item registry name, followed by a single space, then an integer which defines the 'value' of the item. Higher values mean fewer of that currency item are required for a given trade. To specify metadata, use the format 'modid:item:meta value'. For example, 'minecraft:wool:1 5'. If no metadata is given, any metadata will be accepted.",
|
||||||
Pattern.compile("[A-Za-z0-9:_]+ [0-9]+"));
|
Pattern.compile("[A-Za-z0-9:_]+ [0-9]+"));
|
||||||
property.setLanguageKey("config." + Wizardry.MODID + ".currency_items");
|
property.setLanguageKey("config." + Wizardry.MODID + ".currency_items");
|
||||||
propOrder.add(property.getName());
|
propOrder.add(property.getName());
|
||||||
@@ -1487,6 +1498,14 @@ public final class Settings {
|
|||||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||||
showChargeMeter = property.getBoolean();
|
showChargeMeter = property.getBoolean();
|
||||||
propOrder.add(property.getName());
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
|
property = config.get(CLIENT_CATEGORY, "spellBookColors", true, "Whether to show elemental colors on spell books for discovered spells.");
|
||||||
|
property.setLanguageKey("config." + Wizardry.MODID + ".spell_book_colors");
|
||||||
|
property.setRequiresWorldRestart(false);
|
||||||
|
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||||
|
spellBookColors = property.getBoolean();
|
||||||
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
property = config.get(CLIENT_CATEGORY, "loadHandbook", true, "Whether to initialise the in-game handbook. Setting this to false will brick the in-game handbook, but it might help if you have startup crashes.");
|
property = config.get(CLIENT_CATEGORY, "loadHandbook", true, "Whether to initialise the in-game handbook. Setting this to false will brick the in-game handbook, but it might help if you have startup crashes.");
|
||||||
property.setLanguageKey("config." + Wizardry.MODID + ".load_handbook");
|
property.setLanguageKey("config." + Wizardry.MODID + ".load_handbook");
|
||||||
property.setRequiresWorldRestart(false);
|
property.setRequiresWorldRestart(false);
|
||||||
@@ -1817,16 +1836,46 @@ public final class Settings {
|
|||||||
|
|
||||||
string = string.toLowerCase(Locale.ROOT).trim();
|
string = string.toLowerCase(Locale.ROOT).trim();
|
||||||
|
|
||||||
String[] itemArgs = string.split(":");
|
|
||||||
String item;
|
String item;
|
||||||
short meta;
|
short meta;
|
||||||
|
|
||||||
try {
|
int lastColon = string.lastIndexOf(':');
|
||||||
meta = Short.parseShort(itemArgs[itemArgs.length-1]);
|
|
||||||
item = String.join(":", Arrays.copyOfRange(itemArgs, 0, itemArgs.length-1));
|
if (lastColon > -1 && lastColon < string.length() - 1) { // if there is a colon and it's not the last char
|
||||||
}catch(NumberFormatException e){ // If no metadata is specified
|
String metaString = string.substring(lastColon + 1);
|
||||||
meta = OreDictionary.WILDCARD_VALUE;
|
try {
|
||||||
|
short parsedMeta = Short.parseShort(metaString);
|
||||||
|
String itemString = string.substring(0, lastColon);
|
||||||
|
|
||||||
|
// If itemString has no colon, it could be 'item:meta' or 'namespace:numeric_path'.
|
||||||
|
// e.g., 'wool:1' vs 'mod:123'. We want to support 'wool:1' as item 'wool' with meta 1.
|
||||||
|
// We can't reliably distinguish the two cases without knowing all namespaces, so we have to use
|
||||||
|
// a heuristic. The original code favoured the 'item:meta' interpretation, let's stick with that.
|
||||||
|
// The issue was with 'namespace:numeric_path' which this logic now handles.
|
||||||
|
if (itemString.indexOf(':') == -1) {
|
||||||
|
item = itemString;
|
||||||
|
meta = parsedMeta;
|
||||||
|
} else {
|
||||||
|
// Disambiguate things like 'mod:123:4' (item 'mod:123' with meta 4) vs 'mod:item:123' (item 'mod:item' with meta 123)
|
||||||
|
// If the bit before the last colon is a valid resource location, it's probably item:meta
|
||||||
|
try {
|
||||||
|
new ResourceLocation(itemString);
|
||||||
|
item = itemString;
|
||||||
|
meta = parsedMeta;
|
||||||
|
} catch (Exception e) {
|
||||||
|
item = string;
|
||||||
|
meta = OreDictionary.WILDCARD_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
// The part after colon is not a number, so it's part of the name
|
||||||
|
item = string;
|
||||||
|
meta = OreDictionary.WILDCARD_VALUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
item = string;
|
item = string;
|
||||||
|
meta = OreDictionary.WILDCARD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Pair.of(new ResourceLocation(item), meta);
|
return Pair.of(new ResourceLocation(item), meta);
|
||||||
|
|||||||
@@ -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.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.
|
* 1.11.x versions, and so on.
|
||||||
*/
|
*/
|
||||||
public static final String VERSION = "4.3.15";
|
public static final String VERSION = "4.3.16";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Json file used by Forge's built-in <a href="https://mcforge.readthedocs.io/en/1.12.x/gettingstarted/autoupdate/">update checker</a>.
|
* Json file used by Forge's built-in <a href="https://mcforge.readthedocs.io/en/1.12.x/gettingstarted/autoupdate/">update checker</a>.
|
||||||
@@ -198,6 +198,8 @@ public class Wizardry {
|
|||||||
// Client-side stuff (via proxies)
|
// Client-side stuff (via proxies)
|
||||||
proxy.initGuiBits();
|
proxy.initGuiBits();
|
||||||
proxy.registerParticles();
|
proxy.registerParticles();
|
||||||
|
proxy.registerItemColorHandlers();
|
||||||
|
proxy.registerModelProperties();
|
||||||
proxy.registerSoundEventListener();
|
proxy.registerSoundEventListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package electroblob.wizardry.client;
|
package electroblob.wizardry.client;
|
||||||
|
|
||||||
import electroblob.wizardry.CommonProxy;
|
import electroblob.wizardry.CommonProxy;
|
||||||
import electroblob.wizardry.Settings;
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.block.BlockBookshelf;
|
import electroblob.wizardry.block.BlockBookshelf;
|
||||||
import electroblob.wizardry.client.animation.ActionAnimation;
|
import electroblob.wizardry.client.animation.ActionAnimation;
|
||||||
@@ -19,6 +18,8 @@ import electroblob.wizardry.client.model.ModelRobeArmour;
|
|||||||
import electroblob.wizardry.client.model.ModelSageArmour;
|
import electroblob.wizardry.client.model.ModelSageArmour;
|
||||||
import electroblob.wizardry.client.model.ModelWizardArmour;
|
import electroblob.wizardry.client.model.ModelWizardArmour;
|
||||||
import electroblob.wizardry.client.particle.*;
|
import electroblob.wizardry.client.particle.*;
|
||||||
|
import electroblob.wizardry.constants.Element;
|
||||||
|
import electroblob.wizardry.registry.WizardryItems;
|
||||||
import electroblob.wizardry.client.particle.ParticleWizardry.IWizardryParticleFactory;
|
import electroblob.wizardry.client.particle.ParticleWizardry.IWizardryParticleFactory;
|
||||||
import electroblob.wizardry.client.renderer.RenderSpectralGolem;
|
import electroblob.wizardry.client.renderer.RenderSpectralGolem;
|
||||||
import electroblob.wizardry.client.renderer.entity.*;
|
import electroblob.wizardry.client.renderer.entity.*;
|
||||||
@@ -38,6 +39,7 @@ import electroblob.wizardry.entity.projectile.*;
|
|||||||
import electroblob.wizardry.event.SpellCastEvent;
|
import electroblob.wizardry.event.SpellCastEvent;
|
||||||
import electroblob.wizardry.event.SpellCastEvent.Source;
|
import electroblob.wizardry.event.SpellCastEvent.Source;
|
||||||
import electroblob.wizardry.integration.antiqueatlas.WizardryAntiqueAtlasIntegration;
|
import electroblob.wizardry.integration.antiqueatlas.WizardryAntiqueAtlasIntegration;
|
||||||
|
import electroblob.wizardry.item.ItemArtefact;
|
||||||
import electroblob.wizardry.item.ItemScroll;
|
import electroblob.wizardry.item.ItemScroll;
|
||||||
import electroblob.wizardry.item.ItemSpellBook;
|
import electroblob.wizardry.item.ItemSpellBook;
|
||||||
import electroblob.wizardry.item.ItemWand;
|
import electroblob.wizardry.item.ItemWand;
|
||||||
@@ -715,6 +717,65 @@ public class ClientProxy extends CommonProxy {
|
|||||||
}else Wizardry.logger.warn("Received a PacketConquerShrine, but there was no shrine core at the position sent");
|
}else Wizardry.logger.warn("Received a PacketConquerShrine, but there was no shrine core at the position sent");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleBombExplosionPacket(PacketBombExplosion.Message message){
|
||||||
|
|
||||||
|
net.minecraft.world.World world = Minecraft.getMinecraft().world;
|
||||||
|
double x = message.x, y = message.y, z = message.z;
|
||||||
|
float blastMultiplier = message.blastMultiplier;
|
||||||
|
|
||||||
|
switch(message.bombType){
|
||||||
|
|
||||||
|
case PacketBombExplosion.FIREBOMB:
|
||||||
|
ParticleBuilder.create(Type.FLASH).pos(x, y, z).scale(5 * blastMultiplier).clr(1, 0.6f, 0).spawn(world);
|
||||||
|
for(int i = 0; i < 60 * blastMultiplier; i++){
|
||||||
|
ParticleBuilder.create(Type.MAGIC_FIRE, world.rand, x, y, z, 2 * blastMultiplier, false)
|
||||||
|
.time(10 + world.rand.nextInt(4)).scale(2 + world.rand.nextFloat()).spawn(world);
|
||||||
|
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, x, y, z, 2 * blastMultiplier, false)
|
||||||
|
.clr(1.0f, 0.2f + world.rand.nextFloat() * 0.4f, 0.0f).spawn(world);
|
||||||
|
}
|
||||||
|
world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, x, y, z, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PacketBombExplosion.POISON_BOMB:
|
||||||
|
ParticleBuilder.create(Type.FLASH).pos(x, y, z).scale(5 * blastMultiplier)
|
||||||
|
.clr(0.2f + world.rand.nextFloat() * 0.3f, 0.6f, 0.0f).spawn(world);
|
||||||
|
for(int i = 0; i < 60 * blastMultiplier; i++){
|
||||||
|
ParticleBuilder.create(Type.SPARKLE, world.rand, x, y, z, 2 * blastMultiplier, false).time(35)
|
||||||
|
.scale(2).clr(0.2f + world.rand.nextFloat() * 0.3f, 0.6f, 0.0f).spawn(world);
|
||||||
|
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, x, y, z, 2 * blastMultiplier, false)
|
||||||
|
.clr(0.2f + world.rand.nextFloat() * 0.2f, 0.8f, 0.0f).spawn(world);
|
||||||
|
}
|
||||||
|
world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, x, y, z, 0, 0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PacketBombExplosion.SMOKE_BOMB:
|
||||||
|
ParticleBuilder.create(Type.FLASH).pos(x, y, z).scale(5 * blastMultiplier).clr(0, 0, 0).spawn(world);
|
||||||
|
world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, x, y, z, 0, 0, 0);
|
||||||
|
for(int i = 0; i < 60 * blastMultiplier; i++){
|
||||||
|
float brightness = world.rand.nextFloat() * 0.1f + 0.1f;
|
||||||
|
ParticleBuilder.create(Type.CLOUD, world.rand, x, y, z, 2 * blastMultiplier, false)
|
||||||
|
.clr(brightness, brightness, brightness).time(80 + world.rand.nextInt(12)).shaded(true).spawn(world);
|
||||||
|
brightness = world.rand.nextFloat() * 0.3f;
|
||||||
|
ParticleBuilder.create(Type.DARK_MAGIC, world.rand, x, y, z, 2 * blastMultiplier, false)
|
||||||
|
.clr(brightness, brightness, brightness).spawn(world);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PacketBombExplosion.SPARK_BOMB:
|
||||||
|
ParticleBuilder.spawnShockParticles(world, x, y, z);
|
||||||
|
for(int id : message.secondaryTargetIDs){
|
||||||
|
net.minecraft.entity.Entity target = world.getEntityByID(id);
|
||||||
|
if(target instanceof net.minecraft.entity.EntityLivingBase){
|
||||||
|
ParticleBuilder.create(Type.LIGHTNING).pos(x, y, z).target(target).spawn(world);
|
||||||
|
ParticleBuilder.spawnShockParticles(world, target.posX,
|
||||||
|
target.posY + target.height / 2, target.posZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
// ===============================================================================================================
|
// ===============================================================================================================
|
||||||
|
|
||||||
@@ -877,4 +938,51 @@ public class ClientProxy extends CommonProxy {
|
|||||||
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityImbuementAltar.class, new RenderImbuementAltar());
|
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityImbuementAltar.class, new RenderImbuementAltar());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void registerItemColorHandlers() {
|
||||||
|
// Spell book overlay textures are now per-element, so no runtime tinting is needed.
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerModelProperties() {
|
||||||
|
Item spellBook = WizardryItems.spell_book;
|
||||||
|
|
||||||
|
spellBook.addPropertyOverride(new ResourceLocation(Wizardry.MODID, "discovered"), (stack, world, entity) -> {
|
||||||
|
if (!Wizardry.settings.spellBookColors) return 0.0f;
|
||||||
|
|
||||||
|
boolean discovered = shouldDisplayDiscovered(Spell.byMetadata(stack.getMetadata()), stack);
|
||||||
|
|
||||||
|
if(discovered && Wizardry.settings.spellBookColorsRequireArchivistsEyeglass){
|
||||||
|
// Entity can be null so we have to check
|
||||||
|
if(entity instanceof EntityPlayer){
|
||||||
|
return ItemArtefact.isArtefactActive((EntityPlayer)entity, WizardryItems.charm_spell_discovery) ? 1.0f : 0.0f;
|
||||||
|
}
|
||||||
|
// If there's no entity, there's no charm, so no colour
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return discovered ? 1.0f : 0.0f;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Returns ordinal+1 for each element (1=MAGIC through 8=HEALING), or 0 if not yet discovered.
|
||||||
|
// Drives per-element bookmark texture selection via model overrides in spell_book.json.
|
||||||
|
spellBook.addPropertyOverride(new ResourceLocation(Wizardry.MODID, "element"), (stack, world, entity) -> {
|
||||||
|
if (!Wizardry.settings.spellBookColors) return 0.0f;
|
||||||
|
|
||||||
|
Spell spell = Spell.byMetadata(stack.getMetadata());
|
||||||
|
boolean discovered = shouldDisplayDiscovered(spell, stack);
|
||||||
|
|
||||||
|
if(!discovered) return 0.0f;
|
||||||
|
|
||||||
|
if(Wizardry.settings.spellBookColorsRequireArchivistsEyeglass){
|
||||||
|
if(entity instanceof EntityPlayer){
|
||||||
|
if(!ItemArtefact.isArtefactActive((EntityPlayer)entity, WizardryItems.charm_spell_discovery)) return 0.0f;
|
||||||
|
} else {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Element element = spell.getElement();
|
||||||
|
return element == null ? 0.0f : (float)(element.ordinal() + 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package electroblob.wizardry.client;
|
package electroblob.wizardry.client;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.client.renderer.overlay.RenderBlinkEffect;
|
import electroblob.wizardry.client.renderer.overlay.RenderBlinkEffect;
|
||||||
import electroblob.wizardry.data.DispenserCastingData;
|
import electroblob.wizardry.data.DispenserCastingData;
|
||||||
import electroblob.wizardry.data.SpellEmitterData;
|
import electroblob.wizardry.data.SpellEmitterData;
|
||||||
@@ -13,7 +14,6 @@ import electroblob.wizardry.spell.SixthSense;
|
|||||||
import electroblob.wizardry.spell.SlowTime;
|
import electroblob.wizardry.spell.SlowTime;
|
||||||
import electroblob.wizardry.spell.Transience;
|
import electroblob.wizardry.spell.Transience;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.GuiMainMenu;
|
|
||||||
import net.minecraft.client.gui.ScaledResolution;
|
import net.minecraft.client.gui.ScaledResolution;
|
||||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||||
import net.minecraft.client.renderer.BufferBuilder;
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
@@ -31,6 +31,9 @@ import net.minecraftforge.fml.common.Mod;
|
|||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
import net.minecraft.client.resources.I18n;
|
||||||
|
import net.minecraft.util.text.TextFormatting;
|
||||||
|
import net.minecraftforge.event.entity.player.ItemTooltipEvent;
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -196,6 +199,15 @@ public final class WizardryClientEventHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onItemTooltip(ItemTooltipEvent event) {
|
||||||
|
if (event.getItemStack().getItem() == WizardryItems.charm_spell_discovery) {
|
||||||
|
if (Wizardry.settings.spellBookColorsRequireArchivistsEyeglass) {
|
||||||
|
event.getToolTip().add(TextFormatting.GRAY + I18n.format("item.ebwizardry:charm_spell_discovery.desc.color"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders an overlay across the entire screen.
|
* Renders an overlay across the entire screen.
|
||||||
* @param resolution The screen resolution
|
* @param resolution The screen resolution
|
||||||
|
|||||||
@@ -515,12 +515,13 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
|||||||
@Override
|
@Override
|
||||||
protected void keyTyped(char typedChar, int keyCode) throws IOException {
|
protected void keyTyped(char typedChar, int keyCode) throws IOException {
|
||||||
|
|
||||||
if(this.searchNeedsClearing){
|
if(this.searchNeedsClearing){
|
||||||
this.searchNeedsClearing = false;
|
this.searchNeedsClearing = false;
|
||||||
this.searchField.setText("");
|
this.searchField.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.searchField.textboxKeyTyped(typedChar, keyCode)){
|
// Allow exiting the GUI by pressing the inventory button. Does not work if bookshelves are present by default
|
||||||
|
if(this.searchField.getVisible() && this.searchField.textboxKeyTyped(typedChar, keyCode)){
|
||||||
arcaneWorkbenchContainer.setSearchText(searchField.getText().toLowerCase(Locale.ROOT));
|
arcaneWorkbenchContainer.setSearchText(searchField.getText().toLowerCase(Locale.ROOT));
|
||||||
}else{
|
}else{
|
||||||
super.keyTyped(typedChar, keyCode);
|
super.keyTyped(typedChar, keyCode);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import electroblob.wizardry.enchantment.Imbuement;
|
|||||||
import electroblob.wizardry.entity.living.ISummonedCreature;
|
import electroblob.wizardry.entity.living.ISummonedCreature;
|
||||||
import electroblob.wizardry.event.SpellCastEvent;
|
import electroblob.wizardry.event.SpellCastEvent;
|
||||||
import electroblob.wizardry.event.SpellCastEvent.Source;
|
import electroblob.wizardry.event.SpellCastEvent.Source;
|
||||||
import electroblob.wizardry.item.ItemWand;
|
|
||||||
import electroblob.wizardry.packet.PacketCastContinuousSpell;
|
import electroblob.wizardry.packet.PacketCastContinuousSpell;
|
||||||
import electroblob.wizardry.packet.PacketPlayerSync;
|
import electroblob.wizardry.packet.PacketPlayerSync;
|
||||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||||
@@ -356,20 +355,20 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
|
|||||||
|
|
||||||
// For each item in the player's inventory
|
// For each item in the player's inventory
|
||||||
for(ItemStack stack : player.inventory.mainInventory){
|
for(ItemStack stack : player.inventory.mainInventory){
|
||||||
updateImbutedItem(stack, activeImbuements);
|
updateImbuedItem(stack, activeImbuements);
|
||||||
}
|
}
|
||||||
for(ItemStack stack : player.inventory.armorInventory){
|
for(ItemStack stack : player.inventory.armorInventory){
|
||||||
updateImbutedItem(stack, activeImbuements);
|
updateImbuedItem(stack, activeImbuements);
|
||||||
}
|
}
|
||||||
for(ItemStack stack : player.inventory.offHandInventory){
|
for(ItemStack stack : player.inventory.offHandInventory){
|
||||||
updateImbutedItem(stack, activeImbuements);
|
updateImbuedItem(stack, activeImbuements);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removes all imbuements from the map that are no longer active
|
// Removes all imbuements from the map that are no longer active
|
||||||
this.imbuementDurations.keySet().retainAll(activeImbuements);
|
this.imbuementDurations.keySet().retainAll(activeImbuements);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateImbutedItem(ItemStack stack, Set<Imbuement> activeImbuements){
|
private void updateImbuedItem(ItemStack stack, Set<Imbuement> activeImbuements){
|
||||||
|
|
||||||
if(stack.isItemEnchanted()){
|
if(stack.isItemEnchanted()){
|
||||||
|
|
||||||
@@ -466,7 +465,7 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
|
|||||||
|
|
||||||
if(this.castCommandSpell != null && this.castCommandSpell.isContinuous){
|
if(this.castCommandSpell != null && this.castCommandSpell.isContinuous){
|
||||||
|
|
||||||
if(castCommandTick >= castCommandDuration){
|
if(castCommandTick > castCommandDuration){
|
||||||
this.stopCastingContinuousSpell();
|
this.stopCastingContinuousSpell();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
package electroblob.wizardry.entity.projectile;
|
package electroblob.wizardry.entity.projectile;
|
||||||
|
|
||||||
|
import electroblob.wizardry.packet.PacketBombExplosion;
|
||||||
|
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
import electroblob.wizardry.util.EntityUtils;
|
import electroblob.wizardry.util.EntityUtils;
|
||||||
import electroblob.wizardry.util.MagicDamage;
|
import electroblob.wizardry.util.MagicDamage;
|
||||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||||
import electroblob.wizardry.util.ParticleBuilder;
|
|
||||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.util.EnumParticleTypes;
|
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -30,39 +30,26 @@ public class EntityFirebomb extends EntityBomb {
|
|||||||
@Override
|
@Override
|
||||||
protected void onImpact(RayTraceResult rayTrace){
|
protected void onImpact(RayTraceResult rayTrace){
|
||||||
|
|
||||||
Entity entityHit = rayTrace.entityHit;
|
if(!this.world.isRemote){
|
||||||
|
|
||||||
if(entityHit != null){
|
Entity entityHit = rayTrace.entityHit;
|
||||||
// This is if the firebomb gets a direct hit
|
|
||||||
float damage = Spells.firebomb.getProperty(Spell.DIRECT_DAMAGE).floatValue() * damageMultiplier;
|
|
||||||
|
|
||||||
entityHit.attackEntityFrom(
|
if(entityHit != null){
|
||||||
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.FIRE).setProjectile(),
|
// This is if the firebomb gets a direct hit
|
||||||
damage);
|
float damage = Spells.firebomb.getProperty(Spell.DIRECT_DAMAGE).floatValue() * damageMultiplier;
|
||||||
|
|
||||||
if(!MagicDamage.isEntityImmune(DamageType.FIRE, entityHit))
|
entityHit.attackEntityFrom(
|
||||||
entityHit.setFire(Spells.firebomb.getProperty(Spell.BURN_DURATION).intValue());
|
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.FIRE).setProjectile(),
|
||||||
}
|
damage);
|
||||||
|
|
||||||
// Particle effect
|
if(!MagicDamage.isEntityImmune(DamageType.FIRE, entityHit))
|
||||||
if(world.isRemote){
|
entityHit.setFire(Spells.firebomb.getProperty(Spell.BURN_DURATION).intValue());
|
||||||
|
|
||||||
ParticleBuilder.create(Type.FLASH).pos(this.getPositionVector()).scale(5 * blastMultiplier).clr(1, 0.6f, 0)
|
|
||||||
.spawn(world);
|
|
||||||
|
|
||||||
for(int i = 0; i < 60 * blastMultiplier; i++){
|
|
||||||
|
|
||||||
ParticleBuilder.create(Type.MAGIC_FIRE, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
|
||||||
.time(10 + rand.nextInt(4)).scale(2 + rand.nextFloat()).spawn(world);
|
|
||||||
|
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
|
||||||
.clr(1.0f, 0.2f + rand.nextFloat() * 0.4f, 0.0f).spawn(world);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
|
// Notify clients to play the explosion effect
|
||||||
}
|
WizardryPacketHandler.net.sendToAllAround(
|
||||||
|
new PacketBombExplosion.Message(PacketBombExplosion.FIREBOMB, posX, posY, posZ, blastMultiplier),
|
||||||
if(!this.world.isRemote){
|
new NetworkRegistry.TargetPoint(world.provider.getDimension(), posX, posY, posZ, 64));
|
||||||
|
|
||||||
this.playSound(WizardrySounds.ENTITY_FIREBOMB_SMASH, 1.5F, rand.nextFloat() * 0.4F + 0.6F);
|
this.playSound(WizardrySounds.ENTITY_FIREBOMB_SMASH, 1.5F, rand.nextFloat() * 0.4F + 0.6F);
|
||||||
this.playSound(WizardrySounds.ENTITY_FIREBOMB_FIRE, 1, 1);
|
this.playSound(WizardrySounds.ENTITY_FIREBOMB_FIRE, 1, 1);
|
||||||
@@ -82,9 +69,9 @@ public class EntityFirebomb extends EntityBomb {
|
|||||||
target.setFire(Spells.firebomb.getProperty(Spell.BURN_DURATION).intValue());
|
target.setFire(Spells.firebomb.getProperty(Spell.BURN_DURATION).intValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setDead();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setDead();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
package electroblob.wizardry.entity.projectile;
|
package electroblob.wizardry.entity.projectile;
|
||||||
|
|
||||||
|
import electroblob.wizardry.packet.PacketBombExplosion;
|
||||||
|
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
import electroblob.wizardry.util.EntityUtils;
|
import electroblob.wizardry.util.EntityUtils;
|
||||||
import electroblob.wizardry.util.MagicDamage;
|
import electroblob.wizardry.util.MagicDamage;
|
||||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||||
import electroblob.wizardry.util.ParticleBuilder;
|
|
||||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.init.MobEffects;
|
import net.minecraft.init.MobEffects;
|
||||||
import net.minecraft.potion.PotionEffect;
|
import net.minecraft.potion.PotionEffect;
|
||||||
import net.minecraft.util.EnumParticleTypes;
|
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -32,43 +32,29 @@ public class EntityPoisonBomb extends EntityBomb {
|
|||||||
@Override
|
@Override
|
||||||
protected void onImpact(RayTraceResult rayTrace){
|
protected void onImpact(RayTraceResult rayTrace){
|
||||||
|
|
||||||
Entity entityHit = rayTrace.entityHit;
|
|
||||||
|
|
||||||
if(entityHit != null){
|
|
||||||
// This is if the poison bomb gets a direct hit
|
|
||||||
float damage = Spells.poison_bomb.getProperty(Spell.DIRECT_DAMAGE).floatValue() * damageMultiplier;
|
|
||||||
|
|
||||||
entityHit.attackEntityFrom(
|
|
||||||
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.POISON).setProjectile(),
|
|
||||||
damage);
|
|
||||||
|
|
||||||
if(entityHit instanceof EntityLivingBase && !MagicDamage.isEntityImmune(DamageType.POISON, entityHit))
|
|
||||||
((EntityLivingBase)entityHit).addPotionEffect(new PotionEffect(MobEffects.POISON,
|
|
||||||
Spells.poison_bomb.getProperty(Spell.DIRECT_EFFECT_DURATION).intValue(),
|
|
||||||
Spells.poison_bomb.getProperty(Spell.DIRECT_EFFECT_STRENGTH).intValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Particle effect
|
|
||||||
if(world.isRemote){
|
|
||||||
|
|
||||||
ParticleBuilder.create(Type.FLASH).pos(this.getPositionVector()).scale(5 * blastMultiplier)
|
|
||||||
.clr(0.2f + rand.nextFloat() * 0.3f, 0.6f, 0.0f).spawn(world);
|
|
||||||
|
|
||||||
for(int i = 0; i < 60 * blastMultiplier; i++){
|
|
||||||
|
|
||||||
ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 2*blastMultiplier, false).time(35)
|
|
||||||
.scale(2).clr(0.2f + rand.nextFloat() * 0.3f, 0.6f, 0.0f).spawn(world);
|
|
||||||
|
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
|
||||||
.clr(0.2f + rand.nextFloat() * 0.2f, 0.8f, 0.0f).spawn(world);
|
|
||||||
}
|
|
||||||
// Spawning this after the other particles fixes the rendering colour bug. It's a bit of a cheat, but it
|
|
||||||
// works pretty well.
|
|
||||||
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!this.world.isRemote){
|
if(!this.world.isRemote){
|
||||||
|
|
||||||
|
Entity entityHit = rayTrace.entityHit;
|
||||||
|
|
||||||
|
if(entityHit != null){
|
||||||
|
// This is if the poison bomb gets a direct hit
|
||||||
|
float damage = Spells.poison_bomb.getProperty(Spell.DIRECT_DAMAGE).floatValue() * damageMultiplier;
|
||||||
|
|
||||||
|
entityHit.attackEntityFrom(
|
||||||
|
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.POISON).setProjectile(),
|
||||||
|
damage);
|
||||||
|
|
||||||
|
if(entityHit instanceof EntityLivingBase && !MagicDamage.isEntityImmune(DamageType.POISON, entityHit))
|
||||||
|
((EntityLivingBase)entityHit).addPotionEffect(new PotionEffect(MobEffects.POISON,
|
||||||
|
Spells.poison_bomb.getProperty(Spell.DIRECT_EFFECT_DURATION).intValue(),
|
||||||
|
Spells.poison_bomb.getProperty(Spell.DIRECT_EFFECT_STRENGTH).intValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify clients to play the explosion effect
|
||||||
|
WizardryPacketHandler.net.sendToAllAround(
|
||||||
|
new PacketBombExplosion.Message(PacketBombExplosion.POISON_BOMB, posX, posY, posZ, blastMultiplier),
|
||||||
|
new NetworkRegistry.TargetPoint(world.provider.getDimension(), posX, posY, posZ, 64));
|
||||||
|
|
||||||
this.playSound(WizardrySounds.ENTITY_POISON_BOMB_SMASH, 1.5F, rand.nextFloat() * 0.4F + 0.6F);
|
this.playSound(WizardrySounds.ENTITY_POISON_BOMB_SMASH, 1.5F, rand.nextFloat() * 0.4F + 0.6F);
|
||||||
this.playSound(WizardrySounds.ENTITY_POISON_BOMB_POISON, 1.2F, 1.0f);
|
this.playSound(WizardrySounds.ENTITY_POISON_BOMB_POISON, 1.2F, 1.0f);
|
||||||
|
|
||||||
@@ -88,8 +74,8 @@ public class EntityPoisonBomb extends EntityBomb {
|
|||||||
Spells.poison_bomb.getProperty(Spell.SPLASH_EFFECT_STRENGTH).intValue()));
|
Spells.poison_bomb.getProperty(Spell.SPLASH_EFFECT_STRENGTH).intValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setDead();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setDead();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
package electroblob.wizardry.entity.projectile;
|
package electroblob.wizardry.entity.projectile;
|
||||||
|
|
||||||
|
import electroblob.wizardry.packet.PacketBombExplosion;
|
||||||
|
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
import electroblob.wizardry.util.EntityUtils;
|
import electroblob.wizardry.util.EntityUtils;
|
||||||
import electroblob.wizardry.util.ParticleBuilder;
|
|
||||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.init.MobEffects;
|
import net.minecraft.init.MobEffects;
|
||||||
import net.minecraft.potion.PotionEffect;
|
import net.minecraft.potion.PotionEffect;
|
||||||
import net.minecraft.util.EnumParticleTypes;
|
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -29,27 +29,13 @@ public class EntitySmokeBomb extends EntityBomb {
|
|||||||
@Override
|
@Override
|
||||||
protected void onImpact(RayTraceResult rayTrace){
|
protected void onImpact(RayTraceResult rayTrace){
|
||||||
|
|
||||||
// Particle effect
|
|
||||||
if(world.isRemote){
|
|
||||||
|
|
||||||
ParticleBuilder.create(Type.FLASH).pos(this.getPositionVector()).scale(5 * blastMultiplier).clr(0, 0, 0).spawn(world);
|
|
||||||
|
|
||||||
this.world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, this.posX, this.posY, this.posZ, 0, 0, 0);
|
|
||||||
|
|
||||||
for(int i = 0; i < 60 * blastMultiplier; i++){
|
|
||||||
|
|
||||||
float brightness = rand.nextFloat() * 0.1f + 0.1f;
|
|
||||||
ParticleBuilder.create(Type.CLOUD, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
|
||||||
.clr(brightness, brightness, brightness).time(80 + this.rand.nextInt(12)).shaded(true).spawn(world);
|
|
||||||
|
|
||||||
brightness = rand.nextFloat() * 0.3f;
|
|
||||||
ParticleBuilder.create(Type.DARK_MAGIC, rand, posX, posY, posZ, 2*blastMultiplier, false)
|
|
||||||
.clr(brightness, brightness, brightness).spawn(world);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!this.world.isRemote){
|
if(!this.world.isRemote){
|
||||||
|
|
||||||
|
// Notify clients to play the explosion effect
|
||||||
|
WizardryPacketHandler.net.sendToAllAround(
|
||||||
|
new PacketBombExplosion.Message(PacketBombExplosion.SMOKE_BOMB, posX, posY, posZ, blastMultiplier),
|
||||||
|
new NetworkRegistry.TargetPoint(world.provider.getDimension(), posX, posY, posZ, 64));
|
||||||
|
|
||||||
this.playSound(WizardrySounds.ENTITY_SMOKE_BOMB_SMASH, 1.5F, rand.nextFloat() * 0.4F + 0.6F);
|
this.playSound(WizardrySounds.ENTITY_SMOKE_BOMB_SMASH, 1.5F, rand.nextFloat() * 0.4F + 0.6F);
|
||||||
this.playSound(WizardrySounds.ENTITY_SMOKE_BOMB_SMOKE, 1.2F, 1.0f);
|
this.playSound(WizardrySounds.ENTITY_SMOKE_BOMB_SMOKE, 1.2F, 1.0f);
|
||||||
|
|
||||||
@@ -65,8 +51,8 @@ public class EntitySmokeBomb extends EntityBomb {
|
|||||||
target.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, duration, 0));
|
target.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, duration, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setDead();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setDead();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package electroblob.wizardry.entity.projectile;
|
package electroblob.wizardry.entity.projectile;
|
||||||
|
|
||||||
|
import electroblob.wizardry.packet.PacketBombExplosion;
|
||||||
|
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
@@ -13,7 +15,9 @@ import net.minecraft.entity.EntityLivingBase;
|
|||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class EntitySparkBomb extends EntityBomb {
|
public class EntitySparkBomb extends EntityBomb {
|
||||||
@@ -32,46 +36,36 @@ public class EntitySparkBomb extends EntityBomb {
|
|||||||
@Override
|
@Override
|
||||||
protected void onImpact(RayTraceResult rayTrace){
|
protected void onImpact(RayTraceResult rayTrace){
|
||||||
|
|
||||||
this.playSound(WizardrySounds.ENTITY_SPARK_BOMB_HIT_BLOCK, 0.5f, 0.5f);
|
if(!this.world.isRemote){
|
||||||
|
|
||||||
Entity entityHit = rayTrace.entityHit;
|
Entity entityHit = rayTrace.entityHit;
|
||||||
|
|
||||||
if(entityHit != null){
|
if(entityHit != null){
|
||||||
// This is if the spark bomb gets a direct hit
|
// This is if the spark bomb gets a direct hit
|
||||||
float damage = Spells.spark_bomb.getProperty(Spell.DIRECT_DAMAGE).floatValue() * damageMultiplier;
|
float damage = Spells.spark_bomb.getProperty(Spell.DIRECT_DAMAGE).floatValue() * damageMultiplier;
|
||||||
|
|
||||||
this.playSound(WizardrySounds.ENTITY_SPARK_BOMB_HIT, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F));
|
this.playSound(WizardrySounds.ENTITY_SPARK_BOMB_HIT, 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F));
|
||||||
|
|
||||||
entityHit.attackEntityFrom(
|
entityHit.attackEntityFrom(
|
||||||
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK).setProjectile(),
|
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK).setProjectile(),
|
||||||
damage);
|
damage);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
double seekerRange = Spells.spark_bomb.getProperty(Spell.EFFECT_RADIUS).doubleValue() * blastMultiplier;
|
||||||
|
|
||||||
// Particle effect
|
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(seekerRange, this.posX, this.posY,
|
||||||
if(world.isRemote){
|
this.posZ, this.world);
|
||||||
ParticleBuilder.spawnShockParticles(world, posX, posY + height/2, posZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
double seekerRange = Spells.spark_bomb.getProperty(Spell.EFFECT_RADIUS).doubleValue() * blastMultiplier;
|
List<Integer> secondaryTargetIDs = new ArrayList<>();
|
||||||
|
|
||||||
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(seekerRange, this.posX, this.posY,
|
for(int i = 0; i < Math.min(targets.size(), Spells.spark_bomb.getProperty(SECONDARY_MAX_TARGETS).intValue()); i++){
|
||||||
this.posZ, this.world);
|
|
||||||
|
|
||||||
for(int i = 0; i < Math.min(targets.size(), Spells.spark_bomb.getProperty(SECONDARY_MAX_TARGETS).intValue()); i++){
|
boolean flag = targets.get(i) != entityHit && targets.get(i) != this.getThrower()
|
||||||
|
&& !(targets.get(i) instanceof EntityPlayer
|
||||||
|
&& ((EntityPlayer)targets.get(i)).isCreative());
|
||||||
|
|
||||||
boolean flag = targets.get(i) != entityHit && targets.get(i) != this.getThrower()
|
if(flag){
|
||||||
&& !(targets.get(i) instanceof EntityPlayer
|
EntityLivingBase target = targets.get(i);
|
||||||
&& ((EntityPlayer)targets.get(i)).isCreative());
|
|
||||||
|
|
||||||
// Detects (client side) if target is the thrower, to stop particles being spawned around them.
|
|
||||||
//if(flag && world.isRemote && targets.get(i).getEntityId() == this.playerID) flag = false;
|
|
||||||
|
|
||||||
if(flag){
|
|
||||||
|
|
||||||
EntityLivingBase target = targets.get(i);
|
|
||||||
|
|
||||||
if(!this.world.isRemote){
|
|
||||||
|
|
||||||
target.playSound(WizardrySounds.ENTITY_SPARK_BOMB_CHAIN, 1.0F, rand.nextFloat() * 0.4F + 1.5F);
|
target.playSound(WizardrySounds.ENTITY_SPARK_BOMB_CHAIN, 1.0F, rand.nextFloat() * 0.4F + 1.5F);
|
||||||
|
|
||||||
@@ -79,11 +73,18 @@ public class EntitySparkBomb extends EntityBomb {
|
|||||||
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK),
|
MagicDamage.causeIndirectMagicDamage(this, this.getThrower(), DamageType.SHOCK),
|
||||||
Spells.spark_bomb.getProperty(Spell.SPLASH_DAMAGE).floatValue() * damageMultiplier);
|
Spells.spark_bomb.getProperty(Spell.SPLASH_DAMAGE).floatValue() * damageMultiplier);
|
||||||
|
|
||||||
}else{
|
secondaryTargetIDs.add(target.getEntityId());
|
||||||
ParticleBuilder.create(Type.LIGHTNING).pos(this.getPositionVector()).target(target).spawn(world);
|
|
||||||
ParticleBuilder.spawnShockParticles(world, target.posX, target.posY + target.height/2, target.posZ);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Notify clients to play the explosion effect, including lightning arcs to secondary targets
|
||||||
|
int[] idArray = secondaryTargetIDs.stream().mapToInt(Integer::intValue).toArray();
|
||||||
|
WizardryPacketHandler.net.sendToAllAround(
|
||||||
|
new PacketBombExplosion.Message(PacketBombExplosion.SPARK_BOMB, posX, posY + height / 2, posZ,
|
||||||
|
blastMultiplier, idArray),
|
||||||
|
new NetworkRegistry.TargetPoint(world.provider.getDimension(), posX, posY, posZ, 64));
|
||||||
|
|
||||||
|
this.playSound(WizardrySounds.ENTITY_SPARK_BOMB_HIT_BLOCK, 0.5f, 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setDead();
|
this.setDead();
|
||||||
|
|||||||
@@ -160,12 +160,21 @@ public class ItemScroll extends Item implements ISpellCastingItem, IWorkbenchIte
|
|||||||
|
|
||||||
Spell spell = Spell.byMetadata(stack.getItemDamage());
|
Spell spell = Spell.byMetadata(stack.getItemDamage());
|
||||||
// By default, scrolls have no modifiers - but with the event system, they could be added.
|
// By default, scrolls have no modifiers - but with the event system, they could be added.
|
||||||
SpellModifiers modifiers = new SpellModifiers();
|
|
||||||
|
SpellModifiers modifiers;
|
||||||
|
|
||||||
|
if(WizardData.get(player) != null){
|
||||||
|
modifiers = WizardData.get(player).itemCastingModifiers;
|
||||||
|
}else{
|
||||||
|
modifiers = new SpellModifiers();
|
||||||
|
}
|
||||||
|
|
||||||
int castingTick = stack.getMaxItemUseDuration() - count;
|
int castingTick = stack.getMaxItemUseDuration() - count;
|
||||||
|
|
||||||
// Continuous spells (these must check if they can be cast each tick since the mana changes)
|
// Continuous spells (these must check if they can be cast each tick since the mana changes)
|
||||||
// In theory the spell is always continuous here but just in case it isn't...
|
// In theory the spell is always continuous here but just in case it isn't...
|
||||||
if(spell.isContinuous && canCast(stack, spell, player, player.getActiveHand(), castingTick, modifiers)){
|
// Do not check canCast() on tick 0 as it is already done in onItemRightClick() and would duplicate modifiers
|
||||||
|
if(spell.isContinuous && (castingTick == 0 || canCast(stack, spell, player, player.getActiveHand(), castingTick, modifiers))){
|
||||||
cast(stack, spell, player, player.getActiveHand(), castingTick, modifiers);
|
cast(stack, spell, player, player.getActiveHand(), castingTick, modifiers);
|
||||||
}else{
|
}else{
|
||||||
// Scrolls normally work on the max use duration so this isn't ever reached by wizardry, but if the
|
// Scrolls normally work on the max use duration so this isn't ever reached by wizardry, but if the
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ public abstract class Forfeit {
|
|||||||
|
|
||||||
public Forfeit(ResourceLocation name){
|
public Forfeit(ResourceLocation name){
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.sound = WizardrySounds.createSound("forfeit." + name.getPath());
|
this.sound = WizardrySounds.createSound(name.getNamespace(), "forfeit." + name.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void apply(World world, EntityPlayer player);
|
public abstract void apply(World world, EntityPlayer player);
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
package electroblob.wizardry.packet;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <b>[Server -> Client]</b> This packet is sent when a bomb entity impacts something. It is used to guarantee that the
|
||||||
|
* client always sees the explosion effect, even in singleplayer where the server may remove the entity before the
|
||||||
|
* client's own simulation can call {@code onImpact()}.
|
||||||
|
*/
|
||||||
|
public class PacketBombExplosion implements IMessageHandler<PacketBombExplosion.Message, IMessage> {
|
||||||
|
|
||||||
|
/** Bomb type constants, matching the order bombs are handled in {@link electroblob.wizardry.CommonProxy}. */
|
||||||
|
public static final int FIREBOMB = 0;
|
||||||
|
public static final int POISON_BOMB = 1;
|
||||||
|
public static final int SMOKE_BOMB = 2;
|
||||||
|
public static final int SPARK_BOMB = 3;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IMessage onMessage(Message message, MessageContext ctx){
|
||||||
|
if(ctx.side.isClient()){
|
||||||
|
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(
|
||||||
|
() -> Wizardry.proxy.handleBombExplosionPacket(message));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Message implements IMessage {
|
||||||
|
|
||||||
|
/** One of the bomb type constants defined in {@link PacketBombExplosion}. */
|
||||||
|
public int bombType;
|
||||||
|
public double x, y, z;
|
||||||
|
public float blastMultiplier;
|
||||||
|
/** Entity IDs of secondary targets struck by the spark bomb chain. Empty for other bomb types. */
|
||||||
|
public int[] secondaryTargetIDs;
|
||||||
|
|
||||||
|
// Required no-arg constructor
|
||||||
|
public Message(){}
|
||||||
|
|
||||||
|
public Message(int bombType, double x, double y, double z, float blastMultiplier){
|
||||||
|
this(bombType, x, y, z, blastMultiplier, new int[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Message(int bombType, double x, double y, double z, float blastMultiplier, int[] secondaryTargetIDs){
|
||||||
|
this.bombType = bombType;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.blastMultiplier = blastMultiplier;
|
||||||
|
this.secondaryTargetIDs = secondaryTargetIDs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fromBytes(ByteBuf buf){
|
||||||
|
bombType = buf.readInt();
|
||||||
|
x = buf.readDouble();
|
||||||
|
y = buf.readDouble();
|
||||||
|
z = buf.readDouble();
|
||||||
|
blastMultiplier = buf.readFloat();
|
||||||
|
int count = buf.readInt();
|
||||||
|
secondaryTargetIDs = new int[count];
|
||||||
|
for(int i = 0; i < count; i++) secondaryTargetIDs[i] = buf.readInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toBytes(ByteBuf buf){
|
||||||
|
buf.writeInt(bombType);
|
||||||
|
buf.writeDouble(x);
|
||||||
|
buf.writeDouble(y);
|
||||||
|
buf.writeDouble(z);
|
||||||
|
buf.writeFloat(blastMultiplier);
|
||||||
|
buf.writeInt(secondaryTargetIDs.length);
|
||||||
|
for(int id : secondaryTargetIDs) buf.writeInt(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,6 +35,7 @@ public class WizardryPacketHandler {
|
|||||||
registerMessage(PacketSpellQuickAccess.class, PacketSpellQuickAccess.Message.class);
|
registerMessage(PacketSpellQuickAccess.class, PacketSpellQuickAccess.Message.class);
|
||||||
registerMessage(PacketRequestDonationPerks.class, PacketRequestDonationPerks.Message.class);
|
registerMessage(PacketRequestDonationPerks.class, PacketRequestDonationPerks.Message.class);
|
||||||
registerMessage(PacketSyncDonationPerks.class, PacketSyncDonationPerks.Message.class);
|
registerMessage(PacketSyncDonationPerks.class, PacketSyncDonationPerks.Message.class);
|
||||||
|
registerMessage(PacketBombExplosion.class, PacketBombExplosion.Message.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int nextPacketId = 0;
|
private static int nextPacketId = 0;
|
||||||
|
|||||||
@@ -907,7 +907,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
|||||||
* its JSON file using a resource pack. If called with no arguments, defaults to any context, i.e. only returns
|
* its JSON file using a resource pack. If called with no arguments, defaults to any context, i.e. only returns
|
||||||
* false if the spell is completely disabled in all contexts. */
|
* false if the spell is completely disabled in all contexts. */
|
||||||
public final boolean isEnabled(SpellProperties.Context... contexts){
|
public final boolean isEnabled(SpellProperties.Context... contexts){
|
||||||
return enabled && (contexts.length == 0 || properties.isEnabled(contexts));
|
return enabled && (contexts.length == 0 || (arePropertiesInitialised() && properties.isEnabled(contexts)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets whether the spell is enabled or not. */
|
/** Sets whether the spell is enabled or not. */
|
||||||
|
|||||||
@@ -235,12 +235,11 @@ public class TileEntityImbuementAltar extends TileEntity implements ITickable {
|
|||||||
*/
|
*/
|
||||||
public static ItemStack getImbuementResult(ItemStack input, Element[] receptacleElements, boolean fullLootGen, World world, EntityPlayer lastUser){
|
public static ItemStack getImbuementResult(ItemStack input, Element[] receptacleElements, boolean fullLootGen, World world, EntityPlayer lastUser){
|
||||||
|
|
||||||
ItemStack eventResult = ItemStack.EMPTY;
|
ImbuementActivateEvent event = new ImbuementActivateEvent(input, receptacleElements, world, lastUser, ItemStack.EMPTY);
|
||||||
|
|
||||||
if (world != null && MinecraftForge.EVENT_BUS.post(new ImbuementActivateEvent(input, receptacleElements, world, lastUser, eventResult))) {
|
if (world != null && MinecraftForge.EVENT_BUS.post(event)) {
|
||||||
// return the stack if something changes the result from an empty stack.
|
// Event was cancelled; return whatever result the handler set (may be empty to suppress all recipes).
|
||||||
//noinspection ConstantConditions
|
return event.result;
|
||||||
if (eventResult != ItemStack.EMPTY) return eventResult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(input.getItem() instanceof ItemWizardArmour && ((ItemWizardArmour)input.getItem()).element == null){
|
if(input.getItem() instanceof ItemWizardArmour && ((ItemWizardArmour)input.getItem()).element == null){
|
||||||
|
|||||||
@@ -117,6 +117,9 @@ public final class AllyDesignationSystem {
|
|||||||
// Always return true if the attacker is null - this must be after the target null check!
|
// Always return true if the attacker is null - this must be after the target null check!
|
||||||
if(attacker == null) return true;
|
if(attacker == null) return true;
|
||||||
|
|
||||||
|
// Teammates are allies
|
||||||
|
if(attacker.isOnSameTeam(target)) return false;
|
||||||
|
|
||||||
// Tests whether the target is the attacker
|
// Tests whether the target is the attacker
|
||||||
if(target == attacker) return false;
|
if(target == attacker) return false;
|
||||||
|
|
||||||
@@ -220,6 +223,10 @@ public final class AllyDesignationSystem {
|
|||||||
if(allyOf instanceof EntityPlayer && isOwnerAlly((EntityPlayer)allyOf, pet)) return true;
|
if(allyOf instanceof EntityPlayer && isOwnerAlly((EntityPlayer)allyOf, pet)) return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(possibleAlly.isOnSameTeam(allyOf)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if the possibleAlly is mind controlled by the allyOf entity
|
// Check if the possibleAlly is mind controlled by the allyOf entity
|
||||||
if(possibleAlly instanceof EntityLiving && possibleAlly.isPotionActive(WizardryPotions.mind_control)){
|
if(possibleAlly instanceof EntityLiving && possibleAlly.isPotionActive(WizardryPotions.mind_control)){
|
||||||
NBTTagCompound entityNBT = possibleAlly.getEntityData();
|
NBTTagCompound entityNBT = possibleAlly.getEntityData();
|
||||||
|
|||||||
@@ -524,6 +524,7 @@ item.ebwizardry\:charm_move_speed.name=Icarus Medallion
|
|||||||
item.ebwizardry\:charm_move_speed.desc=Move at near-full speed when casting spells
|
item.ebwizardry\:charm_move_speed.desc=Move at near-full speed when casting spells
|
||||||
item.ebwizardry\:charm_spell_discovery.name=Archivist's Eyeglass
|
item.ebwizardry\:charm_spell_discovery.name=Archivist's Eyeglass
|
||||||
item.ebwizardry\:charm_spell_discovery.desc=Spell books found in chests are much more likely to be ones you have not yet discovered
|
item.ebwizardry\:charm_spell_discovery.desc=Spell books found in chests are much more likely to be ones you have not yet discovered
|
||||||
|
item.ebwizardry\:charm_spell_discovery.desc.color=When equipped, you can see the element of a known spell book by the color of its bookmark
|
||||||
item.ebwizardry\:charm_auto_smelt.name=Metallurgist's Mark
|
item.ebwizardry\:charm_auto_smelt.name=Metallurgist's Mark
|
||||||
item.ebwizardry\:charm_auto_smelt.desc=Pocket furnace triggers automatically when bound to a wand on your hotbar
|
item.ebwizardry\:charm_auto_smelt.desc=Pocket furnace triggers automatically when bound to a wand on your hotbar
|
||||||
item.ebwizardry\:charm_lava_walking.name=Nether Ice Core
|
item.ebwizardry\:charm_lava_walking.name=Nether Ice Core
|
||||||
@@ -1692,6 +1693,10 @@ config.ebwizardry.replace_vanilla_fall_damage=Replace Vanilla Fall Damage
|
|||||||
config.ebwizardry.replace_vanilla_fall_damage.tooltip=Whether to replace Minecraft's distance-based fall damage calculation with an equivalent, velocity-based one. This is done such that mobs in freefall will take exactly the same damage as normal, so it will not break falling-based mob farms. Disable this if you experience falling-related weirdness! If this is disabled, some spells revert to a more simplistic method of resetting the player's fall damage in certain cases.
|
config.ebwizardry.replace_vanilla_fall_damage.tooltip=Whether to replace Minecraft's distance-based fall damage calculation with an equivalent, velocity-based one. This is done such that mobs in freefall will take exactly the same damage as normal, so it will not break falling-based mob farms. Disable this if you experience falling-related weirdness! If this is disabled, some spells revert to a more simplistic method of resetting the player's fall damage in certain cases.
|
||||||
config.ebwizardry.replace_vanilla_fall_damage.true=Yes - it's parkour time
|
config.ebwizardry.replace_vanilla_fall_damage.true=Yes - it's parkour time
|
||||||
config.ebwizardry.replace_vanilla_fall_damage.false=No - break my legs normally
|
config.ebwizardry.replace_vanilla_fall_damage.false=No - break my legs normally
|
||||||
|
config.ebwizardry.spell_book_colors_require_charm=Spell Book Colors Require Archivist's Eyeglass
|
||||||
|
config.ebwizardry.spell_book_colors_require_charm.tooltip=Whether to require the Archivist's Eyeglass charm artifact to see colored spell book bookmarks.
|
||||||
|
config.ebwizardry.spell_book_colors_require_charm.true=Yes - I want to see the colours only if the charm is worn
|
||||||
|
config.ebwizardry.spell_book_colors_require_charm.false=No - I want to see the colours all the time
|
||||||
config.ebwizardry.blindness_tweak=Blindness Tweak
|
config.ebwizardry.blindness_tweak=Blindness Tweak
|
||||||
config.ebwizardry.blindness_tweak.tooltip=Whether to tweak the blindness effect to reduce follow distance when used on non-players. This automatically disables itself in favour of Potion Core's implementation if installed.
|
config.ebwizardry.blindness_tweak.tooltip=Whether to tweak the blindness effect to reduce follow distance when used on non-players. This automatically disables itself in favour of Potion Core's implementation if installed.
|
||||||
config.ebwizardry.mob_loot_table_whitelist=Mob Loot Table Whitelist
|
config.ebwizardry.mob_loot_table_whitelist=Mob Loot Table Whitelist
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"parent": "item/generated",
|
"parent": "ebwizardry:item/spell_book_undiscovered",
|
||||||
"textures": {
|
|
||||||
"layer0": "ebwizardry:items/spell_book"
|
|
||||||
},
|
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{"predicate": {"ebwizardry:element": 1}, "model": "ebwizardry:item/spell_book_discovered_magic"},
|
||||||
"predicate": {
|
{"predicate": {"ebwizardry:element": 2}, "model": "ebwizardry:item/spell_book_discovered_fire"},
|
||||||
"festive": 1
|
{"predicate": {"ebwizardry:element": 3}, "model": "ebwizardry:item/spell_book_discovered_ice"},
|
||||||
},
|
{"predicate": {"ebwizardry:element": 4}, "model": "ebwizardry:item/spell_book_discovered_lightning"},
|
||||||
"model": "ebwizardry:item/festive_spell_book"
|
{"predicate": {"ebwizardry:element": 5}, "model": "ebwizardry:item/spell_book_discovered_necromancy"},
|
||||||
}
|
{"predicate": {"ebwizardry:element": 6}, "model": "ebwizardry:item/spell_book_discovered_earth"},
|
||||||
|
{"predicate": {"ebwizardry:element": 7}, "model": "ebwizardry:item/spell_book_discovered_sorcery"},
|
||||||
|
{"predicate": {"ebwizardry:element": 8}, "model": "ebwizardry:item/spell_book_discovered_healing"},
|
||||||
|
{"predicate": {"festive": 1}, "model": "ebwizardry:item/festive_spell_book"}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_earth"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_fire"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_healing"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_ice"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_lightning"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_magic"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_necromancy"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book",
|
||||||
|
"layer1": "ebwizardry:items/spell_book_overlay_sorcery"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/generated",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "ebwizardry:items/spell_book"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 157 B |
|
After Width: | Height: | Size: 145 B |
|
After Width: | Height: | Size: 147 B |
|
After Width: | Height: | Size: 147 B |
|
After Width: | Height: | Size: 147 B |
|
After Width: | Height: | Size: 145 B |
|
After Width: | Height: | Size: 147 B |
|
After Width: | Height: | Size: 147 B |
|
After Width: | Height: | Size: 147 B |