Compare commits

..

45 Commits

Author SHA1 Message Date
WinDanesz e41f83a2dd build: 4.3.9 -> 4.3.10 version bump 2023-06-28 16:06:37 +02:00
WinDanesz 69b52cfe88 feat: A new ArtefactCheckEvent for addons, allowing devs to consider an artefact active (in slot) conditionally, or even prevent its usage based on custom conditions 2023-06-28 16:06:07 +02:00
WinDanesz 7591821e57 feat: A more Wizardry-native support for BELT, BODY, HEAD and TRINKET artefact types (expanded ItemArtefact.Type) intended for addons 2023-06-28 16:02:32 +02:00
WinDanesz 0ce0dcf2e9 feat: Configuration options for the values of: POTENCY_INCREASE_PER_TIER, COOLDOWN_REDUCTION_PER_LEVEL, DURATION_INCREASE_PER_LEVEL, RANGE_INCREASE_PER_LEVEL, BLAST_RADIUS_INCREASE_PER_LEVEL, RANGE_INCREASE_PER_LEVEL 2023-06-28 15:20:00 +02:00
WinDanesz 73811c3a6b feat: Config option to toggle wands not decrementing cooldowns outside of hands 2023-06-28 14:56:01 +02:00
WinDanesz 2a887b7794 fix: Fixed bug with wands not decrementing cooldowns in the offhand 2023-06-28 14:25:15 +02:00
WinDanesz ad9f482e76 fix: Fixed a bug that prevented NPCs (wizards) from casting certain buff spells 2023-06-28 13:55:09 +02:00
WinDanesz 6eaef94459 Fixed Mark Sacrifice reducing damage at amplifier level 0 2023-03-23 22:01:51 +01:00
ZettaSword 4f5c616240 Added missing sound for the Mirage spell (#835)
Because of "[Client thread/WARN]: Missing sound for event: ebwizardry:spell.mirage" in latest.log i found that Mirage spell has no effect, even if it's registered. That's why with this request i add it to sounds.json.
2023-01-11 15:50:07 +01:00
WinDanesz f5947dded9 chore: version bump to 4.3.9 2022-12-31 20:23:14 +01:00
WinDanesz 77e0acc16b fix: Fixed Curse of Undeath breaking wizard headgear. It no longer breaks hats, and the curse sets the player on fire if the hat has no mana. Fixes #820 2022-12-31 20:21:19 +01:00
WinDanesz e48646c5ff feat: Conjured bows will now shoot conjured arrows 2022-12-31 20:14:47 +01:00
WinDanesz 5e48fe51ea fix: Added missing import 2022-12-31 19:58:02 +01:00
WinDanesz 6b30dbef65 fix: Fixed onImbuementRemoval() not being called for imbuements expired in the inventory. Currently this bug was only affecting adons. Fixes #833 2022-12-31 19:52:11 +01:00
WinDanesz d6508a2be4 fix: Fixed Fire Skin potion effect's retaliatory burn duration (was 20x shorter than intended) 2022-12-31 19:51:43 +01:00
WinDanesz dfcadfb3bd fix: No more console spam from Muffle spell 2022-10-04 00:55:06 +02:00
ZettaSword 7888b92129 feat: Wand cooldown only decrements if the player holds the wand 2022-08-04 22:17:31 +02:00
ZettaSword 5b48dffa77 fix: Fixed the adaptive brightness of Oak/Iron/Diamondflesh 2022-08-04 22:15:06 +02:00
WinDanesz 5bf4650da1 fix: Fixed wizards not using addon book spells 2022-07-11 21:14:45 +02:00
WinDanesz 8e9c270b77 fix: Fixed wizards selling addon book spells with the default book 2022-07-11 21:13:38 +02:00
WinDanesz 00080331df feat: Reworked the Summon Iron Golem spell, its new name is Summon Spectral Golem 2022-07-08 22:18:59 +02:00
WinDanesz 27e40e2069 fix: Fixed the opacity of conjured arrows 2022-07-08 21:37:55 +02:00
WinDanesz 3a93877de3 fix: Fire Ring shouldn't instantly melt away players on servers anymore 2022-07-08 21:11:10 +02:00
WinDanesz 7f70784cd3 fix: Fixed Scrolls of continuous spells having a cooldown in creative mode 2022-07-08 20:36:46 +02:00
WinDanesz ed6e3df66e feat: The Arrow Rain spell summons conjured arrows 2022-07-08 20:32:22 +02:00
WinDanesz eb5becbbd4 fix: Fixed some addon crystals restoring more mana than they should
Fixes #816
2022-07-08 19:41:25 +02:00
WinDanesz 9599316fbc fix: Added a config option to prevent crash with guidebook loading on some locales. Note that if you use this config, you won't have the Wizard's Handbook in an usable state!
Fixes #815, Fixes #814, Fixes #800, Fixes #768
2022-07-08 19:30:03 +02:00
WinDanesz cc1c951ef8 feat: Soulwalker's Ring only soulbounds an entity for 20 seconds 2022-07-08 19:20:16 +02:00
WinDanesz d23c4cba18 feat: Forcefield loses 1% durability each time it repulses an enemy or a projectile 2022-07-08 19:16:54 +02:00
WinDanesz 3d30b0b96f feat: Forcefield loses 2% durability each time it repulses an enemy or a projectile 2022-06-22 22:38:54 +02:00
WinDanesz ad1e5d555a feat: Reworked the Oakflesh, Ironflesh and Diamondflesh spells 2022-06-22 22:24:30 +02:00
WinDanesz 14ea5f1c72 fix: Fixed Containment spell for entities 2022-06-19 23:25:36 +02:00
WinDanesz 709d44e4d9 feat: Class Armour sets (Sage, Warlock, Battlemage) only grant their set bonuses if each armour piece has mana 2022-06-19 12:44:14 +02:00
WinDanesz 8df00e9c41 feat: Added potency_per_level spell property for Empowerment, reduced potency gain per level 0.25->0.15 2022-06-13 23:12:14 +02:00
WinDanesz 8dbb0ec058 fix: Fixed 'Ward I' effect not giving any protection against magic 2022-06-12 23:33:07 +02:00
WinDanesz b8310eedae feat: Added a player_effect_duration_multiplier for the Paralysis spell, defaults to 0.5 2022-06-12 00:12:24 +02:00
WinDanesz c04754afe1 chore: version bump to v4.3.7 2022-04-17 21:37:20 +02:00
WinDanesz 3155aa6815 fix: Should fix the disconnect issue when pretty much all existing spell packs are present in the game
Mods were registering spells on the client and server side in a different order (perhaps related to the OS), causing a mismatch in spell networkIDs. This will ensure that spells are sorted alphabetically and redistributes a new ID.
2022-04-17 20:43:59 +02:00
WinDanesz ea27b1a081 Revert "Merge pull request #750 from WinDanesz/patch-1226-2" 2022-04-17 15:53:48 +02:00
WinDanesz 4d078f9597 Revert "Fixed crash on dedicated servers (PacketSpellProperties), Fixes #780, #779, #773, #774, #771, #768"
This reverts commit 6690564017.
2022-04-17 15:46:11 +02:00
WinDanesz 67459cbbbd chore: Delete feature_request.md 2022-04-15 14:06:33 +02:00
WinDanesz 932de4e969 chore: Delete question.md 2022-04-15 13:58:44 +02:00
WinDanesz 41e28291ad chore: create config.yml 2022-04-15 13:58:29 +02:00
WinDanesz 6ae6324368 chore: Rename bug_report.md to bug_report.yml 2022-04-15 13:52:10 +02:00
WinDanesz 4858716f05 chore: update bug_report.md 2022-04-15 13:51:44 +02:00
65 changed files with 1039 additions and 231 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.6",
"1.12.2-recommended": "4.3.6"
"1.12.2-latest": "4.3.10",
"1.12.2-recommended": "4.3.10"
}
}
-20
View File
@@ -1,20 +0,0 @@
---
name: Bug report
about: Report a crash or something that isn't working as it should
title: "[Give a brief, relevant title here]"
labels: bug
assignees: ''
---
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting. You may also find the [troubleshooting page](https://github.com/Electroblob77/Wizardry/wiki/Troubleshooting) helpful.
Minecraft version: 1.12.2 [change as necessary]
Wizardry version: 4.3.6 [change as necessary]
Environment: Singleplayer/LAN game/Server [delete as necessary]
Issue details: [describe what you were doing when the issue occurred, what went wrong, what you expected to happen, etc.]
Other mods involved: [only list mods that are relevant to the problem]
Link to crash report (if applicable): [give a link to the crash report on gist, pastebin, etc.]
+85
View File
@@ -0,0 +1,85 @@
name: 🐛 Bug Report
description: Something is not working as expected
title: "[Bug] <write the title here>"
labels: [ "bug", "Needs Triage" ]
body:
- type: markdown
attributes:
value: |
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting. You may also find the [troubleshooting page](https://github.com/Electroblob77/Wizardry/wiki/Troubleshooting) helpful.
Please try the latest version of the mod and check if the issue persist before submitting a report.
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: textarea
id: observed
attributes:
label: Observed behaviour
description: Describe what happened and when this happened
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behaviour
description: Describe what you expected to happen
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Steps to reproduce
description: Step by step instructions on how to reproduce the observed behaviour
placeholder: |
1. Join a server
2. Cast the [spell]
3. ...
validations:
required: true
- type: input
id: crashlog
attributes:
label: Crashlog
description: If this was a crash, grab [minecraft instance]/logs/debug.log, upload it as a [gist](https://gist.github.com/) and paste the link here. Alternatively, give a link to the crash report on gist, pastebin if you already have one there.
placeholder: https://gist.github.com/<your-user>/abcdef124
- type: dropdown
id: environment
attributes:
label: Environment (Singleplayer/Server, etc.)
options:
- Singleplayer
- LAN game/Server
- Issue present on both sides
- Not sure
validations:
required: true
- type: input
id: mod-version
attributes:
label: Mod version
placeholder: 1.0.0
validations:
required: true
- type: input
id: minecraft-version
attributes:
label: Minecraft version
placeholder: 12.2.2
validations:
required: true
- type: input
id: forge-version
attributes:
label: Forge version
placeholder: 1.12.2 - 14.23.5.2860
validations:
required: true
- type: textarea
id: other-mods
attributes:
label: Other mods
description: List any other mods present when the bug was encountered, include the mod versions. You only have to fill this if no crash log was attached
+14
View File
@@ -0,0 +1,14 @@
blank_issues_enabled: false
contact_links:
- name: 📖 Mod Wiki Page
url: https://github.com/Electroblob77/Wizardry/wiki
about: Most features are documented in the mod's wiki page --- Link --->
- name: 💬 Electroblob's Wizardry discord
url: https://discord.gg/hs8yJP2
about: Ask for help or get more info on Discord. --- Discord Server link --->
- name: 💡 Feature requests / suggestions
url: https://discord.gg/hs8yJP2
about: Please use the discord server to suggest stuff. --- Discord Server link --->
- name: ❓ Question
url: https://discord.gg/hs8yJP2
about: Ask a question about the mod or the code. --- Discord Server link --->
-16
View File
@@ -1,16 +0,0 @@
---
name: Feature request
about: Make a suggestion for improving the mod
title: "[Give a brief, relevant title here]"
labels: enhancement
assignees: ''
---
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting.
Minecraft versions: [if this suggestion only applies to some versions, list them here]
Suggestion details: [describe what you would like to see added to the mod and why]
Other mods involved: [if this suggestion involves integration with other mods, list them here]
-17
View File
@@ -1,17 +0,0 @@
---
name: Question
about: Ask a question about the mod or the code
title: "[Give a brief, relevant title here]"
labels: question
assignees: ''
---
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting.
Minecraft version: 1.12.2 [change as necessary]
Wizardry version: [change as necessary]
Question details: [explain your question here]
Other mods involved: [if this question involves other mods, list them here]
+1 -1
View File
@@ -1,7 +1,7 @@
# Credits
Electroblob's Wizardry
Version 4.3.6
Version 4.3.7
For Minecraft 1.12.2
Designed, coded and textured by Electroblob
+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.6" // There, it matches semver, happy now?
version = "4.3.10"
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "ElectroblobsWizardry"
@@ -156,6 +156,12 @@ public final class Settings {
public Pair<ResourceLocation, Short>[] treeBlocks = parseItemMetaStrings(DEFAULT_TREE_BLOCKS);
/** <b>[Server-only]</b> The chance for wizard towers to generate with an evil wizard and chest inside. */
public double evilWizardChance = 0.2;
public double cooldownReductionPerLevel = 0.15;
public double potencyIncreasePerTier = 0.15;
public double durationIncreasePerLevel = 0.25;
public double rangeIncreasePerLevel = 0.25;
public double blastIncreasePerLevel = 0.25;
public double frostSlownessIncreasePerLevel = 0.5;
/** <b>[Server-only]</b> List of dimension ids in which to generate crystal ore. */
public int[] oreDimensions = {0};
/** <b>[Server-only]</b> List of dimension ids in which to generate crystal flowers. */
@@ -198,6 +204,8 @@ public final class Settings {
public boolean blindnessTweak = true;
/** <b>[Server-only]</b> Whether using bonemeal on grass blocks has a chance to grow crystal flowers. */
public boolean bonemealGrowsCrystalFlowers = true;
/** <b>[Server-only]</b> Whether wands only decrement their cooldowns if a player holds them. */
public boolean wandsMustBeHeldToDecrementCooldown = false;
/** <b>[Server-only]</b> Whether to enable Wizardry mob loot injection. Allows an easier switch instead of blacklisting all entities. */
public boolean injectMobDrops = true;
/**
@@ -379,6 +387,9 @@ public final class Settings {
public boolean showSpellHUD = true;
/** <b>[Client-only]</b> Whether to show the charge meter when charging up a spell. */
public boolean showChargeMeter = true;
/** <b>[Client-only]</b> Whether to initialise the handbook's data. Setting this to false will break the in-game handbook, but might help with some
* startup crashes */
public boolean loadHandbook = true;
/** <b>[Client-only]</b> The position of the spell HUD. */
public GuiPosition spellHUDPosition = GuiPosition.BOTTOM_LEFT;
@@ -665,6 +676,13 @@ public final class Settings {
bonemealGrowsCrystalFlowers = property.getBoolean();
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "wandsMustBeHeldToDecrementCooldown", false,
"Whether wands only decrement their cooldowns if a player holds them.");
property.setLanguageKey("config." + Wizardry.MODID + ".wands_must_be_held_to_decrement_cooldown");
Wizardry.proxy.setToNamedBooleanEntry(property);
wandsMustBeHeldToDecrementCooldown = property.getBoolean();
propOrder.add(property.getName());
checkForRedundantOptions(GAMEPLAY_CATEGORY, propOrder); // Must be before the order is set!
config.setCategoryPropertyOrder(GAMEPLAY_CATEGORY, propOrder);
@@ -923,6 +941,50 @@ public final class Settings {
}
}
property = config.get(TWEAKS_CATEGORY, "cooldown_reduction_per_level", 0.15,
"The fraction by which cooldowns are reduced for each level of cooldown upgrade.",
0.05, Integer.MAX_VALUE); // Sure, I mean you COULD set it to 2^31-1... what could possibly go wrong?
property.setLanguageKey("config." + Wizardry.MODID + ".cast_command_multiplier_limit");
cooldownReductionPerLevel = property.getDouble();
propOrder.add(property.getName());
property = config.get(TWEAKS_CATEGORY, "potency_increase_per_tier", 0.15,
"The fraction by which potency is increased for each tier of matching wand. May cause extreme lag with high values!",
0.05, Integer.MAX_VALUE);
property.setLanguageKey("config." + Wizardry.MODID + ".potency_increase_per_tier");
potencyIncreasePerTier = property.getDouble();
propOrder.add(property.getName());
property = config.get(TWEAKS_CATEGORY, "duration_increase_per_level", 0.25,
"The fraction by which spell duration is increased for each level of duration upgrade.",
0.05, Integer.MAX_VALUE);
property.setLanguageKey("config." + Wizardry.MODID + ".duration_increase_per_level");
durationIncreasePerLevel = property.getDouble();
propOrder.add(property.getName());
property = config.get(TWEAKS_CATEGORY, "range_increase_per_level", 0.25,
"The fraction by which spell range is increased for each level of range upgrade. May cause extreme lag with high values!",
0.05, Integer.MAX_VALUE);
property.setLanguageKey("config." + Wizardry.MODID + ".range_increase_per_level");
rangeIncreasePerLevel = property.getDouble();
propOrder.add(property.getName());
property = config.get(TWEAKS_CATEGORY, "blast_increase_per_level", 0.25,
"The fraction by which spell blast is increased for each level of blast upgrade. May cause extreme lag with high values!",
0.05, Integer.MAX_VALUE);
property.setLanguageKey("config." + Wizardry.MODID + ".blast_increase_per_level");
blastIncreasePerLevel = property.getDouble();
propOrder.add(property.getName());
property = config.get(TWEAKS_CATEGORY, "frost_slowness_increase_per_level", 0.5,
"The fraction by which movement speed is reduced per level of frost effect.",
0.05, Integer.MAX_VALUE);
property.setLanguageKey("config." + Wizardry.MODID + ".frost_slowness_increase_per_level");
frostSlownessIncreasePerLevel = property.getDouble();
propOrder.add(property.getName());
checkForRedundantOptions(TWEAKS_CATEGORY, propOrder); // Must be before the order is set!
config.setCategoryPropertyOrder(TWEAKS_CATEGORY, propOrder);
@@ -1112,6 +1174,13 @@ public final class Settings {
showChargeMeter = 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.setLanguageKey("config." + Wizardry.MODID + ".load_handbook");
property.setRequiresWorldRestart(false);
Wizardry.proxy.setToNamedBooleanEntry(property);
loadHandbook = property.getBoolean();
propOrder.add(property.getName());
property = config.get(CLIENT_CATEGORY, "spellHUDPosition", GuiPosition.BOTTOM_LEFT.name, "The position of the spell HUD.", GuiPosition.names);
property.setLanguageKey("config." + Wizardry.MODID + ".spell_hud_position");
spellHUDPosition = GuiPosition.fromName(property.getString());
@@ -20,6 +20,7 @@ import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryLoot;
import electroblob.wizardry.registry.WizardrySounds;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.SpellNetworkIDSorter;
import electroblob.wizardry.util.SpellProperties;
import electroblob.wizardry.util.WandHelper;
import electroblob.wizardry.worldgen.WorldGenCrystalFlower;
@@ -81,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.6";
public static final String VERSION = "4.3.10";
/**
* Json file used by Forge's built-in <a href="https://mcforge.readthedocs.io/en/1.12.x/gettingstarted/autoupdate/">update checker</a>.
@@ -126,11 +127,10 @@ public class Wizardry {
public void preInit(FMLPreInitializationEvent event){
logger = event.getModLog();
proxy.registerResourceReloadListeners();
configDirectory = new File(event.getModConfigurationDirectory(), Wizardry.MODID);
settings.initConfig(event);
proxy.registerResourceReloadListeners();
Calendar calendar = Calendar.getInstance();
tisTheSeason = calendar.get(Calendar.MONTH) + 1 == 12 && calendar.get(Calendar.DAY_OF_MONTH) >= 24
@@ -202,6 +202,8 @@ public class Wizardry {
public void postInit(FMLPostInitializationEvent event){
proxy.initialiseLayers();
proxy.initialiseAnimations();
SpellNetworkIDSorter.init();
}
@EventHandler
@@ -203,7 +203,6 @@ public final class WizardryEventHandler {
// Find the angle between the direction the mob is looking and the direction the player is in
// Angle between a and b = acos((a.b) / (|a|*|b|))
double angle = Math.acos(vec.dotProduct(event.getEntity().getLookVec()) / vec.length());
System.out.println(angle);
// If the player is not within the 144-degree arc in front of the mob, it won't detect them
if(angle > 0.4 * Math.PI){
((EntityLiving)event.getEntityLiving()).setAttackTarget(null);
@@ -269,7 +268,7 @@ public final class WizardryEventHandler {
// Fireskin
if(event.getEntityLiving().isPotionActive(WizardryPotions.fireskin)
&& !MagicDamage.isEntityImmune(DamageType.FIRE, event.getEntityLiving()))
attacker.setFire(Spells.fire_breath.getProperty(Spell.BURN_DURATION).intValue());
attacker.setFire(Spells.fire_breath.getProperty(Spell.BURN_DURATION).intValue() * 20);
// Ice Shroud
if(event.getEntityLiving().isPotionActive(WizardryPotions.ice_shroud)
@@ -307,7 +306,7 @@ public final class WizardryEventHandler {
PotionEffect effect = event.getEntityLiving().getActivePotionEffect(WizardryPotions.ward);
if(effect != null && event.getSource().isMagicDamage()){
event.setAmount(event.getAmount() * Math.max(0, 1 - 0.4f * effect.getAmplifier())); // Resistance is 20%
event.setAmount(event.getAmount() * Math.max(0, 1 - 0.2f * (1 + effect.getAmplifier()))); // Resistance is 20%
}
// Flaming and freezing swords
@@ -491,4 +490,4 @@ public final class WizardryEventHandler {
}
}
}
}
@@ -1,6 +1,7 @@
package electroblob.wizardry.client;
import electroblob.wizardry.CommonProxy;
import electroblob.wizardry.Settings;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.block.BlockBookshelf;
import electroblob.wizardry.client.animation.ActionAnimation;
@@ -19,6 +20,7 @@ import electroblob.wizardry.client.model.ModelSageArmour;
import electroblob.wizardry.client.model.ModelWizardArmour;
import electroblob.wizardry.client.particle.*;
import electroblob.wizardry.client.particle.ParticleWizardry.IWizardryParticleFactory;
import electroblob.wizardry.client.renderer.RenderSpectralGolem;
import electroblob.wizardry.client.renderer.entity.*;
import electroblob.wizardry.client.renderer.entity.layers.*;
import electroblob.wizardry.client.renderer.overlay.RenderBlinkEffect;
@@ -164,7 +166,8 @@ public class ClientProxy extends CommonProxy {
IResourceManager manager = Minecraft.getMinecraft().getResourceManager();
if(manager instanceof IReloadableResourceManager){
((IReloadableResourceManager)manager).registerReloadListener(GuiSpellDisplay::loadSkins);
((IReloadableResourceManager)manager).registerReloadListener(GuiWizardHandbook::loadHandbookFile);
if (Wizardry.settings.loadHandbook)
((IReloadableResourceManager)manager).registerReloadListener(GuiWizardHandbook::loadHandbookFile);
}
}
@@ -728,6 +731,9 @@ public class ClientProxy extends CommonProxy {
LayerTiledOverlay.initialiseLayers(LayerMindControl::new);
LayerTiledOverlay.initialiseLayers(LayerSummonAnimation::new);
LayerTiledOverlay.initialiseLayers(LayerDisintegrateAnimation::new);
LayerTiledOverlay.initialiseLayers(LayerOak::new);
LayerTiledOverlay.initialiseLayers(LayerIron::new);
LayerTiledOverlay.initialiseLayers(LayerDiamond::new);
}
@Override
@@ -766,6 +772,7 @@ public class ClientProxy extends CommonProxy {
RenderingRegistry.registerEntityRenderingHandler(EntityIceGiant.class, RenderIceGiant::new);
RenderingRegistry.registerEntityRenderingHandler(EntityPhoenix.class, RenderPhoenix::new);
RenderingRegistry.registerEntityRenderingHandler(EntitySpectralGolem.class, RenderSpectralGolem::new);
// Projectiles
RenderingRegistry.registerEntityRenderingHandler(EntityMagicMissile.class, manager -> new RenderMagicArrow(manager,
@@ -780,6 +787,7 @@ public class ClientProxy extends CommonProxy {
new ResourceLocation(Wizardry.MODID, "textures/entity/ice_lance.png"), false, 16.0, 3.0, 22, 5, false));
RenderingRegistry.registerEntityRenderingHandler(EntityFlamecatcherArrow.class, manager -> new RenderMagicArrow(manager,
new ResourceLocation(Wizardry.MODID, "textures/entity/flamecatcher_arrow.png"), false, 8, 2.0, 16, 5, true));
RenderingRegistry.registerEntityRenderingHandler(EntityConjuredArrow.class, RenderConjuredArrow::new);
RenderingRegistry.registerEntityRenderingHandler(EntityForceArrow.class, RenderForceArrow::new);
@@ -0,0 +1,52 @@
package electroblob.wizardry.client.renderer;
import electroblob.wizardry.Wizardry;
import net.minecraft.client.model.ModelIronGolem;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderLiving;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.entity.monster.EntityIronGolem;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.opengl.GL11;
@SideOnly(Side.CLIENT)
public class RenderSpectralGolem extends RenderLiving<EntityIronGolem>
{
private static final ResourceLocation SPECTRAL_GOLEM_TEXTURES = new ResourceLocation(Wizardry.MODID, "textures/entity/spectral_golem.png");
public RenderSpectralGolem(RenderManager renderManagerIn)
{
super(renderManagerIn, new ModelIronGolem(), 0.5F);
}
/**
* Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture.
*/
protected ResourceLocation getEntityTexture(EntityIronGolem entity)
{
return SPECTRAL_GOLEM_TEXTURES;
}
@Override
protected void preRenderCallback(EntityIronGolem entity, float partialTickTime){
super.preRenderCallback(entity, partialTickTime);
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GlStateManager.color(1, 1, 1, 0.7f);
}
protected void applyRotations(EntityIronGolem entityLiving, float ageInTicks, float rotationYaw, float partialTicks)
{
super.applyRotations(entityLiving, ageInTicks, rotationYaw, partialTicks);
if ((double)entityLiving.limbSwingAmount >= 0.01D)
{
float f = 13.0F;
float f1 = entityLiving.limbSwing - entityLiving.limbSwingAmount * (1.0F - partialTicks) + 6.0F;
float f2 = (Math.abs(f1 % 13.0F - 6.5F) - 3.25F) / 3.25F;
GlStateManager.rotate(6.5F * f2, 0.0F, 0.0F, 1.0F);
}
}
}
@@ -0,0 +1,37 @@
package electroblob.wizardry.client.renderer.entity;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.projectile.EntityConjuredArrow;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderArrow;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.opengl.GL11;
@SideOnly(Side.CLIENT)
public class RenderConjuredArrow extends RenderArrow<EntityConjuredArrow> {
public static final ResourceLocation CONJURED_ARROW_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/conjured_arrow.png");
public RenderConjuredArrow(RenderManager manager) {
super(manager);
}
@Override
protected ResourceLocation getEntityTexture(EntityConjuredArrow entity) {
return CONJURED_ARROW_TEXTURE;
}
@Override
public void doRender(EntityConjuredArrow entity, double x, double y, double z, float entityYaw, float partialTicks) {
GlStateManager.pushMatrix();
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GlStateManager.color(1, 1, 1, 0.4f);
super.doRender(entity, x, y, z, entityYaw, partialTicks);
GlStateManager.popMatrix();
}
}
@@ -0,0 +1,53 @@
package electroblob.wizardry.client.renderer.entity.layers;
import electroblob.wizardry.registry.WizardryPotions;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GlStateManager.DestFactor;
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.entity.RenderLivingBase;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.ResourceLocation;
/**
* Layer used to render the diamondflesh texture on creatures with the diamondflesh effect.
*
* @author WinDanesz
* @since Wizardry 4.3.7
*/
public class LayerDiamond extends LayerTiledOverlay<EntityLivingBase> {
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/blocks/diamond_block.png");
public LayerDiamond(RenderLivingBase<?> renderer){
super(renderer);
}
@Override
public boolean shouldRender(EntityLivingBase entity, float partialTicks){
return !entity.isInvisible() && entity.isPotionActive(WizardryPotions.diamondflesh);
}
@Override
public ResourceLocation getTexture(EntityLivingBase entity, float partialTicks){
return TEXTURE;
}
@Override
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
float ageInTicks, float netHeadYaw, float headPitch, float scale){
GlStateManager.enableBlend();
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
int j = entity.getBrightnessForRender();
int k = j % 65536;
int l = j / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) k, (float) l);
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
GlStateManager.disableBlend();
}
}
@@ -0,0 +1,53 @@
package electroblob.wizardry.client.renderer.entity.layers;
import electroblob.wizardry.registry.WizardryPotions;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GlStateManager.DestFactor;
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.entity.RenderLivingBase;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.ResourceLocation;
/**
* Layer used to render the ironflesh texture on creatures with the ironflesh effect.
*
* @author WinDanesz
* @since Wizardry 4.3.7
*/
public class LayerIron extends LayerTiledOverlay<EntityLivingBase> {
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/blocks/iron_block.png");
public LayerIron(RenderLivingBase<?> renderer){
super(renderer);
}
@Override
public boolean shouldRender(EntityLivingBase entity, float partialTicks){
return !entity.isInvisible() && entity.isPotionActive(WizardryPotions.ironflesh);
}
@Override
public ResourceLocation getTexture(EntityLivingBase entity, float partialTicks){
return TEXTURE;
}
@Override
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
float ageInTicks, float netHeadYaw, float headPitch, float scale){
GlStateManager.enableBlend();
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
int j = entity.getBrightnessForRender();
int k = j % 65536;
int l = j / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) k, (float) l);
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
GlStateManager.disableBlend();
}
}
@@ -0,0 +1,53 @@
package electroblob.wizardry.client.renderer.entity.layers;
import electroblob.wizardry.registry.WizardryPotions;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GlStateManager.DestFactor;
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.entity.RenderLivingBase;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.ResourceLocation;
/**
* Layer used to render the oakflesh texture on creatures with the oakflesh effect.
*
* @author WinDanesz
* @since Wizardry 4.3.7
*/
public class LayerOak extends LayerTiledOverlay<EntityLivingBase> {
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/blocks/log_oak.png");
public LayerOak(RenderLivingBase<?> renderer){
super(renderer);
}
@Override
public boolean shouldRender(EntityLivingBase entity, float partialTicks){
return !entity.isInvisible() && entity.isPotionActive(WizardryPotions.oakflesh);
}
@Override
public ResourceLocation getTexture(EntityLivingBase entity, float partialTicks){
return TEXTURE;
}
@Override
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
float ageInTicks, float netHeadYaw, float headPitch, float scale){
GlStateManager.enableBlend();
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
int j = entity.getBrightnessForRender();
int k = j % 65536;
int l = j / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) k, (float) l);
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
GlStateManager.disableBlend();
}
}
@@ -1,5 +1,6 @@
package electroblob.wizardry.constants;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.WizardryEventHandler;
/** Stores various global constants used in Wizardry. */
@@ -17,17 +18,17 @@ public final class Constants {
/** The bonus amount of wand upgrades that can be applied to a non-elemental wand. */
public static final int NON_ELEMENTAL_UPGRADE_BONUS = 3;
/** The fraction by which cooldowns are reduced for each level of cooldown upgrade. */
public static final float COOLDOWN_REDUCTION_PER_LEVEL = 0.15f;
public static float COOLDOWN_REDUCTION_PER_LEVEL = 0.15f;
/** The fraction by which maximum charge is increased for each level of storage upgrade. */
public static final float STORAGE_INCREASE_PER_LEVEL = 0.15f;
/** The fraction by which potency is increased for each tier of matching wand. */
public static final float POTENCY_INCREASE_PER_TIER = 0.15f;
public static float POTENCY_INCREASE_PER_TIER = 0.15f;
/** The fraction by which spell duration is increased for each level of duration upgrade. */
public static final float DURATION_INCREASE_PER_LEVEL = 0.25f;
public static float DURATION_INCREASE_PER_LEVEL = 0.25f;
/** The fraction by which spell range is increased for each level of range upgrade. */
public static final float RANGE_INCREASE_PER_LEVEL = 0.25f;
public static float RANGE_INCREASE_PER_LEVEL = 0.25f;
/** The fraction by which spell blast radius is increased for each level of range upgrade. */
public static final float BLAST_RADIUS_INCREASE_PER_LEVEL = 0.25f;
public static float BLAST_RADIUS_INCREASE_PER_LEVEL = 0.25f;
/** The fraction by which movement speed is reduced per level of frost effect. */
public static final double FROST_SLOWNESS_PER_LEVEL = 0.5;
/** The fraction by which movement speed is reduced per level of decay effect. */
@@ -46,7 +47,15 @@ public final class Constants {
* won't spawn again if something is already standing in it.
*/
public static final int DECAY_SPREAD_INTERVAL = 8;
/** The fraction by which potency is increased per level of the empowerment effect. */
public static final float EMPOWERMENT_POTENCY_PER_LEVEL = 0.25f;
// making this as an update to the existing values to not break addons directly relying on the fields
static {
POTENCY_INCREASE_PER_TIER = (float) Wizardry.settings.potencyIncreasePerTier;
COOLDOWN_REDUCTION_PER_LEVEL = (float) Wizardry.settings.cooldownReductionPerLevel;
DURATION_INCREASE_PER_LEVEL = (float) Wizardry.settings.durationIncreasePerLevel;
RANGE_INCREASE_PER_LEVEL = (float) Wizardry.settings.rangeIncreasePerLevel;
BLAST_RADIUS_INCREASE_PER_LEVEL = (float) Wizardry.settings.blastIncreasePerLevel;
RANGE_INCREASE_PER_LEVEL = (float) Wizardry.settings.frostSlownessIncreasePerLevel;
}
}
@@ -382,6 +382,7 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
activeImbuements.add((Imbuement)enchantment);
}else{
// Otherwise, removes the enchantment from the item
((Imbuement) enchantment).onImbuementRemoval(stack);
iterator.remove(); // FIXME: Apparently this can cause a CME
}
}
@@ -1,10 +1,8 @@
package electroblob.wizardry.entity.construct;
import electroblob.wizardry.entity.projectile.EntityConjuredArrow;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.spell.Spell;
import net.minecraft.entity.projectile.EntityTippedArrow;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
@@ -30,7 +28,7 @@ public class EntityArrowRain extends EntityScaledConstruct {
double y = posY + world.rand.nextDouble() * (double)height;
double z = posZ + (world.rand.nextDouble() - 0.5D) * (double)width;
EntityTippedArrow arrow = new EntityTippedArrow(world, x, y, z);
EntityConjuredArrow arrow = new EntityConjuredArrow(world, x, y, z);
arrow.motionX = MathHelper.cos((float)Math.toRadians(this.rotationYaw + 90));
arrow.motionY = -0.6;
@@ -38,7 +36,6 @@ public class EntityArrowRain extends EntityScaledConstruct {
arrow.shootingEntity = this.getCaster();
arrow.setDamage(7.0d * damageMultiplier);
arrow.setPotionEffect(new ItemStack(Items.ARROW));
this.world.spawnEntity(arrow);
}
@@ -32,7 +32,7 @@ public class EntityFireRing extends EntityScaledConstruct {
super.onUpdate();
if(!this.world.isRemote){
if(this.ticksExisted % 5 == 0 && !this.world.isRemote){
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY, this.posZ, this.world);
@@ -168,6 +168,10 @@ public class EntityForcefield extends EntityMagicConstruct implements ICustomHit
((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target));
}
if (this.ticksExisted % 5 == 0) {
this.lifetime = (int) (lifetime * 0.99);
}
}else{
Vec3d relativeImpactPos = targetRelativePos.normalize().scale(radius);
@@ -0,0 +1,192 @@
package electroblob.wizardry.entity.living;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.util.ParticleBuilder;
import net.minecraft.entity.EntityFlying;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.ai.EntityAIAttackMelee;
import net.minecraft.entity.ai.EntityAIHurtByTarget;
import net.minecraft.entity.ai.EntityAILookAtVillager;
import net.minecraft.entity.ai.EntityAILookIdle;
import net.minecraft.entity.ai.EntityAIMoveThroughVillage;
import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
import net.minecraft.entity.ai.EntityAIMoveTowardsTarget;
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
import net.minecraft.entity.ai.EntityAIWatchClosest;
import net.minecraft.entity.monster.EntityIronGolem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.DifficultyInstance;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.World;
import java.util.UUID;
public class EntitySpectralGolem extends EntityIronGolem implements ISummonedCreature {
private static final DataParameter<Boolean> SPAWN_PARTICLES = EntityDataManager.createKey(EntitySpectralGolem.class, DataSerializers.BOOLEAN);
// Field implementations
private int lifetime = -1;
private UUID casterUUID;
// Setter + getter implementations
@Override public int getLifetime(){ return lifetime; }
@Override public void setLifetime(int lifetime){ this.lifetime = lifetime; }
@Override public UUID getOwnerId(){ return casterUUID; }
@Override public void setOwnerId(UUID uuid){ this.casterUUID = uuid; }
/** Creates a new golem minion in the given world. */
public EntitySpectralGolem(World world){
super(world);
this.experienceValue = 0;
}
@Override
protected void entityInit(){
super.entityInit();
this.dataManager.register(SPAWN_PARTICLES, true);
}
@Override
protected void initEntityAI() {
this.tasks.addTask(1, new EntityAIAttackMelee(this, 1.0D, true));
this.tasks.addTask(2, new EntityAIMoveTowardsTarget(this, 0.9D, 32.0F));
this.tasks.addTask(3, new EntityAIMoveThroughVillage(this, 0.6D, true));
this.tasks.addTask(4, new EntityAIMoveTowardsRestriction(this, 1.0D));
this.tasks.addTask(5, new EntityAILookAtVillager(this));
this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 0.6D));
this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
this.tasks.addTask(8, new EntityAILookIdle(this));
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityLivingBase.class,
0, false, true, this.getTargetSelector()));
}
@Override protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty){} // They don't have equipment!
// Implementations
@Override
public void setRevengeTarget(EntityLivingBase entity){
if(this.shouldRevengeTarget(entity)) super.setRevengeTarget(entity);
}
@Override
public void onUpdate(){
super.onUpdate();
this.updateDelegate();
// Adds a dust particle effect
if(this.world.isRemote){
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
ParticleBuilder.create(ParticleBuilder.Type.DUST).pos(x, y, z).clr(0.7f, 0.9f, 1).shaded(true).spawn(world);
}
}
@Override
public void onSpawn(){
if(this.dataManager.get(SPAWN_PARTICLES)) this.spawnParticleEffect();
}
@Override
public void onDespawn(){
this.spawnParticleEffect();
}
private void spawnParticleEffect(){
if(this.world.isRemote){
for(int i = 0; i < 15; i++){
this.world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.posX + this.rand.nextFloat() - 0.5f,
this.posY + this.rand.nextFloat() * 2, this.posZ + this.rand.nextFloat() - 0.5f, 0, 0, 0);
}
}
}
@Override
public boolean hasParticleEffect(){
return true;
}
@Override
public boolean hasAnimation(){
return this.dataManager.get(SPAWN_PARTICLES) || this.ticksExisted > 20;
}
public void hideParticles(){
this.dataManager.set(SPAWN_PARTICLES, false);
}
@Override
protected boolean processInteract(EntityPlayer player, EnumHand hand){
// In this case, the delegate method determines whether super is called.
// Rather handily, we can make use of Java's short-circuiting method of evaluating OR statements.
return this.interactDelegate(player, hand) || super.processInteract(player, hand);
}
@Override
public void writeEntityToNBT(NBTTagCompound nbttagcompound){
super.writeEntityToNBT(nbttagcompound);
this.writeNBTDelegate(nbttagcompound);
}
@Override
public void readEntityFromNBT(NBTTagCompound nbttagcompound){
super.readEntityFromNBT(nbttagcompound);
this.readNBTDelegate(nbttagcompound);
}
// Recommended overrides
@Override protected int getExperiencePoints(EntityPlayer player){ return 0; }
@Override protected boolean canDropLoot(){ return false; }
@Override protected Item getDropItem(){ return null; }
@Override protected ResourceLocation getLootTable(){ return null; }
@Override public boolean canPickUpLoot(){ return false; }
// This vanilla method has nothing to do with the custom despawn() method.
@Override protected boolean canDespawn(){
return getCaster() == null && getOwnerId() == null;
}
@Override
public boolean getCanSpawnHere(){
return this.world.getDifficulty() != EnumDifficulty.PEACEFUL;
}
@Override
public boolean canAttackClass(Class<? extends EntityLivingBase> entityType){
// Returns true unless the given entity type is a flying entity.
return !EntityFlying.class.isAssignableFrom(entityType);
}
@Override
public ITextComponent getDisplayName(){
if(getCaster() != null){
return new TextComponentTranslation(NAMEPLATE_TRANSLATION_KEY, getCaster().getName(),
new TextComponentTranslation("entity." + this.getEntityString() + ".name"));
}else{
return super.getDisplayName();
}
}
@Override
public boolean hasCustomName(){
// If this returns true, the renderer will show the nameplate when looking directly at the entity
return Wizardry.settings.summonedCreatureNames && getCaster() != null;
}
}
@@ -47,6 +47,7 @@ import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -637,10 +638,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
// This means it is more likely for spell books sold to be of the same element as the wizard if the
// wizard has an element.
return new ItemStack(WizardryItems.spell_book, 1,
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
}else{
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
}
}else{
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
@@ -659,10 +659,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
// This means it is more likely for spell books sold to be of the same element as the wizard if the
// wizard has an element.
return new ItemStack(WizardryItems.spell_book, 1,
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
}else{
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
}
}else if(randomiser < 6){
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
@@ -696,10 +695,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
// This means it is more likely for spell books sold to be of the same element as the wizard if the
// wizard has an element.
return new ItemStack(WizardryItems.spell_book, 1,
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
}else{
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
}
}else if(randomiser < 6){
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
@@ -724,8 +722,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
if(randomiser < 5 && this.getElement() != Element.MAGIC && !specialismSpells.isEmpty()){
// Master spells can only be sold by a specialist in that element.
return new ItemStack(WizardryItems.spell_book, 1,
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
}else if(randomiser < 6){
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
@@ -801,7 +798,6 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
Tier maxTier = Tier.NOVICE;
List<Spell> npcSpells = Spell.getSpells(s -> s.canBeCastBy(wizard, false));
npcSpells.removeIf(s -> !s.applicableForItem(WizardryItems.spell_book));
for(int i = 0; i < n; i++){
@@ -849,6 +845,22 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
return maxTier;
}
/**
* Helper method to handle addon spell books.
* @param spell the spell to look up.
* @return Checks all items of the spell's namespace (modid) if they are applicable for the spell and returns the first match, or falls back to WizardryItems.spell_book if no match was found.
*/
public static ItemStack getBookStackForSpell(Spell spell) {
String modid = spell.getRegistryName().getNamespace();
if (modid.equals(Wizardry.MODID)) {
return new ItemStack(WizardryItems.spell_book, 1, spell.metadata());
}
Optional<Item> firstMatch = ForgeRegistries.ITEMS.getValuesCollection().stream().filter(v -> v instanceof ItemSpellBook && spell.applicableForItem(v)
&& v.getRegistryName().getNamespace().equals(modid)).findFirst();
return firstMatch.map(item -> new ItemStack(item, 1, spell.metadata())).orElseGet(() -> new ItemStack(WizardryItems.spell_book, 1, spell.metadata()));
}
@Override
public void writeSpawnData(ByteBuf data){
data.writeInt(textureIndex);
@@ -0,0 +1,34 @@
package electroblob.wizardry.entity.projectile;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
public class EntityConjuredArrow extends EntityArrow {
public EntityConjuredArrow(World worldIn) {
super(worldIn);
}
public EntityConjuredArrow(World worldIn, double x, double y, double z) {
super(worldIn, x, y, z);
}
public EntityConjuredArrow(World worldIn, EntityLivingBase shooter) {
super(worldIn, shooter);
}
@Override
public void onUpdate() {
super.onUpdate();
if (this.timeInGround > 400) {
this.setDead();
}
}
@Override
protected ItemStack getArrowStack() {
return ItemStack.EMPTY;
}
}
@@ -0,0 +1,45 @@
package electroblob.wizardry.event;
import electroblob.wizardry.item.ItemArtefact;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.fml.common.eventhandler.Cancelable;
import net.minecraftforge.fml.common.eventhandler.Event;
/**
* SpellBindEvent is fired when a check happens for an ItemArtefact using {@link electroblob.wizardry.item.ItemArtefact#isArtefactActive(net.minecraft.entity.player.EntityPlayer, net.minecraft.item.Item)}
* <i>Fired on both sides.</i><br>
* <br>
* This event is {@link Cancelable}. <br>
* <br>
* This event has a result. {@link HasResult}. Set the result to Result.ALLOW to consider an artefact "active"<br>
* <br>
* This event is fired on the {@link MinecraftForge#EVENT_BUS}.
*
* @author WinDanesz
* @since Wizardry 4.3.10
*/
@Cancelable
@Event.HasResult
public class ArtefactCheckEvent extends PlayerEvent {
ItemArtefact artefact;
EntityPlayer player;
public ArtefactCheckEvent(EntityPlayer player, ItemArtefact artefact) {
super(player);
this.player = player;
this.artefact = artefact;
setResult(Result.DENY);
}
public ItemArtefact getArtefact() {
return artefact;
}
public EntityPlayer getPlayer() {
return player;
}
}
@@ -46,6 +46,10 @@ public final class WizardryBaublesIntegration {
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.RING, BaubleType.RING);
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.AMULET, BaubleType.AMULET);
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.CHARM, BaubleType.CHARM);
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.BELT, BaubleType.BELT);
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.BODY, BaubleType.BODY);
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.HEAD, BaubleType.HEAD);
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.TRINKET, BaubleType.TRINKET);
}
public static boolean enabled(){
@@ -10,6 +10,7 @@ import electroblob.wizardry.entity.living.ISummonedCreature;
import electroblob.wizardry.entity.projectile.EntityDart;
import electroblob.wizardry.entity.projectile.EntityForceOrb;
import electroblob.wizardry.entity.projectile.EntityIceShard;
import electroblob.wizardry.event.ArtefactCheckEvent;
import electroblob.wizardry.event.SpellCastEvent;
import electroblob.wizardry.event.SpellCastEvent.Source;
import electroblob.wizardry.integration.DamageSafetyChecker;
@@ -37,6 +38,7 @@ import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraftforge.common.BiomeDictionary;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.event.entity.living.LivingEvent;
@@ -88,7 +90,11 @@ public class ItemArtefact extends Item {
/** An artefact that improves attacking spells. Two of these can be active at any one time. */ RING(2),
/** An artefact that improves defensive spells. One of these can be active at any one time. */ AMULET(1),
/** An artefact that improves utility spells. One of these can be active at any one time. */ CHARM(1);
/** An artefact that improves utility spells. One of these can be active at any one time. */ CHARM(1),
/** Added for add-on artefacts. */ BELT(1),
/** Added for add-on artefacts. */ BODY(1),
/** Added for add-on artefacts. */ HEAD(1),
/** Added for add-on artefacts. */ TRINKET(1);
public final int maxAtOnce;
@@ -178,6 +184,13 @@ public class ItemArtefact extends Item {
if(!((ItemArtefact)artefact).enabled) return false; // Disabled in the config
ArtefactCheckEvent event = new ArtefactCheckEvent(player, (ItemArtefact) artefact);
if(MinecraftForge.EVENT_BUS.post(event)) return false;
if (event.getResult() == Event.Result.ALLOW) {
return true;
}
if(WizardryBaublesIntegration.enabled()){
return WizardryBaublesIntegration.isBaubleEquipped(player, artefact);
}else{
@@ -769,6 +782,7 @@ public class ItemArtefact extends Item {
&& Streams.stream(player.getHeldEquipment()).anyMatch(s -> s.getItem() instanceof ISpellCastingItem
&& ((ISpellCastingItem)s.getItem()).getCurrentSpell(s).getElement() == Element.NECROMANCY))){
event.getEntityLiving().addPotionEffect(new PotionEffect(WizardryPotions.curse_of_soulbinding, 400));
CurseOfSoulbinding.getSoulboundCreatures(WizardData.get(player)).add(event.getEntity().getUniqueID());
}
@@ -244,7 +244,7 @@ public class ItemScroll extends Item implements ISpellCastingItem, IWorkbenchIte
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Finish(Source.SCROLL, spell, user, modifiers, castingTick));
spell.finishCasting(user.world, user, Double.NaN, Double.NaN, Double.NaN, null, castingTick, modifiers);
if(user instanceof EntityPlayer){
if(user instanceof EntityPlayer && !((EntityPlayer)user).isCreative()){
((EntityPlayer)user).getCooldownTracker().setCooldown(this, spell.getCooldown());
}
}
@@ -1,6 +1,7 @@
package electroblob.wizardry.item;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.projectile.EntityConjuredArrow;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.util.InventoryUtils;
import net.minecraft.enchantment.EnchantmentHelper;
@@ -14,6 +15,7 @@ import net.minecraft.init.SoundEvents;
import net.minecraft.item.IItemPropertyGetter;
import net.minecraft.item.ItemArrow;
import net.minecraft.item.ItemBow;
import net.minecraft.item.ItemSpectralArrow;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.StatList;
import net.minecraft.util.*;
@@ -197,8 +199,7 @@ public class ItemSpectralBow extends ItemBow implements IConjuredItem {
if(!world.isRemote){
ItemArrow itemarrow = (ItemArrow)Items.ARROW;
EntityArrow entityarrow = itemarrow.createArrow(world, new ItemStack(itemarrow), entityplayer);
EntityConjuredArrow entityarrow = new EntityConjuredArrow(world, entityplayer);
entityarrow.shoot(entityplayer, entityplayer.rotationPitch, entityplayer.rotationYaw, 0.0F,
f * 3.0F, 1.0F);
@@ -226,9 +226,15 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
}
@Override
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean isHeld){
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean isHeldInMainhand){
boolean isHeld = isHeldInMainhand || entity instanceof EntityLivingBase && ItemStack.areItemStacksEqual(stack, ((EntityLivingBase) entity).getHeldItemOffhand());
WandHelper.decrementCooldowns(stack);
// If Wizardry.settings.wandsMustBeHeldToDecrementCooldown is false, the cooldowns will be decremented.
// If Wizardry.settings.wandsMustBeHeldToDecrementCooldown is true and isHeld is true, the cooldowns will also be decremented.
// If Wizardry.settings.wandsMustBeHeldToDecrementCooldown is true and isHeld is false, the cooldowns will not be decremented.
if (!Wizardry.settings.wandsMustBeHeldToDecrementCooldown || isHeld) {
WandHelper.decrementCooldowns(stack);
}
// Decrements wand damage (increases mana) every 1.5 seconds if it has a condenser upgrade
if(!world.isRemote && !this.isManaFull(stack) && world.getTotalWorldTime() % Constants.CONDENSER_TICK_INTERVAL == 0){
@@ -849,7 +855,12 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
int chargeDepleted = this.getManaCapacity(centre.getStack()) - this.getMana(centre.getStack());
int manaPerItem = Constants.MANA_PER_CRYSTAL;
// Not too pretty but allows addons implementing the IManaStoringItem interface to provide their mana amount for custom crystals,
// previously this was defaulted to the regular crystal's amount, allowing players to exploit it if a crystal was worth less mana than that.
int manaPerItem = crystals.getStack().getItem() instanceof IManaStoringItem ?
((IManaStoringItem) crystals.getStack().getItem()).getMana(crystals.getStack()) :
crystals.getStack().getItem() instanceof ItemCrystal ? Constants.MANA_PER_CRYSTAL : Constants.MANA_PER_SHARD;
if(crystals.getStack().getItem() == WizardryItems.crystal_shard) manaPerItem = Constants.MANA_PER_SHARD;
if(crystals.getStack().getItem() == WizardryItems.grand_crystal) manaPerItem = Constants.GRAND_CRYSTAL_MANA;
@@ -209,8 +209,8 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
@Override
public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack){
if(armorType == EntityEquipmentSlot.HEAD && isWearingFullSet(player, element, ArmourClass.BATTLEMAGE)
&& player.ticksExisted % 20 == 0){
if(armorType == EntityEquipmentSlot.HEAD && player.ticksExisted % 20 == 0
&& isWearingFullSet(player, element, ArmourClass.BATTLEMAGE) && doAllArmourPiecesHaveMana(player)){
player.addPotionEffect(new PotionEffect(WizardryPotions.ward, 219, 0, true, false));
}
}
@@ -237,7 +237,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
modifiers.set(WizardryItems.cooldown_upgrade, modifiers.get(WizardryItems.cooldown_upgrade) - armourClass.cooldownReduction, true);
// Full set bonuses
if(this.armorType == EntityEquipmentSlot.HEAD && isWearingFullSet(caster, element, armourClass)){
if(this.armorType == EntityEquipmentSlot.HEAD && isWearingFullSet(caster, element, armourClass) && doAllArmourPiecesHaveMana(caster)){
if(armourClass == ArmourClass.SAGE && spell.getElement() != this.element){
modifiers.set(SpellModifiers.COST, 1 - SAGE_OTHER_COST_REDUCTION, false);
}
@@ -334,7 +334,12 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
int chargeDepleted = this.getManaCapacity(centre.getStack()) - this.getMana(centre.getStack());
int manaPerItem = Constants.MANA_PER_CRYSTAL;
// Not too pretty but allows addons implementing the IManaStoringItem interface to provide their mana amount for custom crystals,
// previously this was defaulted to the regular crystal's amount, allowing players to exploit it if a crystal was worth less mana than that.
int manaPerItem = crystals.getStack().getItem() instanceof IManaStoringItem ?
((IManaStoringItem) crystals.getStack().getItem()).getMana(crystals.getStack()) :
crystals.getStack().getItem() instanceof ItemCrystal ? Constants.MANA_PER_CRYSTAL : Constants.MANA_PER_SHARD;
if(crystals.getStack().getItem() == WizardryItems.crystal_shard) manaPerItem = Constants.MANA_PER_SHARD;
if(crystals.getStack().getItem() == WizardryItems.grand_crystal) manaPerItem = Constants.GRAND_CRYSTAL_MANA;
@@ -363,7 +368,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
IAttributeInstance movementSpeed = event.getEntityLiving().getAttributeMap().getAttributeInstance(SharedMonsterAttributes.MOVEMENT_SPEED);
if(isWearingFullSet(event.getEntityLiving(), null, ArmourClass.WARLOCK)){
if(isWearingFullSet(event.getEntityLiving(), null, ArmourClass.WARLOCK) && doAllArmourPiecesHaveMana(event.getEntityLiving())){
// Only apply the modifier once (can't just check this is the helmet since it might not be the last piece equipped)
if(movementSpeed.getModifier(WARLOCK_SPEED_BOOST_UUID) == null){
movementSpeed.applyModifier(new AttributeModifier(WARLOCK_SPEED_BOOST_UUID, "Warlock set bonus", WARLOCK_SPEED_BOOST, Operations.MULTIPLY_FLAT));
@@ -433,7 +438,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
* @param armourClass The class to check, or null to accept any class as long as they are all the same.
* @return True if the entity is wearing a full set of the given element and class, false otherwise.
*/
private static boolean isWearingFullSet(EntityLivingBase entity, @Nullable Element element, @Nullable ArmourClass armourClass){
public static boolean isWearingFullSet(EntityLivingBase entity, @Nullable Element element, @Nullable ArmourClass armourClass){
ItemStack helmet = entity.getItemStackFromSlot(EntityEquipmentSlot.HEAD);
if(!(helmet.getItem() instanceof ItemWizardArmour)) return false;
Element e = element == null ? ((ItemWizardArmour)helmet.getItem()).element : element;
@@ -444,6 +449,16 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
&& ((ItemWizardArmour)entity.getItemStackFromSlot(s).getItem()).armourClass == ac);
}
/**
* Returns whether the given entity's armour pieces which implement {@link IManaStoringItem} has mana. Ignores pieces which doesn't have a mana storage.
* @param entity The entity to query.
* @return True if all armour pieces which implement {@link IManaStoringItem} has mana, false otherwise.
*/
public static boolean doAllArmourPiecesHaveMana(EntityLivingBase entity){
return Arrays.stream(InventoryUtils.ARMOUR_SLOTS).noneMatch(s -> entity.getItemStackFromSlot(s).getItem() instanceof IManaStoringItem
&& ((IManaStoringItem) entity.getItemStackFromSlot(s).getItem()).isManaEmpty(entity.getItemStackFromSlot(s)));
}
@SubscribeEvent
public static void onLivingSetAttackTargetEvent(LivingSetAttackTargetEvent event){
// Undo the mob detection penalty for wearing armour when invisible
@@ -10,6 +10,7 @@ import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.text.Style;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
@@ -36,7 +37,11 @@ public class ItemWizardHandbook extends Item {
@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand){
ItemStack stack = player.getHeldItem(hand);
player.openGui(Wizardry.instance, WizardryGuiHandler.WIZARD_HANDBOOK, world, 0, 0, 0);
if (Wizardry.settings.loadHandbook) {
player.openGui(Wizardry.instance, WizardryGuiHandler.WIZARD_HANDBOOK, world, 0, 0, 0);
} else if (!world.isRemote){
player.sendStatusMessage(new TextComponentTranslation("item." + Wizardry.MODID + ":wizard_handbook.disabled"), false);
}
return ActionResult.newResult(EnumActionResult.SUCCESS, stack);
}
@@ -20,14 +20,8 @@ public class PacketSpellProperties implements IMessageHandler<PacketSpellPropert
if(ctx.side.isClient()){
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> {
int spellId = message.firstId;
for(int i = 0; i <message.propertiesArray.length; i++){
Spell spell = Spell.byNetworkID(spellId);
SpellProperties props = message.propertiesArray[i];
spell.setPropertiesClient(props);
spellId++;
for(int i=0; i<message.propertiesArray.length; i++){
Spell.byNetworkID(i).setPropertiesClient(message.propertiesArray[i]);
}
});
}
@@ -38,31 +32,22 @@ public class PacketSpellProperties implements IMessageHandler<PacketSpellPropert
public static class Message implements IMessage {
private SpellProperties[] propertiesArray;
private int firstId;
private int count;
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
public Message(){}
public Message(int firstId, int count, SpellProperties... properties){
this.firstId = firstId;
this.count = count;
public Message(SpellProperties... properties){
this.propertiesArray = properties;
}
@Override
public void fromBytes(ByteBuf buf){
List<SpellProperties> propertiesList = new ArrayList<>();
firstId = buf.readInt();
count = buf.readInt();
int k = 0;
int j = firstId;
while(k < count){
SpellProperties props = new SpellProperties(Spell.byNetworkID(j), buf);
propertiesList.add(props);
k++;
j++;
List<SpellProperties> propertiesList = new ArrayList<>();
int i = 0;
while(buf.isReadable()){
propertiesList.add(new SpellProperties(Spell.byNetworkID(i++), buf));
}
propertiesArray = propertiesList.toArray(new SpellProperties[0]);
@@ -70,8 +55,6 @@ public class PacketSpellProperties implements IMessageHandler<PacketSpellPropert
@Override
public void toBytes(ByteBuf buf){
buf.writeInt(firstId);
buf.writeInt(count);
for(SpellProperties properties : propertiesArray) properties.write(buf);
}
}
@@ -1,6 +1,7 @@
package electroblob.wizardry.potion;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.item.ItemWizardArmour;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
@@ -45,8 +46,12 @@ public class CurseUndeath extends Curse {
} else {
itemstack.setItemDamage(itemstack.getItemDamage() + entitylivingbase.world.rand.nextInt(2));
if (itemstack.getItemDamage() >= itemstack.getMaxDamage()) {
entitylivingbase.renderBrokenItemStack(itemstack);
entitylivingbase.setItemStackToSlot(EntityEquipmentSlot.HEAD, ItemStack.EMPTY);
if (itemstack.getItem() instanceof ItemWizardArmour) {
entitylivingbase.setFire(8);
} else {
entitylivingbase.renderBrokenItemStack(itemstack);
entitylivingbase.setItemStackToSlot(EntityEquipmentSlot.HEAD, ItemStack.EMPTY);
}
}
}
}
@@ -59,10 +59,9 @@ public class PotionContainment extends PotionMagicEffect {
if(x != target.posX || y != target.posY || z != target.posZ)
{
target.addVelocity(0.15 * Math.signum(x - target.posX), 0.15 * Math.signum(y - target.posY), 0.15 * Math.signum(z - target.posZ));
EntityUtils.undoGravity(target);
if(target.world.isRemote){
EntityUtils.undoGravity(target);
target.addVelocity(0.15 * Math.signum(x - target.posX), 0.15 * Math.signum(y - target.posY), 0.15 * Math.signum(z - target.posZ));
target.world.playSound(target.posX, target.posY, target.posZ, WizardrySounds.ENTITY_FORCEFIELD_DEFLECT,
WizardrySounds.SPELLS, 0.3f, 1f, false);
}
@@ -0,0 +1,28 @@
package electroblob.wizardry.potion;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.util.EntityUtils;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber
public class PotionDiamondflesh extends PotionMagicEffect {
public PotionDiamondflesh(boolean isBadEffect, int liquidColour) {
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/diamondflesh.png"));
// This needs to be here because registerPotionAttributeModifier doesn't like it if the potion has no name yet.
this.setPotionName("potion." + Wizardry.MODID + ":ironflesh");
this.registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED,
"158a8af2-6db0-4340-a01c-a7b60d10ddf4", -0.1f, EntityUtils.Operations.MULTIPLY_CUMULATIVE);
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR_TOUGHNESS,
"a68d4532-5847-426c-9b03-d541b113cec2", 3.0f, EntityUtils.Operations.ADD);
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR,
"46a095be-82dd-43fd-8b67-13f51591eb8e", 4.0f, EntityUtils.Operations.ADD);
}
@Override
public boolean isReady(int duration, int amplifier) {
return true;
}
}
@@ -0,0 +1,28 @@
package electroblob.wizardry.potion;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.util.EntityUtils;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber
public class PotionIronflesh extends PotionMagicEffect {
public PotionIronflesh(boolean isBadEffect, int liquidColour) {
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/ironflesh.png"));
// This needs to be here because registerPotionAttributeModifier doesn't like it if the potion has no name yet.
this.setPotionName("potion." + Wizardry.MODID + ":ironflesh");
this.registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED,
"fe607d55-50e3-4f4f-a959-6571503f92f4", -0.1f, EntityUtils.Operations.MULTIPLY_CUMULATIVE);
this.registerPotionAttributeModifier(SharedMonsterAttributes.KNOCKBACK_RESISTANCE,
"6f78206e-8dd4-4d44-9792-d7a882111951", 0.3f, EntityUtils.Operations.ADD);
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR,
"e1adff1e-8510-4a09-96ed-ef677cad20c1", 4.0f, EntityUtils.Operations.ADD);
}
@Override
public boolean isReady(int duration, int amplifier) {
return true;
}
}
@@ -0,0 +1,28 @@
package electroblob.wizardry.potion;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.util.EntityUtils;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber
public class PotionOakflesh extends PotionMagicEffect {
public PotionOakflesh(boolean isBadEffect, int liquidColour) {
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/oakflesh.png"));
// This needs to be here because registerPotionAttributeModifier doesn't like it if the potion has no name yet.
this.setPotionName("potion." + Wizardry.MODID + ":ironflesh");
this.registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED,
"98b4ba66-7c50-4a4c-9f3f-40bcb37313b5", -0.1f, EntityUtils.Operations.MULTIPLY_CUMULATIVE);
this.registerPotionAttributeModifier(SharedMonsterAttributes.MAX_HEALTH,
"ed9d0423-60f4-4998-bd8d-dc7c33bd45b8", 0.2f, EntityUtils.Operations.MULTIPLY_FLAT);
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR,
"0b607c3f-fb14-43d7-96b5-1c1b6f6da242", 3.0f, EntityUtils.Operations.ADD);
}
@Override
public boolean isReady(int duration, int amplifier) {
return true;
}
}
@@ -359,7 +359,7 @@ public final class Spells {
registry.register(new GreaterHeal());
registry.register(new SpellConstruct<>("healing_aura", SpellActions.POINT_DOWN, EntityHealAura::new, false).addProperties(Spell.EFFECT_RADIUS, Spell.DAMAGE, Spell.HEALTH));
registry.register(new Forcefield());
registry.register(new SpellBuff("ironflesh", 0.4f, 0.5f, 0.6f, () -> MobEffects.RESISTANCE).soundValues(0.7f, 1.2f, 0.4f));
registry.register(new SpellBuff("ironflesh", 0.4f, 0.5f, 0.6f, () -> WizardryPotions.ironflesh).soundValues(0.7f, 1.2f, 0.4f));
registry.register(new Transience());
registry.register(new Meteor());
@@ -378,9 +378,10 @@ public final class Spells {
registry.register(new SpellMinion<>("silverfish_swarm", EntitySilverfishMinion::new).soundValues(1, 1.1f, 0.1f));
registry.register(new SpellConstructRanged<>("black_hole", EntityBlackHole::new, false).addProperties(Spell.EFFECT_RADIUS).soundValues(2, 0.7f, 0));
registry.register(new Shockwave());
registry.register(new SummonIronGolem());
registry.register(new SpellMinion<>("summon_iron_golem", EntitySpectralGolem::new).soundValues(1, 1.1f, 0.1f));
registry.register(new ArrowRain());
registry.register(new SpellBuff("diamondflesh", 0.1f, 0.7f, 1, () -> MobEffects.RESISTANCE).soundValues(0.7f, 1.2f, 0.4f));
registry.register(new SpellBuff("diamondflesh", 0.1f, 0.7f, 1, () -> WizardryPotions.diamondflesh).soundValues(0.7f, 1.2f, 0.4f));
registry.register(new SpellBuff("font_of_vitality", 1, 0.8f, 0.3f, () -> MobEffects.ABSORPTION, () -> MobEffects.REGENERATION).soundValues(0.7f, 1.2f, 0.4f));
// Wizardry 1.1 spells
@@ -398,7 +399,7 @@ public final class Spells {
registry.register(new PocketWorkbench());
registry.register(new ImbueWeapon());
registry.register(new InvigoratingPresence());
registry.register(new SpellBuff("oakflesh", 0.6f, 0.5f, 0.4f, () -> MobEffects.RESISTANCE).soundValues(0.7f, 1.2f, 0.4f));
registry.register(new SpellBuff("oakflesh", 0.6f, 0.5f, 0.4f, () -> WizardryPotions.oakflesh).soundValues(0.7f, 1.2f, 0.4f));
registry.register(new SpellProjectile<>("greater_fireball", EntityLargeMagicFireball::new).addProperties(Spell.DAMAGE, EntityLargeMagicFireball.EXPLOSION_POWER));//new GreaterFireball());
registry.register(new FlamingWeapon());
@@ -88,6 +88,7 @@ public class WizardryEntities {
registry.register(createEntry(EntitySpiritHorse.class, "spirit_horse", TrackingType.LIVING).egg(0x5464c6, 0xbcc2e8).build());
registry.register(createEntry(EntityPhoenix.class, "phoenix", TrackingType.LIVING).egg(0xff4900, 0xfde535).build());
registry.register(createEntry(EntityIceGiant.class, "ice_giant", TrackingType.LIVING).egg(0x5bacd9, 0xeffaff).build());
registry.register(createEntry(EntitySpectralGolem.class, "spectral_golem", TrackingType.LIVING).egg(0x5bacd9, 0xeffaff).build());
registry.register(createEntry(EntityMagicSlime.class, "magic_slime", TrackingType.LIVING).build());
registry.register(createEntry(EntityDecoy.class, "decoy", TrackingType.LIVING).build());
@@ -113,6 +114,7 @@ public class WizardryEntities {
registry.register(createEntry(EntityDart.class, "dart", TrackingType.PROJECTILE).build());
registry.register(createEntry(EntityIceLance.class, "ice_lance", TrackingType.PROJECTILE).build());
registry.register(createEntry(EntityFlamecatcherArrow.class, "flamecatcher_arrow", TrackingType.PROJECTILE).build());
registry.register(createEntry(EntityConjuredArrow.class, "conjured_arrow", TrackingType.PROJECTILE).build());
// Directionless projectiles
registry.register(createEntry(EntityFirebomb.class, "firebomb", TrackingType.PROJECTILE).build());
@@ -57,6 +57,9 @@ public final class WizardryPotions {
public static final Potion frost_step = placeholder();
public static final Potion mark_of_sacrifice = placeholder();
public static final Potion mirage = placeholder();
public static final Potion oakflesh = placeholder();
public static final Potion ironflesh = placeholder();
public static final Potion diamondflesh = placeholder();
/**
* Sets both the registry and unlocalised names of the given potion, then registers it with the given registry. Use
@@ -201,6 +204,10 @@ public final class WizardryPotions {
public void spawnCustomParticle(World world, double x, double y, double z){} // We only want the syncing
}.setBeneficial());
registerPotion(registry, "oakflesh", new PotionOakflesh(false, 0).setBeneficial());
registerPotion(registry, "ironflesh", new PotionIronflesh(false, 0).setBeneficial());
registerPotion(registry, "diamondflesh", new PotionDiamondflesh(false, 0).setBeneficial());
}
}
@@ -5,6 +5,7 @@ import electroblob.wizardry.constants.Constants;
import electroblob.wizardry.entity.living.ISpellCaster;
import electroblob.wizardry.event.SpellCastEvent;
import electroblob.wizardry.item.SpellActions;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.util.ParticleBuilder;
@@ -24,11 +25,14 @@ import javax.annotation.Nullable;
@Mod.EventBusSubscriber
public class EmpoweringPresence extends SpellAreaEffect {
/** The fraction by which potency is increased per level of the empowerment effect. */
public static final String POTENCY_PER_LEVEL = "potency_per_level";
public EmpoweringPresence(){
super("empowering_presence", SpellActions.POINT_UP, false);
this.alwaysSucceed(true);
this.targetAllies(true);
addProperties(EFFECT_DURATION, EFFECT_STRENGTH);
addProperties(EFFECT_DURATION, EFFECT_STRENGTH, POTENCY_PER_LEVEL);
}
@Override
@@ -62,7 +66,7 @@ public class EmpoweringPresence extends SpellAreaEffect {
if(event.getCaster() != null && event.getCaster().isPotionActive(WizardryPotions.empowerment)
&& !(event.getSpell() instanceof EmpoweringPresence)){ // Prevent exponential empowerment stacking!
float potency = 1 + Constants.EMPOWERMENT_POTENCY_PER_LEVEL
float potency = 1 + Spells.empowering_presence.getProperty(POTENCY_PER_LEVEL).floatValue()
* (event.getCaster().getActivePotionEffect(WizardryPotions.empowerment).getAmplifier() + 1);
event.getModifiers().set(SpellModifiers.POTENCY,
@@ -63,7 +63,7 @@ public class MarkSacrifice extends SpellRay {
PotionEffect effect = event.getEntityLiving().getActivePotionEffect(WizardryPotions.mark_of_sacrifice);
if(effect != null && event.getSource().isMagicDamage()){
event.setAmount(event.getAmount() * (1 + effect.getAmplifier()) * DAMAGE_INCREASE_PER_LEVEL);
event.setAmount(event.getAmount() * (1 + (1 + effect.getAmplifier()) * DAMAGE_INCREASE_PER_LEVEL));
event.getEntityLiving().removePotionEffect(WizardryPotions.mark_of_sacrifice);
}
}
@@ -30,9 +30,14 @@ public class Paralysis extends SpellRay {
* will end. */
private static final String CRITICAL_HEALTH = "critical_health";
/**
* Multiplier for affecting players
*/
private static final String PLAYER_EFFECT_DURATION_MULTIPLIER = "player_effect_duration_multiplier";
public Paralysis(){
super("paralysis", SpellActions.POINT, false);
addProperties(DAMAGE, EFFECT_DURATION, CRITICAL_HEALTH);
addProperties(DAMAGE, EFFECT_DURATION, CRITICAL_HEALTH, PLAYER_EFFECT_DURATION_MULTIPLIER);
}
@Override
@@ -57,9 +62,10 @@ public class Paralysis extends SpellRay {
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY));
}
float durationMultiplier = target instanceof EntityPlayer ? modifiers.get(PLAYER_EFFECT_DURATION_MULTIPLIER) : 1.0f;
((EntityLivingBase)target).addPotionEffect(new PotionEffect(WizardryPotions.paralysis,
(int)(getProperty(EFFECT_DURATION).floatValue() * modifiers.get(WizardryItems.duration_upgrade)), 0));
(int)(getProperty(EFFECT_DURATION).floatValue() * durationMultiplier * modifiers.get(WizardryItems.duration_upgrade)), 0));
}
return false;
@@ -189,7 +189,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
private static int nextSpellId = 0;
/** The spell's integer ID, mainly used for networking. */
// This was added after I learnt the hard way why you can't assume Forge's registry IDs are sequential...
private final int id;
private int id;
/**
* This constructor should be called from any subclasses, either feeding in the constants directly or through their
@@ -225,6 +225,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
this.icon = new ResourceLocation(modID, "textures/spells/" + name + ".png");
this.sounds = createSounds();
this.id = nextSpellId++;
Wizardry.logger.debug("Registering spell " + this.unlocalisedName +" with networkID " + id);
this.items(WizardryItems.spell_book, WizardryItems.scroll);
this.npcSelector((e, o) -> false);
}
@@ -319,24 +320,8 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
// To avoid sending extra data unnecessarily, the spell properties are sent in order of spell ID
List<Spell> spells = new ArrayList<>(registry.getValuesCollection());
spells.sort(Comparator.comparingInt(Spell::networkID));
SpellProperties[] propertiesArray = spells.stream().map(s -> s.properties).toArray(SpellProperties[]::new);
// splitting the packet into batches of 100 spells
int i = 0;
while (i < propertiesArray.length) {
List<SpellProperties> propertiesList = new ArrayList<>();
int first = i;
int batchCounter = 0;
for (int currentIndex = i; currentIndex < propertiesArray.length && batchCounter < 100; currentIndex++) {
propertiesList.add(propertiesArray[currentIndex]);
batchCounter++;
i++;
}
SpellProperties[] currentArray = propertiesList.toArray(new SpellProperties[0]);
PacketSpellProperties.Message currentPacket = new PacketSpellProperties.Message(first, currentArray.length, currentArray);
WizardryPacketHandler.net.sendTo(currentPacket, player);
}
WizardryPacketHandler.net.sendTo(new PacketSpellProperties.Message(spells.stream()
.map(s -> s.properties).toArray(SpellProperties[]::new)), player);
}
private static void clearProperties(){
@@ -576,6 +561,11 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
return id;
}
/** Sets the networkID of this spell. Do not call this or it will cause all packets to fail. */
public void setId(int id) {
this.id = id;
}
/** Returns the {@code ResourceLocation} for this spell's icon. */
public final ResourceLocation getIcon(){
return icon;
@@ -125,7 +125,8 @@ public class SpellBuff extends Spell {
@Override
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){
// Wizards can only cast a buff spell if they don't already have its effects.
if(caster.getActivePotionMap().keySet().containsAll(potionSet)) return false;
// Some buff spells doesn't add any potion effects, those are ignored by this check
if(!potionSet.isEmpty() && caster.getActivePotionMap().keySet().containsAll(potionSet)) return false;
// Only return on the server side or the client probably won't spawn particles
if(!this.applyEffects(caster, modifiers) && !world.isRemote) return false;
if(world.isRemote) this.spawnParticles(world, caster, modifiers);
@@ -1,51 +0,0 @@
package electroblob.wizardry.spell;
import electroblob.wizardry.item.SpellActions;
import electroblob.wizardry.util.BlockUtils;
import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.ParticleBuilder.Type;
import electroblob.wizardry.util.SpellModifiers;
import net.minecraft.entity.monster.EntityIronGolem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class SummonIronGolem extends Spell {
public SummonIronGolem(){
super("summon_iron_golem", SpellActions.SUMMON, false);
addProperties(SpellMinion.SUMMON_RADIUS);
soundValues(1, 1.1f, 0.2f);
}
@Override
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
BlockPos pos = BlockUtils.findNearbyFloorSpace(caster, getProperty(SpellMinion.SUMMON_RADIUS).intValue(),
getProperty(SpellMinion.SUMMON_RADIUS).intValue());
if(pos == null) return false;
if(!world.isRemote){
EntityIronGolem golem = new EntityIronGolem(world);
golem.setPosition(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5);
golem.setPlayerCreated(true);
world.spawnEntity(golem);
}else{
for(int i=0; i<10; i++){
double x = pos.getX() + world.rand.nextDouble() * 2 - 1;
double y = pos.getY() + 0.5 + world.rand.nextDouble();
double z = pos.getZ() + world.rand.nextDouble() * 2 - 1;
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).clr(0.6f, 0.6f, 1).spawn(world);
}
}
this.playSound(world, caster, ticksInUse, -1, modifiers);
return true;
}
}
@@ -0,0 +1,32 @@
package electroblob.wizardry.util;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.spell.Spell;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
/**
* Helper class which ensures that all spellpack spell networkIDs are distributed in alphabetical order. Introducing this was necessary as mods (especially with
* (load-after) dependencies were not always registering their spells in the exact same order. This is definitely
*/
public class SpellNetworkIDSorter {
public static void init() {
//reorder network IDs based on addon modids. This is necessary as modloading order doesn't seem to be guaranteed to match between various servers and clients
Wizardry.logger.debug("Reordering all spell NetworkIDs based on addon modid alphabetical order");
// the first available ID after all default spells
int nextSpellId = (int) Spell.getAllSpells().stream().filter(spell -> spell.getRegistryName().getNamespace().equals(Wizardry.MODID)).count() + 1;
List<Spell> addonSpells = Spell.getAllSpells().stream().filter(spell -> !spell.getRegistryName().getNamespace().equals(Wizardry.MODID)).collect(Collectors.toList());
// sorting spells
addonSpells.sort(Comparator.comparing((Spell o) -> o.getRegistryName().toString()));
for (Spell spell : addonSpells) {
Wizardry.logger.debug("Updating networkID of spell " + spell.getRegistryName().toString() + " from " + spell.networkID() + " to " + nextSpellId);
spell.setId(nextSpellId++);
}
}
}
@@ -83,6 +83,7 @@ item.ebwizardry\:arcane_tome.desc=Upgrades any %1$s wand with sufficient progres
item.ebwizardry\:wizard_handbook.name=The Wizard's Handbook
item.ebwizardry\:wizard_handbook.author=by %1$s
item.ebwizardry\:wizard_handbook.desc=Your not-so-pocket-sized guide to the arcane arts! A must-have for any aspiring wizard who seeks to learn the secrets of magic.\n\nRight-click while holding this book to read it.
item.ebwizardry\:wizard_handbook.disabled=This item was disabled in the config!
item.ebwizardry\:wand.generic=wand
@@ -402,6 +403,10 @@ item.ebwizardry\:generic.disabled=This item has been disabled in the config
item.ebwizardry\:ring.generic.desc=Equip this ring in the Baubles inventory or by placing it on your hotbar. Up to 2 rings may be equipped at once.
item.ebwizardry\:amulet.generic.desc=Equip this amulet in the Baubles inventory or by placing it on your hotbar. Only one amulet may be equipped at a time.
item.ebwizardry\:charm.generic.desc=Equip this charm in the Baubles inventory or by placing it on your hotbar. Only one charm may be equipped at a time.
item.ebwizardry\:belt.generic.desc=Equip this belt in the Baubles inventory or by placing it on your hotbar. Only one belt may be equipped at a time.
item.ebwizardry\:body.generic.desc=Equip this body item in the Baubles inventory or by placing it on your hotbar. Only one body item may be equipped at a time.
item.ebwizardry\:trinket.generic.desc=Equip this trinket in the Baubles inventory or by placing it on your hotbar. Only one trinklet may be equipped at a time.
item.ebwizardry\:head.generic.desc=Equip this headgear in the Baubles inventory or by placing it on your hotbar. Only one headgear may be equipped at a time.
item.ebwizardry\:ring_condensing.name=Ring of Condensing
item.ebwizardry\:ring_condensing.desc=Slowly regenerates mana for all wands on your hotbar
@@ -438,7 +443,7 @@ item.ebwizardry\:ring_hammer.desc=Lightning hammers can be picked up and thrown
item.ebwizardry\:ring_stormcloud.name=Lokenzen's Ring
item.ebwizardry\:ring_stormcloud.desc=Stormcloud moves towards targets and lasts longer with every strike
item.ebwizardry\:ring_soulbinding.name=Soulwalker's Ring
item.ebwizardry\:ring_soulbinding.desc=Creatures damaged by necromancy spells become soulbound to you
item.ebwizardry\:ring_soulbinding.desc=Creatures damaged by necromancy spells become soulbound to you for 20 seconds
item.ebwizardry\:ring_leeching.name=Ring of Leeching
item.ebwizardry\:ring_leeching.desc=All necromancy attacks have a 30%% chance to trigger a life drain effect
item.ebwizardry\:ring_necromancy_melee.name=Ring of Necrotic Touch
@@ -732,6 +737,7 @@ entity.ebwizardry\:evil_wizard.name=Wizard
entity.ebwizardry\:decoy.name=Decoy
entity.ebwizardry\:vex_minion.name=Vex
entity.ebwizardry\:remnant.name=Remnant
entity.ebwizardry\:spectral_golem.name=Spectral Golem
entity.ebwizardry\:magic_missile.name=Magic
entity.ebwizardry\:arc.name=Magic
@@ -758,6 +764,7 @@ entity.ebwizardry\:smoke_bomb.name=Magic
entity.ebwizardry\:ice_spike.name=Magic
entity.ebwizardry\:combustion_rune.name=Magic
entity.ebwizardry\:flamecatcher_arrow.name=Magic
entity.ebwizardry\:conjured_arrow.name=Magic
entity.ebwizardry\:black_hole.name=Black Hole
entity.ebwizardry\:shield.name=Shield
@@ -1075,7 +1082,7 @@ spell.ebwizardry\:stormcloud=Stormcloud
spell.ebwizardry\:summon_blaze=Summon Blaze
spell.ebwizardry\:summon_ice_giant=Summon Ice Giant
spell.ebwizardry\:summon_ice_wraith=Summon Ice Wraith
spell.ebwizardry\:summon_iron_golem=Summon Iron Golem
spell.ebwizardry\:summon_iron_golem=Summon Spectral Golem
spell.ebwizardry\:summon_lightning_wraith=Summon Lightning Wraith
spell.ebwizardry\:summon_phoenix=Summon Phoenix
spell.ebwizardry\:summon_shadow_wraith=Summon Shadow Wraith
@@ -1203,7 +1210,7 @@ spell.ebwizardry\:intimidate.desc=Emits an intimidating growl which causes nearb
spell.ebwizardry\:invigorating_presence.desc=Grants the caster and all nearby allies increased strength for 45 seconds.
spell.ebwizardry\:invisibility.desc=Makes the caster invisible for 30 seconds.
spell.ebwizardry\:invoke_weather.desc=Changes the weather in the world.
spell.ebwizardry\:ironflesh.desc=Greatly improves the caster's damage resistance for 30 seconds.
spell.ebwizardry\:ironflesh.desc=Greatly improves the caster's armor and knockback resistance for 30 seconds.
spell.ebwizardry\:leap.desc=Causes the caster to jump upwards several blocks and slightly forward.
spell.ebwizardry\:levitation.desc=Raises the caster upwards while the use item button is held. Will also negate fall damage if used before hitting the ground.
spell.ebwizardry\:life_drain.desc=Creates a stream of withering energy in the direction you are pointing which drains the life of the target and uses it to gradually regenerate your health.
@@ -1226,7 +1233,7 @@ spell.ebwizardry\:mine.desc=Breaks the block the caster is looking at. Potency w
spell.ebwizardry\:mirage.desc=Creates an illusion where the caster appears to be a few blocks away from their actual position, blinking around every few seconds. The illusion lasts for 20 seconds.
spell.ebwizardry\:muffle.desc=Silences any sounds made by the caster for 30 seconds. When muffled, mobs can only detect you when looking towards you.
spell.ebwizardry\:none.desc=To get a spell book with the /give command, use id\: /give [player] ebwizardry\:spell_book 1 [spell id] (if you found this book in a chest, some other mod has messed things up).
spell.ebwizardry\:oakflesh.desc=Improves the caster's damage resistance for 30 seconds.
spell.ebwizardry\:oakflesh.desc=Slightly improves the caster's vitality and damage resistance for 30 seconds.
spell.ebwizardry\:paralysis.desc=Delivers a powerful lightning bolt that paralyses targets for 5 seconds. Paralysed creatures cannot move and will still take damage - but too much will snap the creature out of paralysis.
spell.ebwizardry\:permafrost.desc=Spreads a layer of slippery ice on the ground where you are pointing, the extreme cold of which causes creatures to slowly take damage.
spell.ebwizardry\:petrify.desc=Turns the target to stone until broken out, with a chance for it to break out when it is dark. The target cannot move or do anything while petrified but is also impervious to all damage.
@@ -1400,6 +1407,9 @@ potion.ebwizardry\:containment=Containment
potion.ebwizardry\:frost_step=Frost Step
potion.ebwizardry\:mark_of_sacrifice=Mark of Sacrifice
potion.ebwizardry\:mirage=Mirage
potion.ebwizardry\:oakflesh=Oakflesh
potion.ebwizardry\:ironflesh=Ironflesh
potion.ebwizardry\:diamondflesh=Diamondflesh
enchantment.ebwizardry\:magic_sword=Imbuement
enchantment.ebwizardry\:magic_bow=Imbuement
@@ -1524,6 +1534,20 @@ config.ebwizardry.slow_time_affects_players=Slow Time Affects Players
config.ebwizardry.slow_time_affects_players.tooltip=Whether players are slowed when another nearby player uses the slow time spell. If this is disabled, mobs and projectiles will still be affected but players will move at normal speed.
config.ebwizardry.bonemeal_grows_crystal_flowers=Bonemeal Grows Crystal Flowers
config.ebwizardry.bonemeal_grows_crystal_flowers.tooltip=Whether using bonemeal on grass blocks has a chance to grow crystal flowers.
config.ebwizardry.wands_must_be_held_to_decrement_cooldown=Wands Must Be Held To Decrement Cooldown
config.ebwizardry.wands_must_be_held_to_decrement_cooldown.tooltip=Whether wands only decrement their cooldowns if a player holds them.
config.ebwizardry.cooldown_reduction_per_level=Cooldown Reduction Per Level
config.ebwizardry.cooldown_reduction_per_level.tooltip=The fraction by which cooldowns are reduced for each level of cooldown upgrade.
config.ebwizardry.potency_increase_per_tier=Potency Increase Per Tier
config.ebwizardry.potency_increase_per_tier.tooltip=The fraction by which potency is increased for each tier of matching wand. May cause extreme lag with high values!
config.ebwizardry.duration_increase_per_level=Duration Increase Per Level
config.ebwizardry.duration_increase_per_level.tooltip=The fraction by which spell duration is increased for each level of duration upgrade.
config.ebwizardry.range_increase_per_level=Range Increase Per Level
config.ebwizardry.range_increase_per_level.tooltip=The fraction by which spell range is increased for each level of range upgrade. May cause extreme lag with high values!
config.ebwizardry.blast_increase_per_level=Blast Increase Per Level
config.ebwizardry.blast_increase_per_level.tooltip=The fraction by which spell blast is increased for each level of blast upgrade. May cause extreme lag with high values!
config.ebwizardry.frost_slowness_increase_per_level=Frost Slowness Increase Per Level
config.ebwizardry.frost_slowness_increase_per_level.tooltip=The fraction by which movement speed is reduced per level of frost effect.
config.ebwizardry.category.difficulty=Difficulty Settings
config.ebwizardry.category.difficulty.tooltip=Configure wizardry's difficulty
@@ -363,6 +363,7 @@
"spell.zombie_apocalypse.start": {"category": "spells", "sounds": ["ebwizardry:dark_aura_start"]},
"spell.zombie_apocalypse.loop": {"category": "spells", "sounds": ["ebwizardry:dark_aura_loop"]},
"spell.zombie_apocalypse.end": {"category": "spells", "sounds": ["ebwizardry:dark_aura_end"]},
"spell.mirage": {"category": "spells", "sounds": ["ebwizardry:buff"]},
"forfeit.burn_self": {"category": "spells", "sounds": ["fire/ignite"]},
"forfeit.fireball": {"category": "spells", "sounds": ["mob/ghast/fireball4"]},
@@ -409,4 +410,4 @@
"forfeit.weaken_self": {"category": "spells", "sounds": ["mob/guardian/curse"]},
"forfeit.jam_self": {"category": "spells", "sounds": ["ebwizardry:effect1", "ebwizardry:effect2"]},
"forfeit.curse_self": {"category": "spells", "sounds": ["mob/guardian/curse"]}
}
}
@@ -17,7 +17,7 @@
"chargeup": 25,
"cooldown": 300,
"base_properties": {
"resistance_duration": 600,
"resistance_strength": 2
"diamondflesh_duration": 600,
"diamondflesh_strength": 0
}
}
@@ -14,11 +14,12 @@
"element": "healing",
"type": "buff",
"cost": 30,
"chargeup": 0,
"chargeup": 20,
"cooldown": 60,
"base_properties": {
"effect_radius": 5,
"effect_duration": 900,
"effect_strength": 1
"effect_strength": 0,
"potency_per_level": 0.15
}
}
@@ -17,7 +17,7 @@
"chargeup": 15,
"cooldown": 100,
"base_properties": {
"resistance_duration": 600,
"resistance_strength": 1
"ironflesh_duration": 600,
"ironflesh_strength": 0
}
}
@@ -17,7 +17,7 @@
"chargeup": 0,
"cooldown": 50,
"base_properties": {
"resistance_duration": 600,
"resistance_strength": 0
"oakflesh_duration": 600,
"oakflesh_strength": 0
}
}
@@ -20,6 +20,7 @@
"range": 10,
"damage": 4,
"effect_duration": 100,
"critical_health": 4
"critical_health": 4,
"player_effect_duration_multiplier": 0.5
}
}
@@ -17,6 +17,8 @@
"chargeup": 20,
"cooldown": 400,
"base_properties": {
"minion_lifetime": 600,
"minion_count": 1,
"summon_radius": 2
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

+1 -1
View File
@@ -2,7 +2,7 @@
{
"modid" : "ebwizardry",
"name" : "Electroblob's Wizardry",
"version" : "4.3.6",
"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",