Compare commits
90 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 275f514810 | |||
| 7cf09e76f8 | |||
| 61080134fd | |||
| 563bed3b25 | |||
| 75740c388f | |||
| 5d96f4d700 | |||
| df8fd21c0b | |||
| d6b64b3576 | |||
| 22c00c47ff | |||
| 6d0e65c2b0 | |||
| 0a6fd452c1 | |||
| 28a8a4ff2a | |||
| 71c09cf16d | |||
| 794085660e | |||
| 3d89186308 | |||
| a0bd7b64d7 | |||
| 4c633c98ff | |||
| 45ff70c207 | |||
| 0328f41564 | |||
| 9ab4684aef | |||
| e64cf9a6af | |||
| f13f220564 | |||
| 311b5750df | |||
| e54aee332d | |||
| e4bf09f15a | |||
| aa166814ea | |||
| d37ab6072f | |||
| ba83cb7985 | |||
| 3052e56d03 | |||
| b682740751 | |||
| 38429cb697 | |||
| dc7b6790b8 | |||
| 7a247df3e1 | |||
| de2087c0e8 | |||
| f5da195605 | |||
| 6cd6411c25 | |||
| 40e77728ad | |||
| d50ff5729f | |||
| 76b4f2f72f | |||
| a608375433 | |||
| c3f8ba245d | |||
| 34b3fe93bb | |||
| 996ec9a7f7 | |||
| 2b38ca9a89 | |||
| 67788a2bd8 | |||
| 58fcaa8af2 | |||
| 24e89c8b8a | |||
| 1293b89905 | |||
| 807fc61541 | |||
| 9741c751b3 | |||
| d3003ae473 | |||
| 9fde24f341 | |||
| 452eb17b5f | |||
| 36963aac30 | |||
| f161cdfe7c | |||
| 455c5a5e07 | |||
| 9852f61d0f | |||
| a2c8cde4c4 | |||
| 497d28eafd | |||
| f3f3377c4d | |||
| 4c81c61644 | |||
| 31a6ab6db0 | |||
| 69f2aedef7 | |||
| e8818a4db5 | |||
| 470a7e82bc | |||
| 6439c233f1 | |||
| c931d42d62 | |||
| 5b497e107a | |||
| 324094f418 | |||
| 9ade6442b2 | |||
| ffea49bc40 | |||
| 2b89a890d0 | |||
| 3a67388ff3 | |||
| 3468bbb073 | |||
| 963178c609 | |||
| cfdb049368 | |||
| 058d83fd00 | |||
| c7ccc37dca | |||
| 74345d0c3b | |||
| 907b94c74f | |||
| 2c6b397be6 | |||
| eddcb2402d | |||
| 0301f3c300 | |||
| 7a8cfb73cd | |||
| c7c6f964bf | |||
| 91df7cfd72 | |||
| 0ed9ee64c4 | |||
| f82d2871d5 | |||
| 01cea3df06 | |||
| 591cfb5857 |
@@ -7,10 +7,10 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting.
|
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]
|
Minecraft version: 1.12.2 [change as necessary]
|
||||||
Wizardry version: 4.2.2 [change as necessary]
|
Wizardry version: 4.2.9 [change as necessary]
|
||||||
Environment: Singleplayer/LAN game/Server [delete 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.]
|
Issue details: [describe what you were doing when the issue occurred, what went wrong, what you expected to happen, etc.]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting.
|
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]
|
Minecraft versions: [if this suggestion only applies to some versions, list them here]
|
||||||
|
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting.
|
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]
|
Minecraft version: 1.12.2 [change as necessary]
|
||||||
Wizardry version: 4.2.2 [change as necessary]
|
Wizardry version: 4.2.9 [change as necessary]
|
||||||
|
|
||||||
Question details: [explain your question here]
|
Question details: [explain your question here]
|
||||||
|
|
||||||
|
|||||||
+12
-7
@@ -1,7 +1,7 @@
|
|||||||
# Credits
|
# Credits
|
||||||
|
|
||||||
Electroblob's Wizardry
|
Electroblob's Wizardry
|
||||||
Version 4.2.3
|
Version 4.2.9
|
||||||
For Minecraft 1.12.2
|
For Minecraft 1.12.2
|
||||||
|
|
||||||
Designed, coded and textured by Electroblob
|
Designed, coded and textured by Electroblob
|
||||||
@@ -21,15 +21,20 @@ In addition, I'd like to thank the following individuals for their contributions
|
|||||||
- Tora-B
|
- Tora-B
|
||||||
- Avatair
|
- Avatair
|
||||||
- Aeronica
|
- Aeronica
|
||||||
|
- UltraHex
|
||||||
|
- Azim-Palmer
|
||||||
|
- raoulvdberge
|
||||||
|
|
||||||
#### Translations
|
#### Translations
|
||||||
|
|
||||||
- Spanish and Mexican Spanish: MadWrist
|
- Spanish: MadWrist, Alsentar
|
||||||
- Russian: VilagVil, kellixon
|
- Mexican Spanish: MadWrist
|
||||||
- French: Hahdrim
|
- Russian: VilagVil, kellixon, bigenergy
|
||||||
- Brazilian Portuguese: lorrampi
|
- French: Hahdrim
|
||||||
- Chinese: ZHENGLOC, dragon-evol
|
- Brazilian Portuguese: lorrampi
|
||||||
- Korean: shejery, rewi_wire
|
- Chinese: ZHENGLOC, dragon-evol, Hokorizero, TUsama
|
||||||
|
- Korean: shejery, rewi_wire
|
||||||
- Polish: Trozuu
|
- Polish: Trozuu
|
||||||
|
- German: BirdyDragon
|
||||||
|
|
||||||
Lightning ray sound effect from OhhWowProductions
|
Lightning ray sound effect from OhhWowProductions
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting.
|
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting.
|
||||||
|
|
||||||
Minecraft version: 1.12.2 [change as necessary]
|
Minecraft version: 1.12.2 [change as necessary]
|
||||||
Wizardry version: 4.1.4 [change as necessary]
|
Wizardry version: 4.2.9 [change as necessary]
|
||||||
Environment: Singleplayer/LAN game/Server [delete 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.]
|
Issue details: [describe what you were doing when the issue occurred, what went wrong, what you expected to happen, etc.]
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ apply plugin: 'net.minecraftforge.gradle.forge'
|
|||||||
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
|
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
|
||||||
|
|
||||||
|
|
||||||
version = "4.2.4" // There, it matches semver, happy now?
|
version = "4.2.9" // There, it matches semver, happy now?
|
||||||
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||||
archivesBaseName = "ElectroblobsWizardry"
|
archivesBaseName = "ElectroblobsWizardry"
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import electroblob.wizardry.spell.Spell;
|
|||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.SoundCategory;
|
import net.minecraft.util.SoundCategory;
|
||||||
@@ -99,9 +100,9 @@ public class CommonProxy {
|
|||||||
return ((ItemSpectralBow)WizardryItems.spectral_bow).getDefaultDurabilityForDisplay(stack);
|
return ((ItemSpectralBow)WizardryItems.spectral_bow).getDefaultDurabilityForDisplay(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Like {@link CommonProxy#addMultiLineDescription(List, String, Style)}, but style defaults to light grey. */
|
/** Like {@link CommonProxy#addMultiLineDescription(List, String, Style, Object...)}, but style defaults to light grey. */
|
||||||
public void addMultiLineDescription(List<String> tooltip, String key){
|
public void addMultiLineDescription(List<String> tooltip, String key, Object... args){
|
||||||
this.addMultiLineDescription(tooltip, key, new Style().setColor(TextFormatting.GRAY));
|
this.addMultiLineDescription(tooltip, key, new Style().setColor(TextFormatting.GRAY), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -112,7 +113,7 @@ public class CommonProxy {
|
|||||||
* @param key The translation key for the description
|
* @param key The translation key for the description
|
||||||
* @param style A style to apply
|
* @param style A style to apply
|
||||||
*/
|
*/
|
||||||
public void addMultiLineDescription(List<String> tooltip, String key, Style style){}
|
public void addMultiLineDescription(List<String> tooltip, String key, Style style, Object... args){}
|
||||||
|
|
||||||
// SECTION Packet Handlers
|
// SECTION Packet Handlers
|
||||||
// ===============================================================================================================
|
// ===============================================================================================================
|
||||||
@@ -139,8 +140,6 @@ public class CommonProxy {
|
|||||||
|
|
||||||
public void handleAdvancementSyncPacket(PacketSyncAdvancements.Message message){}
|
public void handleAdvancementSyncPacket(PacketSyncAdvancements.Message message){}
|
||||||
|
|
||||||
public void handleEndSlowTimePacket(PacketEndSlowTime.Message message){}
|
|
||||||
|
|
||||||
public void handleResurrectionPacket(PacketResurrection.Message message){}
|
public void handleResurrectionPacket(PacketResurrection.Message message){}
|
||||||
|
|
||||||
public void handlePossessionPacket(PacketPossession.Message message){}
|
public void handlePossessionPacket(PacketPossession.Message message){}
|
||||||
@@ -238,6 +237,16 @@ public class CommonProxy {
|
|||||||
+ "of sound events, but the given array contained less than 3 sound events!");
|
+ "of sound events, but the given array contained less than 3 sound events!");
|
||||||
playSpellSoundLoop(world, x, y, z, spell, sounds[0], sounds[1], sounds[2], category, volume, pitch, duration);
|
playSpellSoundLoop(world, x, y, z, spell, sounds[0], sounds[1], sounds[2], category, volume, pitch, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Starts the first-person blink overlay effect for the specified player. */
|
||||||
|
public void playBlinkEffect(EntityPlayer player){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the client-side screen shake effect for the specified player.
|
||||||
|
* @param player The player whose screen is to be shaken
|
||||||
|
* @param intensity The amplitude of the shaking (around 10 looks about right)
|
||||||
|
*/
|
||||||
|
public void shakeScreen(EntityPlayer player, float intensity){}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the client side world using Minecraft.getMinecraft().world. <b>Only to be called client side!</b> Returns
|
* Gets the client side world using Minecraft.getMinecraft().world. <b>Only to be called client side!</b> Returns
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ import electroblob.wizardry.spell.Spell;
|
|||||||
import electroblob.wizardry.util.AllyDesignationSystem.FriendlyFire;
|
import electroblob.wizardry.util.AllyDesignationSystem.FriendlyFire;
|
||||||
import electroblob.wizardry.util.MagicDamage;
|
import electroblob.wizardry.util.MagicDamage;
|
||||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.EntityList;
|
import net.minecraft.entity.EntityList;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.text.translation.I18n;
|
import net.minecraft.util.text.translation.I18n;
|
||||||
import net.minecraftforge.common.config.ConfigCategory;
|
import net.minecraftforge.common.config.ConfigCategory;
|
||||||
@@ -16,6 +18,8 @@ import net.minecraftforge.common.config.Property;
|
|||||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
|
import net.minecraftforge.oredict.OreDictionary;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -125,7 +129,7 @@ public final class Settings {
|
|||||||
new ResourceLocation(Wizardry.MODID, "shrine_6"),
|
new ResourceLocation(Wizardry.MODID, "shrine_6"),
|
||||||
new ResourceLocation(Wizardry.MODID, "shrine_7")};
|
new ResourceLocation(Wizardry.MODID, "shrine_7")};
|
||||||
/** <b>[Server-only]</b> List of solid blocks (usually trees) which are ignored by the structure generators. */
|
/** <b>[Server-only]</b> List of solid blocks (usually trees) which are ignored by the structure generators. */
|
||||||
public ResourceLocation[] treeBlocks = toResourceLocations(DEFAULT_TREE_BLOCKS);
|
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. */
|
/** <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 evilWizardChance = 0.2;
|
||||||
/** <b>[Server-only]</b> List of dimension ids in which to generate crystal ore. */
|
/** <b>[Server-only]</b> List of dimension ids in which to generate crystal ore. */
|
||||||
@@ -169,6 +173,8 @@ public final class Settings {
|
|||||||
/** <b>[Server-only]</b> Whether to replace Minecraft's distance-based fall damage calculation with an equivalent,
|
/** <b>[Server-only]</b> Whether to replace Minecraft's distance-based fall damage calculation with an equivalent,
|
||||||
* velocity-based one. */
|
* velocity-based one. */
|
||||||
public boolean replaceVanillaFallDamage = true;
|
public boolean replaceVanillaFallDamage = 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> List of registry names of entities which summoned creatures are allowed to attack, in addition
|
* <b>[Server-only]</b> List of registry names of entities which summoned creatures are allowed to attack, in addition
|
||||||
* to the defaults.
|
* to the defaults.
|
||||||
@@ -188,15 +194,15 @@ public final class Settings {
|
|||||||
* <b>[Server-only]</b> List of registry names of items which cannot be smelted by the pocket furnace spell, in
|
* <b>[Server-only]</b> List of registry names of items which cannot be smelted by the pocket furnace spell, in
|
||||||
* addition to armour, tools and weapons.
|
* addition to armour, tools and weapons.
|
||||||
*/
|
*/
|
||||||
public ResourceLocation[] pocketFurnaceItemBlacklist = toResourceLocations("cobblestone", "netherrack");
|
public Pair<ResourceLocation, Short>[] pocketFurnaceItemBlacklist = parseItemMetaStrings("cobblestone", "netherrack");
|
||||||
/** <b>[Server-only]</b> List of registry names of blocks which can be detected by the divination spell. */
|
/** <b>[Server-only]</b> List of registry names of blocks which can be detected by the divination spell. */
|
||||||
public ResourceLocation[] divinationOreWhitelist = {};
|
public Pair<ResourceLocation, Short>[] divinationOreWhitelist = parseItemMetaStrings(); // That works I guess
|
||||||
/** <b>[Server-only]</b> List of registry names of items which count as swords for imbuement spells. */
|
/** <b>[Server-only]</b> List of registry names of items which count as swords for imbuement spells. */
|
||||||
public ResourceLocation[] swordItemWhitelist = {};
|
public Pair<ResourceLocation, Short>[] swordItemWhitelist = parseItemMetaStrings();
|
||||||
/** <b>[Server-only]</b> List of registry names of items which count as bows for imbuement spells. */
|
/** <b>[Server-only]</b> List of registry names of items which count as bows for imbuement spells. */
|
||||||
public ResourceLocation[] bowItemWhitelist = {};
|
public Pair<ResourceLocation, Short>[] bowItemWhitelist = parseItemMetaStrings();
|
||||||
/** <b>[Server-only]</b> Map of items to values which wizard trades may use as currency. */
|
/** <b>[Server-only]</b> Map of items to values which wizard trades may use as currency. */
|
||||||
public Map<ResourceLocation, Integer> currencyItems = new HashMap<>();
|
public Map<Pair<ResourceLocation, Short>, Integer> currencyItems = new HashMap<>();
|
||||||
/** <b>[Server-only]</b> Global damage scaling factor for all player magic damage. */
|
/** <b>[Server-only]</b> Global damage scaling factor for all player magic damage. */
|
||||||
public double playerDamageScale = 1.0;
|
public double playerDamageScale = 1.0;
|
||||||
/** <b>[Server-only]</b> Global damage scaling factor for all npc magic damage. */
|
/** <b>[Server-only]</b> Global damage scaling factor for all npc magic damage. */
|
||||||
@@ -431,7 +437,7 @@ public final class Settings {
|
|||||||
|
|
||||||
Property property;
|
Property property;
|
||||||
|
|
||||||
for(Spell spell : Spell.getSpells(Spell.allSpells)){
|
for(Spell spell : Spell.getAllSpells()){
|
||||||
property = config.get(SPELLS_CATEGORY, spell.getRegistryName().toString(), true,
|
property = config.get(SPELLS_CATEGORY, spell.getRegistryName().toString(), true,
|
||||||
I18n.translateToLocal("spell." + spell.getUnlocalisedName() + ".desc"));
|
I18n.translateToLocal("spell." + spell.getUnlocalisedName() + ".desc"));
|
||||||
// Uses the same config key as the spell name, because - well, that's what it's called!
|
// Uses the same config key as the spell name, because - well, that's what it's called!
|
||||||
@@ -542,6 +548,13 @@ public final class Settings {
|
|||||||
slowTimeAffectsPlayers = property.getBoolean();
|
slowTimeAffectsPlayers = property.getBoolean();
|
||||||
propOrder.add(property.getName());
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
|
property = config.get(GAMEPLAY_CATEGORY, "bonemealGrowsCrystalFlowers", true,
|
||||||
|
"Whether using bonemeal on grass blocks has a chance to grow crystal flowers.");
|
||||||
|
property.setLanguageKey("config." + Wizardry.MODID + ".bonemeal_grows_crystal_flowers");
|
||||||
|
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||||
|
bonemealGrowsCrystalFlowers = property.getBoolean();
|
||||||
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
property = config.get(GAMEPLAY_CATEGORY, "mobLootTableWhitelist", new String[0], "Whitelist for loot tables to inject additional mob drops (as specified in loot_tables/entities/mob_additions.json) into. Wizardry makes a best guess as to which loot tables belong to hostile mobs, but this may not always be correct or appropriate; add loot table locations (not entity IDs) to this list to manually include them.");
|
property = config.get(GAMEPLAY_CATEGORY, "mobLootTableWhitelist", new String[0], "Whitelist for loot tables to inject additional mob drops (as specified in loot_tables/entities/mob_additions.json) into. Wizardry makes a best guess as to which loot tables belong to hostile mobs, but this may not always be correct or appropriate; add loot table locations (not entity IDs) to this list to manually include them.");
|
||||||
property.setLanguageKey("config." + Wizardry.MODID + ".mob_loot_table_whitelist");
|
property.setLanguageKey("config." + Wizardry.MODID + ".mob_loot_table_whitelist");
|
||||||
property.setRequiresMcRestart(true);
|
property.setRequiresMcRestart(true);
|
||||||
@@ -643,41 +656,42 @@ public final class Settings {
|
|||||||
"List of registry names of blocks or items which cannot be smelted by the pocket furnace spell, in addition to armour, tools and weapons. Block/item names are not case sensitive. For mod items, prefix with the mod ID (e.g. " + Wizardry.MODID + ":crystal_ore).");
|
"List of registry names of blocks or items which cannot be smelted by the pocket furnace spell, in addition to armour, tools and weapons. Block/item names are not case sensitive. For mod items, prefix with the mod ID (e.g. " + Wizardry.MODID + ":crystal_ore).");
|
||||||
property.setLanguageKey("config." + Wizardry.MODID + ".pocket_furnace_item_blacklist");
|
property.setLanguageKey("config." + Wizardry.MODID + ".pocket_furnace_item_blacklist");
|
||||||
property.setRequiresWorldRestart(true);
|
property.setRequiresWorldRestart(true);
|
||||||
pocketFurnaceItemBlacklist = getResourceLocationList(property);
|
pocketFurnaceItemBlacklist = parseItemMetaStrings(property.getStringList());
|
||||||
propOrder.add(property.getName());
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
property = config.get(GAMEPLAY_CATEGORY, "divinationOreWhitelist", new String[0], "List of registry names of ore blocks which can be detected by the divination spell. Block names are not case sensitive. For mod blocks, prefix with the mod ID (e.g. " + Wizardry.MODID + ":crystal_ore).");
|
property = config.get(GAMEPLAY_CATEGORY, "divinationOreWhitelist", new String[0], "List of registry names of ore blocks which can be detected by the divination spell. Block names are not case sensitive. For mod blocks, prefix with the mod ID (e.g. " + Wizardry.MODID + ":crystal_ore).");
|
||||||
property.setLanguageKey("config." + Wizardry.MODID + ".divination_ore_whitelist");
|
property.setLanguageKey("config." + Wizardry.MODID + ".divination_ore_whitelist");
|
||||||
property.setRequiresWorldRestart(true);
|
property.setRequiresWorldRestart(true);
|
||||||
divinationOreWhitelist = getResourceLocationList(property);
|
divinationOreWhitelist = parseItemMetaStrings(property.getStringList());
|
||||||
propOrder.add(property.getName());
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
property = config.get(GAMEPLAY_CATEGORY, "swordItemWhitelist", new String[0], "List of registry names of items which should count as swords for imbuement spells. Most swords should work automatically, but those that don't can be added manually here. Item names are not case sensitive. For mod items, prefix with the mod ID (e.g. tconstruct:broadsword).");
|
property = config.get(GAMEPLAY_CATEGORY, "swordItemWhitelist", new String[0], "List of registry names of items which should count as swords for imbuement spells. Most swords should work automatically, but those that don't can be added manually here. Item names are not case sensitive. For mod items, prefix with the mod ID (e.g. tconstruct:broadsword).");
|
||||||
property.setLanguageKey("config." + Wizardry.MODID + ".sword_item_whitelist");
|
property.setLanguageKey("config." + Wizardry.MODID + ".sword_item_whitelist");
|
||||||
property.setRequiresWorldRestart(true);
|
property.setRequiresWorldRestart(true);
|
||||||
swordItemWhitelist = getResourceLocationList(property);
|
swordItemWhitelist = parseItemMetaStrings(property.getStringList());
|
||||||
propOrder.add(property.getName());
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
property = config.get(GAMEPLAY_CATEGORY, "bowItemWhitelist", new String[0], "List of registry names of items which should count as bows for imbuement spells. Most bows should work automatically, but those that don't can be added manually here. Item names are not case sensitive. For mod items, prefix with the mod ID (e.g. tconstruct:shortbow).");
|
property = config.get(GAMEPLAY_CATEGORY, "bowItemWhitelist", new String[0], "List of registry names of items which should count as bows for imbuement spells. Most bows should work automatically, but those that don't can be added manually here. Item names are not case sensitive. For mod items, prefix with the mod ID (e.g. tconstruct:shortbow).");
|
||||||
property.setLanguageKey("config." + Wizardry.MODID + ".bow_item_whitelist");
|
property.setLanguageKey("config." + Wizardry.MODID + ".bow_item_whitelist");
|
||||||
property.setRequiresWorldRestart(true);
|
property.setRequiresWorldRestart(true);
|
||||||
bowItemWhitelist = getResourceLocationList(property);
|
bowItemWhitelist = parseItemMetaStrings(property.getStringList());
|
||||||
propOrder.add(property.getName());
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
property = config.get(GAMEPLAY_CATEGORY, "currencyItems", new String[]{"gold_ingot 3", "emerald 6"}, "List of registry names of items which wizard trades can use as currency (in the first slot; the second slot is unaffected). Each entry in this list should consist of an item registry name, followed by a single space, then an integer which defines the 'value' of the item. Higher values mean fewer of that currency item are required for a given trade.",
|
property = config.get(GAMEPLAY_CATEGORY, "currencyItems", new String[]{"gold_ingot 3", "emerald 6"}, "List of registry names of items which wizard trades can use as currency (in the first slot; the second slot is unaffected). Each entry in this list should consist of an item registry name, followed by a single space, then an integer which defines the 'value' of the item. Higher values mean fewer of that currency item are required for a given trade.",
|
||||||
Pattern.compile("[A-Za-z:_]+ [0-9]+"));
|
Pattern.compile("[A-Za-z0-9:_]+ [0-9]+"));
|
||||||
property.setLanguageKey("config." + Wizardry.MODID + ".currency_items");
|
property.setLanguageKey("config." + Wizardry.MODID + ".currency_items");
|
||||||
property.setRequiresWorldRestart(true);
|
property.setRequiresWorldRestart(true);
|
||||||
propOrder.add(property.getName());
|
propOrder.add(property.getName());
|
||||||
currencyItems = new HashMap<>();
|
currencyItems = new HashMap<>();
|
||||||
for(String string : property.getStringList()){
|
for(String string : property.getStringList()){
|
||||||
|
string = string.toLowerCase(Locale.ROOT).trim();
|
||||||
String[] args = string.split(" ");
|
String[] args = string.split(" ");
|
||||||
if(args.length != 2){
|
if(args.length != 2){
|
||||||
Wizardry.logger.warn("Invalid entry in currency items: {}", string);
|
Wizardry.logger.warn("Invalid entry in currency items: {}", string);
|
||||||
continue; // Ignore invalid entries, the pattern above should ensure this never happens
|
continue; // Ignore invalid entries, the pattern above should ensure this never happens
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
currencyItems.put(new ResourceLocation(args[0]), Integer.parseInt(args[1]));
|
currencyItems.put(parseItemMetaString(args[0]), Integer.parseInt(args[1]));
|
||||||
}catch(NumberFormatException e){
|
}catch(NumberFormatException e){
|
||||||
Wizardry.logger.warn("Invalid integer in currency items: {}", args[1]);
|
Wizardry.logger.warn("Invalid integer in currency items: {}", args[1]);
|
||||||
}
|
}
|
||||||
@@ -782,7 +796,7 @@ public final class Settings {
|
|||||||
property = config.get(GAMEPLAY_CATEGORY, "treeBlocks", DEFAULT_TREE_BLOCKS, "List of registry names of blocks which can be overwritten by wizardry's structure generators, affecting both fast and fancy structure generation. Most tree blocks and other foliage should work automatically, but those that don't can be added manually here. Block names are not case sensitive. For mod blocks, prefix with the mod ID (e.g. dynamictrees:oakbranch).");
|
property = config.get(GAMEPLAY_CATEGORY, "treeBlocks", DEFAULT_TREE_BLOCKS, "List of registry names of blocks which can be overwritten by wizardry's structure generators, affecting both fast and fancy structure generation. Most tree blocks and other foliage should work automatically, but those that don't can be added manually here. Block names are not case sensitive. For mod blocks, prefix with the mod ID (e.g. dynamictrees:oakbranch).");
|
||||||
property.setLanguageKey("config." + Wizardry.MODID + ".tree_blocks");
|
property.setLanguageKey("config." + Wizardry.MODID + ".tree_blocks");
|
||||||
property.setRequiresWorldRestart(true);
|
property.setRequiresWorldRestart(true);
|
||||||
treeBlocks = getResourceLocationList(property);
|
treeBlocks = parseItemMetaStrings(property.getStringList());
|
||||||
propOrder.add(property.getName());
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
property = config.get(WORLDGEN_CATEGORY, "oreDimensions", new int[]{0}, "List of dimension ids in which crystal ore will generate. Note that removing the overworld (id 0) from this list will make the mod VERY difficult to play!");
|
property = config.get(WORLDGEN_CATEGORY, "oreDimensions", new int[]{0}, "List of dimension ids in which crystal ore will generate. Note that removing the overworld (id 0) from this list will make the mod VERY difficult to play!");
|
||||||
@@ -1073,4 +1087,45 @@ public final class Settings {
|
|||||||
public static ResourceLocation[] toResourceLocations(String... strings){
|
public static ResourceLocation[] toResourceLocations(String... strings){
|
||||||
return Arrays.stream(strings).map(s -> new ResourceLocation(s.toLowerCase(Locale.ROOT).trim())).toArray(ResourceLocation[]::new);
|
return Arrays.stream(strings).map(s -> new ResourceLocation(s.toLowerCase(Locale.ROOT).trim())).toArray(ResourceLocation[]::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Applies {@link Settings#parseItemMetaString(String)} to each input string and returns and array of the resulting
|
||||||
|
* {@link Pair}s. */
|
||||||
|
@SuppressWarnings("unchecked") // Shut up java
|
||||||
|
public static Pair<ResourceLocation, Short>[] parseItemMetaStrings(String... strings){
|
||||||
|
return Arrays.stream(strings).map(Settings::parseItemMetaString).toArray(Pair[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Parses the given input string as an item of the form {@code id:metadata} and returns the resulting
|
||||||
|
* {@link ResourceLocation} ID and metadata value as a {@link Pair} object. */
|
||||||
|
public static Pair<ResourceLocation, Short> parseItemMetaString(String string){
|
||||||
|
|
||||||
|
string = string.toLowerCase(Locale.ROOT).trim();
|
||||||
|
|
||||||
|
String[] itemArgs = string.split(":");
|
||||||
|
String item;
|
||||||
|
short meta;
|
||||||
|
|
||||||
|
try {
|
||||||
|
meta = Short.parseShort(itemArgs[itemArgs.length-1]);
|
||||||
|
item = String.join(":", Arrays.copyOfRange(itemArgs, 0, itemArgs.length-1));
|
||||||
|
}catch(NumberFormatException e){ // If no metadata is specified
|
||||||
|
meta = OreDictionary.WILDCARD_VALUE;
|
||||||
|
item = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Pair.of(new ResourceLocation(item), meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean containsMetaBlock(Pair<ResourceLocation, Short>[] array, IBlockState block){
|
||||||
|
return containsMetaThing(array, block.getBlock().getRegistryName(), (short)block.getBlock().getMetaFromState(block));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean containsMetaItem(Pair<ResourceLocation, Short>[] array, ItemStack stack){
|
||||||
|
return containsMetaThing(array, stack.getItem().getRegistryName(), (short)stack.getMetadata());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean containsMetaThing(Pair<ResourceLocation, Short>[] array, ResourceLocation id, short metadata){
|
||||||
|
return Arrays.asList(array).contains(Pair.of(id, metadata)) || Arrays.asList(array).contains(Pair.of(id, OreDictionary.WILDCARD_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import net.minecraftforge.fml.common.registry.GameRegistry;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <i>"Electroblob's Wizardry adds an RPG-like system of spells to Minecraft, with the aim of being as playable as
|
* <i>"Electroblob's Wizardry adds an RPG-like system of spells to Minecraft, with the aim of being as playable as
|
||||||
@@ -63,7 +64,7 @@ public class Wizardry {
|
|||||||
* 1.x.x represents Minecraft 1.7.x versions, 2.x.x represents Minecraft 1.10.x versions, 3.x.x represents Minecraft
|
* 1.x.x represents Minecraft 1.7.x versions, 2.x.x represents Minecraft 1.10.x versions, 3.x.x represents Minecraft
|
||||||
* 1.11.x versions, and so on.
|
* 1.11.x versions, and so on.
|
||||||
*/
|
*/
|
||||||
public static final String VERSION = "4.2.4";
|
public static final String VERSION = "4.2.9";
|
||||||
|
|
||||||
// IDEA: Triggering of inbuilt Forge events in relevant places?
|
// IDEA: Triggering of inbuilt Forge events in relevant places?
|
||||||
// IDEA: Abstract the vanilla particles behind the particle builder
|
// IDEA: Abstract the vanilla particles behind the particle builder
|
||||||
@@ -88,6 +89,8 @@ public class Wizardry {
|
|||||||
* this folder contains the main config file and the global spell properties folder, if used. */
|
* this folder contains the main config file and the global spell properties folder, if used. */
|
||||||
public static File configDirectory;
|
public static File configDirectory;
|
||||||
|
|
||||||
|
public static boolean tisTheSeason;
|
||||||
|
|
||||||
// The instance of wizardry that Forge uses.
|
// The instance of wizardry that Forge uses.
|
||||||
@Instance(Wizardry.MODID)
|
@Instance(Wizardry.MODID)
|
||||||
public static Wizardry instance;
|
public static Wizardry instance;
|
||||||
@@ -106,6 +109,10 @@ public class Wizardry {
|
|||||||
configDirectory = new File(event.getModConfigurationDirectory(), Wizardry.MODID);
|
configDirectory = new File(event.getModConfigurationDirectory(), Wizardry.MODID);
|
||||||
settings.initConfig(event);
|
settings.initConfig(event);
|
||||||
|
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
tisTheSeason = calendar.get(Calendar.MONTH) + 1 == 12 && calendar.get(Calendar.DAY_OF_MONTH) >= 24
|
||||||
|
&& calendar.get(Calendar.DAY_OF_MONTH) <= 26;
|
||||||
|
|
||||||
// Capabilities
|
// Capabilities
|
||||||
WizardData.register();
|
WizardData.register();
|
||||||
DispenserCastingData.register();
|
DispenserCastingData.register();
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ import net.minecraft.util.ResourceLocation;
|
|||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.text.TextComponentTranslation;
|
import net.minecraft.util.text.TextComponentTranslation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.WorldServer;
|
||||||
|
import net.minecraft.world.storage.loot.LootContext;
|
||||||
|
import net.minecraft.world.storage.loot.LootTable;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.common.util.FakePlayer;
|
import net.minecraftforge.common.util.FakePlayer;
|
||||||
import net.minecraftforge.event.entity.PlaySoundAtEntityEvent;
|
import net.minecraftforge.event.entity.PlaySoundAtEntityEvent;
|
||||||
@@ -46,6 +49,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|||||||
import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent;
|
import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General-purpose event handler for things that don't fit anywhere else or groups of related behaviours that are better
|
* General-purpose event handler for things that don't fit anywhere else or groups of related behaviours that are better
|
||||||
@@ -286,7 +290,7 @@ public final class WizardryEventHandler {
|
|||||||
EntityLivingBase attacker = (EntityLivingBase)event.getSource().getTrueSource();
|
EntityLivingBase attacker = (EntityLivingBase)event.getSource().getTrueSource();
|
||||||
|
|
||||||
// Players can only ever attack with their main hand, so this is the right method to use here.
|
// Players can only ever attack with their main hand, so this is the right method to use here.
|
||||||
if(!attacker.getHeldItemMainhand().isEmpty() && ImbueWeapon.isSword(attacker.getHeldItemMainhand().getItem())){
|
if(!attacker.getHeldItemMainhand().isEmpty() && ImbueWeapon.isSword(attacker.getHeldItemMainhand())){
|
||||||
|
|
||||||
int level = EnchantmentHelper.getEnchantmentLevel(WizardryEnchantments.flaming_weapon,
|
int level = EnchantmentHelper.getEnchantmentLevel(WizardryEnchantments.flaming_weapon,
|
||||||
attacker.getHeldItemMainhand());
|
attacker.getHeldItemMainhand());
|
||||||
@@ -343,18 +347,21 @@ public final class WizardryEventHandler {
|
|||||||
|
|
||||||
Spell spell = ((ISpellCaster)event.getEntity()).getContinuousSpell();
|
Spell spell = ((ISpellCaster)event.getEntity()).getContinuousSpell();
|
||||||
SpellModifiers modifiers = ((ISpellCaster)event.getEntity()).getModifiers();
|
SpellModifiers modifiers = ((ISpellCaster)event.getEntity()).getModifiers();
|
||||||
|
int count = ((ISpellCaster)event.getEntity()).getSpellCounter();
|
||||||
|
|
||||||
if(spell != null && spell != Spells.none){ // IntelliJ is wrong, do NOT remove the null check!
|
if(spell != null && spell != Spells.none){ // IntelliJ is wrong, do NOT remove the null check!
|
||||||
|
|
||||||
if(!MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Tick(SpellCastEvent.Source.NPC, spell, event.getEntityLiving(),
|
if(!MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Tick(SpellCastEvent.Source.NPC, spell, event.getEntityLiving(),
|
||||||
modifiers, 0))){
|
modifiers, count))){
|
||||||
|
|
||||||
spell.cast(event.getEntity().world, (EntityLiving)event.getEntity(), EnumHand.MAIN_HAND, 0,
|
spell.cast(event.getEntity().world, (EntityLiving)event.getEntity(), EnumHand.MAIN_HAND, count,
|
||||||
// TODO: This implementation of modifiers relies on them being accessible client-side.
|
// TODO: This implementation of modifiers relies on them being accessible client-side.
|
||||||
// Right now that doesn't matter because NPCs don't use modifiers, but they might in future
|
// Right now that doesn't matter because NPCs don't use modifiers, but they might in future
|
||||||
((EntityLiving)event.getEntity()).getAttackTarget(), modifiers);
|
((EntityLiving)event.getEntity()).getAttackTarget(), modifiers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
((ISpellCaster)event.getEntity()).setSpellCounter(count + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -366,6 +373,22 @@ public final class WizardryEventHandler {
|
|||||||
|
|
||||||
EntityPlayer player = (EntityPlayer)event.getSource().getTrueSource();
|
EntityPlayer player = (EntityPlayer)event.getSource().getTrueSource();
|
||||||
|
|
||||||
|
// Compatibility with "Lycanites Mobs" -it uses custom loot drop logic which can't be hooked, given the
|
||||||
|
// number of mobs that spawn as Lycanites when this mod is active it would massively nerf the wizard drops
|
||||||
|
// if we didn't handle this
|
||||||
|
if(event.getEntity().getClass().getCanonicalName().contains("lycanitesmobs"))
|
||||||
|
{
|
||||||
|
WorldServer world = (WorldServer)event.getEntity().getEntityWorld();
|
||||||
|
LootTable table = world.getLootTableManager().getLootTableFromLocation(new ResourceLocation(Wizardry.MODID, "entities/mob_additions"));
|
||||||
|
|
||||||
|
LootContext ctx = new LootContext.Builder(world).withPlayer(player).build();
|
||||||
|
List<ItemStack> stacks = table.generateLootForPools(world.rand, ctx);
|
||||||
|
|
||||||
|
for(ItemStack stack : stacks) {
|
||||||
|
event.getEntity().entityDropItem(stack, 0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for(ItemStack stack : WizardryUtilities.getPrioritisedHotbarAndOffhand(player)){
|
for(ItemStack stack : WizardryUtilities.getPrioritisedHotbarAndOffhand(player)){
|
||||||
|
|
||||||
if(stack.getItem() instanceof IManaStoringItem && !((IManaStoringItem)stack.getItem()).isManaFull(stack)
|
if(stack.getItem() instanceof IManaStoringItem && !((IManaStoringItem)stack.getItem()).isManaFull(stack)
|
||||||
@@ -444,7 +467,8 @@ public final class WizardryEventHandler {
|
|||||||
// Wizardry.logger.info("Replaced fall distance {} with effective distance {} based on entity velocity", event.getDistance(), y);
|
// Wizardry.logger.info("Replaced fall distance {} with effective distance {} based on entity velocity", event.getDistance(), y);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
event.setDistance((float)y);
|
// Don't let it increase fall damage beyond vanilla values
|
||||||
|
if(y < event.getDistance()) event.setDistance((float)y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package electroblob.wizardry.block;
|
package electroblob.wizardry.block;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.registry.WizardryBlocks;
|
import electroblob.wizardry.registry.WizardryBlocks;
|
||||||
import electroblob.wizardry.util.ParticleBuilder;
|
import electroblob.wizardry.util.ParticleBuilder;
|
||||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||||
@@ -56,7 +57,7 @@ public class BlockCrystalFlower extends BlockBush {
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onBonemealEvent(BonemealEvent event){
|
public static void onBonemealEvent(BonemealEvent event){
|
||||||
// Grows crystal flowers when bonemeal is used on grass
|
// Grows crystal flowers when bonemeal is used on grass
|
||||||
if(event.getBlock().getBlock() == Blocks.GRASS){
|
if(Wizardry.settings.bonemealGrowsCrystalFlowers && event.getBlock().getBlock() == Blocks.GRASS){
|
||||||
|
|
||||||
BlockPos pos = event.getPos().add(event.getWorld().rand.nextInt(8) - event.getWorld().rand.nextInt(8),
|
BlockPos pos = event.getPos().add(event.getWorld().rand.nextInt(8) - event.getWorld().rand.nextInt(8),
|
||||||
event.getWorld().rand.nextInt(4) - event.getWorld().rand.nextInt(4),
|
event.getWorld().rand.nextInt(4) - event.getWorld().rand.nextInt(4),
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import net.minecraft.item.Item;
|
|||||||
import net.minecraft.potion.PotionEffect;
|
import net.minecraft.potion.PotionEffect;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.BlockRenderLayer;
|
import net.minecraft.util.BlockRenderLayer;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.EnumBlockRenderType;
|
import net.minecraft.util.EnumBlockRenderType;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
@@ -54,21 +55,24 @@ public class BlockSnare extends Block implements ITileEntityProvider {
|
|||||||
@Override
|
@Override
|
||||||
public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entity){
|
public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entity){
|
||||||
|
|
||||||
if(!world.isRemote && entity instanceof EntityLivingBase){
|
if(entity instanceof EntityLivingBase){
|
||||||
|
|
||||||
if(world.getTileEntity(pos) instanceof TileEntityPlayerSave){
|
if(world.getTileEntity(pos) instanceof TileEntityPlayerSave){
|
||||||
|
|
||||||
TileEntityPlayerSave tileentity = (TileEntityPlayerSave)world.getTileEntity(pos);
|
TileEntityPlayerSave tileentity = (TileEntityPlayerSave)world.getTileEntity(pos);
|
||||||
|
|
||||||
if(AllyDesignationSystem.isValidTarget(tileentity.getCaster(), entity)){
|
if(AllyDesignationSystem.isValidTarget(tileentity.getCaster(), entity)){
|
||||||
|
|
||||||
entity.attackEntityFrom(MagicDamage.causeDirectMagicDamage(tileentity.getCaster(), DamageType.MAGIC),
|
DamageSource source = tileentity.getCaster() == null ? DamageSource.CACTUS
|
||||||
Spells.snare.getProperty(Spell.DAMAGE).floatValue());
|
: MagicDamage.causeDirectMagicDamage(tileentity.getCaster(), DamageType.MAGIC);
|
||||||
|
|
||||||
|
entity.attackEntityFrom(source, Spells.snare.getProperty(Spell.DAMAGE).floatValue());
|
||||||
|
|
||||||
((EntityLivingBase)entity).addPotionEffect(new PotionEffect(MobEffects.SLOWNESS,
|
((EntityLivingBase)entity).addPotionEffect(new PotionEffect(MobEffects.SLOWNESS,
|
||||||
Spells.snare.getProperty(Spell.EFFECT_DURATION).intValue(),
|
Spells.snare.getProperty(Spell.EFFECT_DURATION).intValue(),
|
||||||
Spells.snare.getProperty(Spell.EFFECT_STRENGTH).intValue()));
|
Spells.snare.getProperty(Spell.EFFECT_STRENGTH).intValue()));
|
||||||
|
|
||||||
world.destroyBlock(pos, false);
|
if(!world.isRemote) world.destroyBlock(pos, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,9 +137,11 @@ public class BlockThorns extends BlockBush implements ITileEntityProvider {
|
|||||||
TileEntity tileentity = world.getTileEntity(pos);
|
TileEntity tileentity = world.getTileEntity(pos);
|
||||||
|
|
||||||
if(tileentity instanceof TileEntityPlayerSaveTimed){
|
if(tileentity instanceof TileEntityPlayerSaveTimed){
|
||||||
if(AllyDesignationSystem.isValidTarget(((TileEntityPlayerSaveTimed)tileentity).getCaster(), target)){
|
|
||||||
source = MagicDamage.causeDirectMagicDamage(((TileEntityPlayerSaveTimed)tileentity).getCaster(),
|
EntityLivingBase caster = ((TileEntityPlayerSaveTimed)tileentity).getCaster();
|
||||||
MagicDamage.DamageType.MAGIC);
|
|
||||||
|
if(caster != null && AllyDesignationSystem.isValidTarget(caster, target)){
|
||||||
|
source = MagicDamage.causeDirectMagicDamage(caster, MagicDamage.DamageType.MAGIC);
|
||||||
}else{
|
}else{
|
||||||
return false; // Don't attack or slow allies of the caster
|
return false; // Don't attack or slow allies of the caster
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,7 +141,8 @@ public class BlockTransportationStone extends Block {
|
|||||||
if(locations.isEmpty()) locations.add(here);
|
if(locations.isEmpty()) locations.add(here);
|
||||||
else{
|
else{
|
||||||
locations.remove(here); // Prevents duplicates
|
locations.remove(here); // Prevents duplicates
|
||||||
locations.set(Math.max(locations.size() - 1, 0), here);
|
if(locations.isEmpty()) locations.add(here);
|
||||||
|
else locations.set(Math.max(locations.size() - 1, 0), here);
|
||||||
}
|
}
|
||||||
if(!world.isRemote) player.sendStatusMessage(new TextComponentTranslation("tile." + Wizardry.MODID + ":transportation_stone.confirm", Spells.transportation.getNameForTranslationFormatted()), true);
|
if(!world.isRemote) player.sendStatusMessage(new TextComponentTranslation("tile." + Wizardry.MODID + ":transportation_stone.confirm", Spells.transportation.getNameForTranslationFormatted()), true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ import electroblob.wizardry.item.ItemScroll;
|
|||||||
import electroblob.wizardry.item.ItemSpellBook;
|
import electroblob.wizardry.item.ItemSpellBook;
|
||||||
import electroblob.wizardry.item.ItemWand;
|
import electroblob.wizardry.item.ItemWand;
|
||||||
import electroblob.wizardry.packet.*;
|
import electroblob.wizardry.packet.*;
|
||||||
import electroblob.wizardry.potion.PotionSlowTime;
|
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.spell.*;
|
import electroblob.wizardry.spell.*;
|
||||||
@@ -107,7 +106,7 @@ public class ClientProxy extends CommonProxy {
|
|||||||
// Armour Model
|
// Armour Model
|
||||||
public static final ModelBiped WIZARD_ARMOUR_MODEL = new ModelWizardArmour(0.75f);
|
public static final ModelBiped WIZARD_ARMOUR_MODEL = new ModelWizardArmour(0.75f);
|
||||||
|
|
||||||
/** The wrap width for standard multi-line descriptions (see {@link ClientProxy#addMultiLineDescription(List, String, Style)}). */
|
/** The wrap width for standard multi-line descriptions (see {@link ClientProxy#addMultiLineDescription(List, String, Style, Object...)}). */
|
||||||
private static final int TOOLTIP_WRAP_WIDTH = 140;
|
private static final int TOOLTIP_WRAP_WIDTH = 140;
|
||||||
|
|
||||||
// SECTION Registry
|
// SECTION Registry
|
||||||
@@ -190,6 +189,16 @@ public class ClientProxy extends CommonProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void playBlinkEffect(EntityPlayer player){
|
||||||
|
if(Minecraft.getMinecraft().player == player) WizardryClientEventHandler.playBlinkEffect();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shakeScreen(EntityPlayer player, float intensity){
|
||||||
|
if(Minecraft.getMinecraft().player == player) WizardryClientEventHandler.shakeScreen(intensity);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> getSpellHUDSkins(){
|
public Set<String> getSpellHUDSkins(){
|
||||||
return GuiSpellDisplay.getSkinKeys();
|
return GuiSpellDisplay.getSkinKeys();
|
||||||
@@ -282,8 +291,8 @@ public class ClientProxy extends CommonProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addMultiLineDescription(List<String> tooltip, String key, Style style){
|
public void addMultiLineDescription(List<String> tooltip, String key, Style style, Object... args){
|
||||||
String description = style.getFormattingCode() + I18n.format(key);
|
String description = style.getFormattingCode() + I18n.format(key, args);
|
||||||
tooltip.addAll(Minecraft.getMinecraft().fontRenderer.listFormattedStringToWidth(description, TOOLTIP_WRAP_WIDTH));
|
tooltip.addAll(Minecraft.getMinecraft().fontRenderer.listFormattedStringToWidth(description, TOOLTIP_WRAP_WIDTH));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,6 +438,7 @@ public class ClientProxy extends CommonProxy {
|
|||||||
if(caster instanceof ISpellCaster){
|
if(caster instanceof ISpellCaster){
|
||||||
if(spell.isContinuous || spell instanceof None){
|
if(spell.isContinuous || spell instanceof None){
|
||||||
((ISpellCaster)caster).setContinuousSpell(spell);
|
((ISpellCaster)caster).setContinuousSpell(spell);
|
||||||
|
((ISpellCaster)caster).setSpellCounter(spell instanceof None ? 0 : 1);
|
||||||
((EntityLiving)caster).setAttackTarget((EntityLivingBase)target);
|
((EntityLiving)caster).setAttackTarget((EntityLivingBase)target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -542,7 +552,7 @@ public class ClientProxy extends CommonProxy {
|
|||||||
data.randomNames = new HashMap<>();
|
data.randomNames = new HashMap<>();
|
||||||
data.randomDescriptions = new HashMap<>();
|
data.randomDescriptions = new HashMap<>();
|
||||||
|
|
||||||
for(Spell spell : Spell.getSpells(Spell.allSpells)){
|
for(Spell spell : Spell.getAllSpells()){
|
||||||
// -1 because the none spell isn't included
|
// -1 because the none spell isn't included
|
||||||
// This is a case where we must use the network ID, not the metadata
|
// This is a case where we must use the network ID, not the metadata
|
||||||
data.randomNames.put(spell, message.names.get(spell.networkID() - 1));
|
data.randomNames.put(spell, message.names.get(spell.networkID() - 1));
|
||||||
@@ -569,13 +579,6 @@ public class ClientProxy extends CommonProxy {
|
|||||||
GuiWizardHandbook.updateUnlockStatus(message.showToasts, message.completedAdvancements);
|
GuiWizardHandbook.updateUnlockStatus(message.showToasts, message.completedAdvancements);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleEndSlowTimePacket(PacketEndSlowTime.Message message){
|
|
||||||
Entity entity = Minecraft.getMinecraft().world.getEntityByID(message.hostID);
|
|
||||||
if(entity instanceof EntityLivingBase) PotionSlowTime.unblockNearbyEntities((EntityLivingBase)entity);
|
|
||||||
else Wizardry.logger.warn("Received a PacketEndSlowTime, but the entity ID did not match any living entity");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handleResurrectionPacket(PacketResurrection.Message message){
|
public void handleResurrectionPacket(PacketResurrection.Message message){
|
||||||
Entity entity = Minecraft.getMinecraft().world.getEntityByID(message.playerID);
|
Entity entity = Minecraft.getMinecraft().world.getEntityByID(message.playerID);
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import electroblob.wizardry.data.WizardData;
|
|||||||
import electroblob.wizardry.item.ISpellCastingItem;
|
import electroblob.wizardry.item.ISpellCastingItem;
|
||||||
import electroblob.wizardry.item.ItemArtefact;
|
import electroblob.wizardry.item.ItemArtefact;
|
||||||
import electroblob.wizardry.item.ItemSpectralBow;
|
import electroblob.wizardry.item.ItemSpectralBow;
|
||||||
|
import electroblob.wizardry.potion.PotionSlowTime;
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.registry.WizardryItems;
|
import electroblob.wizardry.registry.WizardryItems;
|
||||||
import electroblob.wizardry.registry.WizardryPotions;
|
import electroblob.wizardry.registry.WizardryPotions;
|
||||||
@@ -23,11 +24,8 @@ import net.minecraft.client.renderer.OpenGlHelper;
|
|||||||
import net.minecraft.client.renderer.Tessellator;
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
import net.minecraft.client.renderer.entity.RenderManager;
|
import net.minecraft.client.renderer.entity.RenderManager;
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||||
import net.minecraft.client.settings.KeyBinding;
|
|
||||||
import net.minecraft.entity.EntityLiving;
|
import net.minecraft.entity.EntityLiving;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.SharedMonsterAttributes;
|
|
||||||
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
|
||||||
import net.minecraft.entity.item.EntityArmorStand;
|
import net.minecraft.entity.item.EntityArmorStand;
|
||||||
import net.minecraft.inventory.Slot;
|
import net.minecraft.inventory.Slot;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
@@ -35,18 +33,17 @@ import net.minecraft.tileentity.TileEntity;
|
|||||||
import net.minecraft.tileentity.TileEntityDispenser;
|
import net.minecraft.tileentity.TileEntityDispenser;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.village.MerchantRecipe;
|
import net.minecraft.village.MerchantRecipe;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.client.event.*;
|
import net.minecraftforge.client.event.*;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
|
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event handler responsible for client-side only events, mostly rendering.
|
* Event handler responsible for client-side only events, mostly rendering.
|
||||||
@@ -72,24 +69,34 @@ public final class WizardryClientEventHandler {
|
|||||||
/** The number of ticks the blink effect lasts for. */
|
/** The number of ticks the blink effect lasts for. */
|
||||||
private static final int BLINK_EFFECT_DURATION = 8;
|
private static final int BLINK_EFFECT_DURATION = 8;
|
||||||
|
|
||||||
private static final Method unpressKey;
|
/** The remaining time for which the screen shake effect will be active. */
|
||||||
|
private static int screenShakeCounter = 0;
|
||||||
static {
|
private static final float SHAKINESS = 0.5f;
|
||||||
unpressKey = ObfuscationReflectionHelper.findMethod(KeyBinding.class, "func_74505_d", void.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Starts the first person blink overlay effect. */
|
/** Starts the first-person blink overlay effect. */
|
||||||
public static void playBlinkEffect(){
|
public static void playBlinkEffect(){
|
||||||
blinkEffectTimer = BLINK_EFFECT_DURATION;
|
blinkEffectTimer = BLINK_EFFECT_DURATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Starts the client-side screen shake effect. */
|
||||||
|
public static void shakeScreen(float intensity){
|
||||||
|
screenShakeCounter = (int)(intensity / SHAKINESS);
|
||||||
|
Minecraft.getMinecraft().player.rotationPitch -= intensity * 0.5f; // Start halfway down
|
||||||
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onPlayerTickEvent(TickEvent.PlayerTickEvent event){
|
public static void onPlayerTickEvent(TickEvent.PlayerTickEvent event){
|
||||||
|
|
||||||
if(event.player == Minecraft.getMinecraft().player){
|
if(event.player == Minecraft.getMinecraft().player && event.phase == TickEvent.Phase.END){
|
||||||
|
|
||||||
if(blinkEffectTimer > 0) blinkEffectTimer--;
|
if(blinkEffectTimer > 0) blinkEffectTimer--;
|
||||||
|
|
||||||
|
if(screenShakeCounter > 0){
|
||||||
|
float magnitude = screenShakeCounter * SHAKINESS;
|
||||||
|
Minecraft.getMinecraft().player.rotationPitch += screenShakeCounter % 2 == 0 ? magnitude : -magnitude;
|
||||||
|
screenShakeCounter--;
|
||||||
|
}
|
||||||
|
|
||||||
// Only seems to work here...
|
// Only seems to work here...
|
||||||
// EntityLiving victim = Possession.getPossessee(Minecraft.getMinecraft().player);
|
// EntityLiving victim = Possession.getPossessee(Minecraft.getMinecraft().player);
|
||||||
// if(victim != null && victim.getHeldItemMainhand().isEmpty()){
|
// if(victim != null && victim.getHeldItemMainhand().isEmpty()){
|
||||||
@@ -151,7 +158,10 @@ public final class WizardryClientEventHandler {
|
|||||||
|
|
||||||
if(world == null) return;
|
if(world == null) return;
|
||||||
|
|
||||||
for(TileEntity tileentity : world.loadedTileEntityList){
|
// Somehow this was throwing a CME, I have no idea why so I'm just going to cheat and copy the list
|
||||||
|
List<TileEntity> tileEntities = new ArrayList<>(world.loadedTileEntityList);
|
||||||
|
|
||||||
|
for(TileEntity tileentity : tileEntities){
|
||||||
if(tileentity instanceof TileEntityDispenser){
|
if(tileentity instanceof TileEntityDispenser){
|
||||||
if(DispenserCastingData.get((TileEntityDispenser)tileentity) != null){
|
if(DispenserCastingData.get((TileEntityDispenser)tileentity) != null){
|
||||||
DispenserCastingData.get((TileEntityDispenser)tileentity).update();
|
DispenserCastingData.get((TileEntityDispenser)tileentity).update();
|
||||||
@@ -160,6 +170,7 @@ public final class WizardryClientEventHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SpellEmitterData.update(world);
|
SpellEmitterData.update(world);
|
||||||
|
PotionSlowTime.cleanUpEntities(world);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import net.minecraft.inventory.Slot;
|
|||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.util.math.MathHelper;
|
|
||||||
import net.minecraft.util.text.TextFormatting;
|
import net.minecraft.util.text.TextFormatting;
|
||||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package electroblob.wizardry.client.model;
|
package electroblob.wizardry.client.model;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.block.BlockStatue;
|
import electroblob.wizardry.block.BlockStatue;
|
||||||
import net.minecraft.client.model.ModelRenderer;
|
import net.minecraft.client.model.ModelRenderer;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
@@ -13,6 +14,7 @@ public class ModelWizardArmour extends ModelArmourFixer {
|
|||||||
ModelRenderer hatSegment4;
|
ModelRenderer hatSegment4;
|
||||||
ModelRenderer hatSegment5;
|
ModelRenderer hatSegment5;
|
||||||
ModelRenderer hatSegment6;
|
ModelRenderer hatSegment6;
|
||||||
|
ModelRenderer hatBobble;
|
||||||
ModelRenderer robe;
|
ModelRenderer robe;
|
||||||
|
|
||||||
public ModelWizardArmour(float delta){
|
public ModelWizardArmour(float delta){
|
||||||
@@ -75,6 +77,13 @@ public class ModelWizardArmour extends ModelArmourFixer {
|
|||||||
hatSegment6.mirror = true;
|
hatSegment6.mirror = true;
|
||||||
setRotation(hatSegment6, -0.5585054F, 0F, 0F);
|
setRotation(hatSegment6, -0.5585054F, 0F, 0F);
|
||||||
|
|
||||||
|
hatBobble = new ModelRenderer(this, 52, 47);
|
||||||
|
hatBobble.addBox(0F, 0F, 0F, 3, 3, 3);
|
||||||
|
hatBobble.setRotationPoint(-1.5F, -15.1F, 4F);
|
||||||
|
hatBobble.setTextureSize(64, 64);
|
||||||
|
hatBobble.mirror = true;
|
||||||
|
setRotation(hatBobble, -0.65F, 0F, 0F);
|
||||||
|
|
||||||
bipedBody = new ModelRenderer(this, 16, 16);
|
bipedBody = new ModelRenderer(this, 16, 16);
|
||||||
bipedBody.addBox(-4F, 0F, -2F, 8, 11, 4, delta);
|
bipedBody.addBox(-4F, 0F, -2F, 8, 11, 4, delta);
|
||||||
bipedBody.setRotationPoint(0F, 0F, 0F);
|
bipedBody.setRotationPoint(0F, 0F, 0F);
|
||||||
@@ -97,6 +106,7 @@ public class ModelWizardArmour extends ModelArmourFixer {
|
|||||||
bipedHead.addChild(hatSegment4);
|
bipedHead.addChild(hatSegment4);
|
||||||
bipedHead.addChild(hatSegment5);
|
bipedHead.addChild(hatSegment5);
|
||||||
bipedHead.addChild(hatSegment6);
|
bipedHead.addChild(hatSegment6);
|
||||||
|
bipedHead.addChild(hatBobble);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5){
|
public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5){
|
||||||
@@ -129,6 +139,8 @@ public class ModelWizardArmour extends ModelArmourFixer {
|
|||||||
this.robe.rotateAngleX = (this.bipedLeftLeg.rotateAngleX + this.bipedRightLeg.rotateAngleX) / 2f;
|
this.robe.rotateAngleX = (this.bipedLeftLeg.rotateAngleX + this.bipedRightLeg.rotateAngleX) / 2f;
|
||||||
this.robe.rotateAngleY = this.bipedBody.rotateAngleY;
|
this.robe.rotateAngleY = this.bipedBody.rotateAngleY;
|
||||||
this.robe.rotateAngleZ = (this.bipedLeftLeg.rotateAngleZ + this.bipedRightLeg.rotateAngleZ) / 2f;
|
this.robe.rotateAngleZ = (this.bipedLeftLeg.rotateAngleZ + this.bipedRightLeg.rotateAngleZ) / 2f;
|
||||||
|
|
||||||
|
this.hatBobble.showModel = Wizardry.tisTheSeason;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,10 +67,10 @@ public final class WizardryModels {
|
|||||||
|
|
||||||
registerMultiTexturedModel((ItemCrystal)WizardryItems.magic_crystal);
|
registerMultiTexturedModel((ItemCrystal)WizardryItems.magic_crystal);
|
||||||
|
|
||||||
registerItemModel(WizardryItems.magic_wand);
|
registerWandModel(WizardryItems.magic_wand);
|
||||||
registerItemModel(WizardryItems.apprentice_wand);
|
registerWandModel(WizardryItems.apprentice_wand);
|
||||||
registerItemModel(WizardryItems.advanced_wand);
|
registerWandModel(WizardryItems.advanced_wand);
|
||||||
registerItemModel(WizardryItems.master_wand);
|
registerWandModel(WizardryItems.master_wand);
|
||||||
|
|
||||||
registerItemModel(WizardryItems.spell_book);
|
registerItemModel(WizardryItems.spell_book);
|
||||||
// Wildcard registered for wizard trades.
|
// Wildcard registered for wizard trades.
|
||||||
@@ -78,37 +78,37 @@ public final class WizardryModels {
|
|||||||
registerItemModel(WizardryItems.arcane_tome);
|
registerItemModel(WizardryItems.arcane_tome);
|
||||||
registerItemModel(WizardryItems.wizard_handbook);
|
registerItemModel(WizardryItems.wizard_handbook);
|
||||||
|
|
||||||
registerItemModel(WizardryItems.novice_fire_wand);
|
registerWandModel(WizardryItems.novice_fire_wand);
|
||||||
registerItemModel(WizardryItems.novice_ice_wand);
|
registerWandModel(WizardryItems.novice_ice_wand);
|
||||||
registerItemModel(WizardryItems.novice_lightning_wand);
|
registerWandModel(WizardryItems.novice_lightning_wand);
|
||||||
registerItemModel(WizardryItems.novice_necromancy_wand);
|
registerWandModel(WizardryItems.novice_necromancy_wand);
|
||||||
registerItemModel(WizardryItems.novice_earth_wand);
|
registerWandModel(WizardryItems.novice_earth_wand);
|
||||||
registerItemModel(WizardryItems.novice_sorcery_wand);
|
registerWandModel(WizardryItems.novice_sorcery_wand);
|
||||||
registerItemModel(WizardryItems.novice_healing_wand);
|
registerWandModel(WizardryItems.novice_healing_wand);
|
||||||
|
|
||||||
registerItemModel(WizardryItems.apprentice_fire_wand);
|
registerWandModel(WizardryItems.apprentice_fire_wand);
|
||||||
registerItemModel(WizardryItems.apprentice_ice_wand);
|
registerWandModel(WizardryItems.apprentice_ice_wand);
|
||||||
registerItemModel(WizardryItems.apprentice_lightning_wand);
|
registerWandModel(WizardryItems.apprentice_lightning_wand);
|
||||||
registerItemModel(WizardryItems.apprentice_necromancy_wand);
|
registerWandModel(WizardryItems.apprentice_necromancy_wand);
|
||||||
registerItemModel(WizardryItems.apprentice_earth_wand);
|
registerWandModel(WizardryItems.apprentice_earth_wand);
|
||||||
registerItemModel(WizardryItems.apprentice_sorcery_wand);
|
registerWandModel(WizardryItems.apprentice_sorcery_wand);
|
||||||
registerItemModel(WizardryItems.apprentice_healing_wand);
|
registerWandModel(WizardryItems.apprentice_healing_wand);
|
||||||
|
|
||||||
registerItemModel(WizardryItems.advanced_fire_wand);
|
registerWandModel(WizardryItems.advanced_fire_wand);
|
||||||
registerItemModel(WizardryItems.advanced_ice_wand);
|
registerWandModel(WizardryItems.advanced_ice_wand);
|
||||||
registerItemModel(WizardryItems.advanced_lightning_wand);
|
registerWandModel(WizardryItems.advanced_lightning_wand);
|
||||||
registerItemModel(WizardryItems.advanced_necromancy_wand);
|
registerWandModel(WizardryItems.advanced_necromancy_wand);
|
||||||
registerItemModel(WizardryItems.advanced_earth_wand);
|
registerWandModel(WizardryItems.advanced_earth_wand);
|
||||||
registerItemModel(WizardryItems.advanced_sorcery_wand);
|
registerWandModel(WizardryItems.advanced_sorcery_wand);
|
||||||
registerItemModel(WizardryItems.advanced_healing_wand);
|
registerWandModel(WizardryItems.advanced_healing_wand);
|
||||||
|
|
||||||
registerItemModel(WizardryItems.master_fire_wand);
|
registerWandModel(WizardryItems.master_fire_wand);
|
||||||
registerItemModel(WizardryItems.master_ice_wand);
|
registerWandModel(WizardryItems.master_ice_wand);
|
||||||
registerItemModel(WizardryItems.master_lightning_wand);
|
registerWandModel(WizardryItems.master_lightning_wand);
|
||||||
registerItemModel(WizardryItems.master_necromancy_wand);
|
registerWandModel(WizardryItems.master_necromancy_wand);
|
||||||
registerItemModel(WizardryItems.master_earth_wand);
|
registerWandModel(WizardryItems.master_earth_wand);
|
||||||
registerItemModel(WizardryItems.master_sorcery_wand);
|
registerWandModel(WizardryItems.master_sorcery_wand);
|
||||||
registerItemModel(WizardryItems.master_healing_wand);
|
registerWandModel(WizardryItems.master_healing_wand);
|
||||||
|
|
||||||
registerItemModel(WizardryItems.spectral_sword);
|
registerItemModel(WizardryItems.spectral_sword);
|
||||||
registerItemModel(WizardryItems.spectral_pickaxe);
|
registerItemModel(WizardryItems.spectral_pickaxe);
|
||||||
@@ -303,6 +303,23 @@ public final class WizardryModels {
|
|||||||
// Assigns the model for all metadata values
|
// Assigns the model for all metadata values
|
||||||
ModelLoader.setCustomMeshDefinition(item, s -> new ModelResourceLocation(item.getRegistryName(), "inventory"));
|
ModelLoader.setCustomMeshDefinition(item, s -> new ModelResourceLocation(item.getRegistryName(), "inventory"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a wand model, using the item's registry name as the model name (this convention makes it easier to
|
||||||
|
* keep track of everything).
|
||||||
|
*/
|
||||||
|
private static void registerWandModel(Item item){
|
||||||
|
|
||||||
|
if(Wizardry.tisTheSeason){
|
||||||
|
// Changing the last parameter from null to "inventory" fixed the item/block model weirdness. No idea why!
|
||||||
|
ModelBakery.registerItemVariants(item, new ModelResourceLocation("ebwizardry:festive_wand", "inventory"));
|
||||||
|
// Assigns the model for all metadata values
|
||||||
|
ModelLoader.setCustomMeshDefinition(item, s -> new ModelResourceLocation("ebwizardry:festive_wand", "inventory"));
|
||||||
|
}else{
|
||||||
|
registerItemModel(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers an item model, using the itemstack-sensitive {@link IMultiTexturedItem#getModelName(ItemStack)} as the
|
* Registers an item model, using the itemstack-sensitive {@link IMultiTexturedItem#getModelName(ItemStack)} as the
|
||||||
|
|||||||
@@ -525,30 +525,42 @@ public abstract class ParticleWizardry extends Particle {
|
|||||||
|
|
||||||
|
|
||||||
// =============================================== Helper Methods ===============================================
|
// =============================================== Helper Methods ===============================================
|
||||||
|
|
||||||
|
/** Internal overload for {@link ParticleWizardry#generateTextures(String, String, int)} which uses wizardry's mod
|
||||||
|
* ID automatically. */
|
||||||
|
public static ResourceLocation[] generateTextures(String stem, int n){
|
||||||
|
return generateTextures(Wizardry.MODID, stem, n);
|
||||||
|
}
|
||||||
|
|
||||||
/** Static helper method that generates an array of n ResourceLocations using the particle file naming convention,
|
/** Static helper method that generates an array of n ResourceLocations using the particle file naming convention,
|
||||||
* which is the given stem plus an underscore plus the integer index. */
|
* which is the given stem plus an underscore plus the integer index. */
|
||||||
public static ResourceLocation[] generateTextures(String stem, int n){
|
public static ResourceLocation[] generateTextures(String modID, String stem, int n){
|
||||||
|
|
||||||
ResourceLocation[] textures = new ResourceLocation[n];
|
ResourceLocation[] textures = new ResourceLocation[n];
|
||||||
|
|
||||||
for(int i=0; i<n; i++){
|
for(int i=0; i<n; i++){
|
||||||
textures[i] = new ResourceLocation(Wizardry.MODID, "particle/" + stem + "_" + i);
|
textures[i] = new ResourceLocation(modID, "particle/" + stem + "_" + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return textures;
|
return textures;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Internal overload for {@link ParticleWizardry#generateTextures(String, String, int, int)} which uses wizardry's
|
||||||
|
* mod ID automatically. */
|
||||||
|
public static ResourceLocation[][] generateTextures(String stem, int m, int n){
|
||||||
|
return generateTextures(Wizardry.MODID, stem, m, n);
|
||||||
|
}
|
||||||
|
|
||||||
/** Static helper method that generates a 2D m x n array of ResourceLocations using the particle file naming
|
/** Static helper method that generates a 2D m x n array of ResourceLocations using the particle file naming
|
||||||
* convention, which is the given stem plus an underscore plus the first index, plus an underscore plus the second
|
* convention, which is the given stem plus an underscore plus the first index, plus an underscore plus the second
|
||||||
* index. Useful for animated particles that also pick a random animation strip. */
|
* index. Useful for animated particles that also pick a random animation strip. */
|
||||||
public static ResourceLocation[][] generateTextures(String stem, int m, int n){
|
public static ResourceLocation[][] generateTextures(String modID, String stem, int m, int n){
|
||||||
|
|
||||||
ResourceLocation[][] textures = new ResourceLocation[m][n];
|
ResourceLocation[][] textures = new ResourceLocation[m][n];
|
||||||
|
|
||||||
for(int i=0; i<m; i++){
|
for(int i=0; i<m; i++){
|
||||||
for(int j=0; j<n; j++){
|
for(int j=0; j<n; j++){
|
||||||
textures[i][j] = new ResourceLocation(Wizardry.MODID, "particle/" + stem + "_" + i + "_" + j);
|
textures[i][j] = new ResourceLocation(modID, "particle/" + stem + "_" + i + "_" + j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ public class LayerFrost implements LayerRenderer<EntityLivingBase> {
|
|||||||
double scaleX = 1, scaleY = 1;
|
double scaleX = 1, scaleY = 1;
|
||||||
// It's more logical to use the model's texture size, but some classes don't bother setting it properly
|
// It's more logical to use the model's texture size, but some classes don't bother setting it properly
|
||||||
// (e.g. ModelVillager), so to get the correct dimensions I'm getting them from the first box instead.
|
// (e.g. ModelVillager), so to get the correct dimensions I'm getting them from the first box instead.
|
||||||
if(model.boxList != null && model.boxList.get(0) != null){
|
if(model.boxList != null && model.boxList.size() >= 1 && model.boxList.get(0) != null){
|
||||||
scaleX = (double)model.boxList.get(0).textureWidth / 16d;
|
scaleX = (double)model.boxList.get(0).textureWidth / 16d;
|
||||||
scaleY = (double)model.boxList.get(0).textureHeight / 16d;
|
scaleY = (double)model.boxList.get(0).textureHeight / 16d;
|
||||||
}else{ // Fallback to model fields; should never be needed
|
}else{ // Fallback to model fields; should never be needed
|
||||||
@@ -121,11 +121,26 @@ public class LayerFrost implements LayerRenderer<EntityLivingBase> {
|
|||||||
}
|
}
|
||||||
GlStateManager.scale(scaleX, scaleY, 1);
|
GlStateManager.scale(scaleX, scaleY, 1);
|
||||||
GlStateManager.matrixMode(GL11.GL_MODELVIEW);
|
GlStateManager.matrixMode(GL11.GL_MODELVIEW);
|
||||||
|
|
||||||
|
boolean headWearHidden = false;
|
||||||
|
boolean bodyWearHidden = false;
|
||||||
|
boolean leftArmWearHidden = false;
|
||||||
|
boolean rightArmWearHidden = false;
|
||||||
|
boolean leftLegWearHidden = false;
|
||||||
|
boolean rightLegWearHidden = false;
|
||||||
|
|
||||||
// Hides the hat layer for bipeds
|
// Hides the hat layer for bipeds
|
||||||
if(this.model instanceof ModelBiped) ((ModelBiped)this.model).bipedHeadwear.isHidden = true;
|
if(this.model instanceof ModelBiped){
|
||||||
|
headWearHidden = ((ModelBiped)this.model).bipedHeadwear.isHidden;
|
||||||
|
((ModelBiped)this.model).bipedHeadwear.isHidden = true;
|
||||||
|
}
|
||||||
|
|
||||||
if(this.model instanceof ModelPlayer){
|
if(this.model instanceof ModelPlayer){
|
||||||
|
bodyWearHidden = ((ModelPlayer)this.model).bipedBodyWear.isHidden;
|
||||||
|
leftArmWearHidden = ((ModelPlayer)this.model).bipedLeftArmwear.isHidden;
|
||||||
|
rightArmWearHidden = ((ModelPlayer)this.model).bipedRightArmwear.isHidden;
|
||||||
|
leftLegWearHidden = ((ModelPlayer)this.model).bipedLeftLegwear.isHidden;
|
||||||
|
rightLegWearHidden = ((ModelPlayer)this.model).bipedRightLegwear.isHidden;
|
||||||
((ModelPlayer)this.model).bipedBodyWear.isHidden = true;
|
((ModelPlayer)this.model).bipedBodyWear.isHidden = true;
|
||||||
((ModelPlayer)this.model).bipedLeftArmwear.isHidden = true;
|
((ModelPlayer)this.model).bipedLeftArmwear.isHidden = true;
|
||||||
((ModelPlayer)this.model).bipedRightArmwear.isHidden = true;
|
((ModelPlayer)this.model).bipedRightArmwear.isHidden = true;
|
||||||
@@ -136,7 +151,15 @@ public class LayerFrost implements LayerRenderer<EntityLivingBase> {
|
|||||||
this.model.setLivingAnimations(entity, limbSwing, limbSwingAmount, partialTicks);
|
this.model.setLivingAnimations(entity, limbSwing, limbSwingAmount, partialTicks);
|
||||||
this.model.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale);
|
this.model.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale);
|
||||||
|
|
||||||
if(this.model instanceof ModelBiped) ((ModelBiped)this.model).bipedHeadwear.isHidden = false;
|
if(this.model instanceof ModelBiped) ((ModelBiped)this.model).bipedHeadwear.isHidden = headWearHidden;
|
||||||
|
|
||||||
|
if(this.model instanceof ModelPlayer){
|
||||||
|
((ModelPlayer)this.model).bipedBodyWear.isHidden = bodyWearHidden;
|
||||||
|
((ModelPlayer)this.model).bipedLeftArmwear.isHidden = leftArmWearHidden;
|
||||||
|
((ModelPlayer)this.model).bipedRightArmwear.isHidden = rightArmWearHidden;
|
||||||
|
((ModelPlayer)this.model).bipedLeftLegwear.isHidden = leftLegWearHidden;
|
||||||
|
((ModelPlayer)this.model).bipedRightLegwear.isHidden = rightLegWearHidden;
|
||||||
|
}
|
||||||
|
|
||||||
// Undoes the texture scaling
|
// Undoes the texture scaling
|
||||||
GlStateManager.matrixMode(GL11.GL_TEXTURE);
|
GlStateManager.matrixMode(GL11.GL_TEXTURE);
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ public class RenderArcaneLock {
|
|||||||
|
|
||||||
GlStateManager.pushMatrix();
|
GlStateManager.pushMatrix();
|
||||||
GlStateManager.enableBlend();
|
GlStateManager.enableBlend();
|
||||||
|
boolean lighting = GL11.glIsEnabled(GL11.GL_LIGHTING);
|
||||||
GlStateManager.disableLighting();
|
GlStateManager.disableLighting();
|
||||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
|
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
|
||||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||||
@@ -62,6 +63,8 @@ public class RenderArcaneLock {
|
|||||||
List<TileEntity> tileentities = new ArrayList<>(world.loadedTileEntityList);
|
List<TileEntity> tileentities = new ArrayList<>(world.loadedTileEntityList);
|
||||||
|
|
||||||
for(TileEntity tileentity : tileentities){
|
for(TileEntity tileentity : tileentities){
|
||||||
|
|
||||||
|
if(tileentity == null) continue; // What the heck VoxelMap
|
||||||
|
|
||||||
if(tileentity.getDistanceSq(origin.x, origin.y, origin.z) <= tileentity.getMaxRenderDistanceSquared()
|
if(tileentity.getDistanceSq(origin.x, origin.y, origin.z) <= tileentity.getMaxRenderDistanceSquared()
|
||||||
&& tileentity.getTileData().hasUniqueId(ArcaneLock.NBT_KEY)){
|
&& tileentity.getTileData().hasUniqueId(ArcaneLock.NBT_KEY)){
|
||||||
@@ -82,7 +85,9 @@ public class RenderArcaneLock {
|
|||||||
|
|
||||||
GlStateManager.disableBlend();
|
GlStateManager.disableBlend();
|
||||||
GlStateManager.enableTexture2D();
|
GlStateManager.enableTexture2D();
|
||||||
GlStateManager.enableLighting();
|
if (lighting) {
|
||||||
|
GlStateManager.enableLighting();
|
||||||
|
}
|
||||||
GlStateManager.disableRescaleNormal();
|
GlStateManager.disableRescaleNormal();
|
||||||
GlStateManager.popMatrix();
|
GlStateManager.popMatrix();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,9 +53,8 @@ public class RenderBlackHole extends Render<EntityBlackHole> {
|
|||||||
(float)blackhole.ticksExisted / 10);
|
(float)blackhole.ticksExisted / 10);
|
||||||
}
|
}
|
||||||
if(blackhole.ticksExisted > blackhole.lifetime - 10){
|
if(blackhole.ticksExisted > blackhole.lifetime - 10){
|
||||||
GlStateManager.scale((float)(blackhole.lifetime - blackhole.ticksExisted) / 10,
|
float scale = Math.max(0, (float)(blackhole.lifetime - blackhole.ticksExisted) / 10);
|
||||||
(float)(blackhole.lifetime - blackhole.ticksExisted) / 10,
|
GlStateManager.scale(scale, scale, scale);
|
||||||
(float)(blackhole.lifetime - blackhole.ticksExisted) / 10);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.bindTexture(texture);
|
this.bindTexture(texture);
|
||||||
|
|||||||
@@ -190,7 +190,8 @@ public class CommandCastSpell extends CommandBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(spell.isContinuous){
|
if(spell.isContinuous){
|
||||||
|
// We need not query Spell#canBeCastByDispensers since with commands there's no difference between
|
||||||
|
// a spell that can't be cast positionally and one that can be cast positionally but fails
|
||||||
if(spell.cast(world, origin.x, origin.y, origin.z, direction, 0, duration, modifiers)){
|
if(spell.cast(world, origin.x, origin.y, origin.z, direction, 0, duration, modifiers)){
|
||||||
|
|
||||||
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(Source.COMMAND, spell, world, origin.x, origin.y, origin.z, direction, modifiers));
|
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(Source.COMMAND, spell, world, origin.x, origin.y, origin.z, direction, modifiers));
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public class CommandDiscoverSpell extends CommandBase {
|
|||||||
if(server.sendCommandFeedback()) sender.sendMessage(
|
if(server.sendCommandFeedback()) sender.sendMessage(
|
||||||
new TextComponentTranslation("commands." + Wizardry.MODID + ":discoverspell.clear", player.getName()));
|
new TextComponentTranslation("commands." + Wizardry.MODID + ":discoverspell.clear", player.getName()));
|
||||||
}else if(all){
|
}else if(all){
|
||||||
data.spellsDiscovered.addAll(Spell.getSpells(Spell.allSpells));
|
data.spellsDiscovered.addAll(Spell.getAllSpells());
|
||||||
if(server.sendCommandFeedback()) sender.sendMessage(
|
if(server.sendCommandFeedback()) sender.sendMessage(
|
||||||
new TextComponentTranslation("commands." + Wizardry.MODID + ":discoverspell.all", player.getName()));
|
new TextComponentTranslation("commands." + Wizardry.MODID + ":discoverspell.all", player.getName()));
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import electroblob.wizardry.Wizardry;
|
|||||||
import electroblob.wizardry.data.SpellEmitterData;
|
import electroblob.wizardry.data.SpellEmitterData;
|
||||||
import electroblob.wizardry.event.SpellCastEvent;
|
import electroblob.wizardry.event.SpellCastEvent;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
|
import electroblob.wizardry.util.NBTExtras;
|
||||||
import electroblob.wizardry.util.SpellModifiers;
|
import electroblob.wizardry.util.SpellModifiers;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
@@ -129,7 +130,7 @@ public class SpellEmitter implements ITickable {
|
|||||||
nbt.setDouble("z", z);
|
nbt.setDouble("z", z);
|
||||||
nbt.setInteger("direction", direction.getIndex());
|
nbt.setInteger("direction", direction.getIndex());
|
||||||
nbt.setInteger("duration", duration);
|
nbt.setInteger("duration", duration);
|
||||||
nbt.setTag("modifiers", modifiers.toNBT());
|
NBTExtras.storeTagSafely(nbt, "modifiers", modifiers.toNBT());
|
||||||
nbt.setInteger("castingTick", castingTick);
|
nbt.setInteger("castingTick", castingTick);
|
||||||
|
|
||||||
return nbt;
|
return nbt;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import electroblob.wizardry.packet.WizardryPacketHandler;
|
|||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.spell.None;
|
import electroblob.wizardry.spell.None;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
|
import electroblob.wizardry.util.NBTExtras;
|
||||||
import electroblob.wizardry.util.SpellModifiers;
|
import electroblob.wizardry.util.SpellModifiers;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
@@ -141,7 +142,7 @@ public abstract class BlockCastingData<T extends TileEntity> implements INBTSeri
|
|||||||
|
|
||||||
nbt.setInteger("spell", spell.metadata());
|
nbt.setInteger("spell", spell.metadata());
|
||||||
nbt.setInteger("castingTick", castingTick);
|
nbt.setInteger("castingTick", castingTick);
|
||||||
nbt.setTag("modifiers", modifiers.toNBT());
|
NBTExtras.storeTagSafely(nbt, "modifiers", modifiers.toNBT());
|
||||||
|
|
||||||
return nbt;
|
return nbt;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,7 +166,10 @@ public class DispenserCastingData extends BlockCastingData<TileEntityDispenser>
|
|||||||
// This will fire once for each dimension, but since we want dispenser-casting to work in all dimensions,
|
// This will fire once for each dimension, but since we want dispenser-casting to work in all dimensions,
|
||||||
// this is correct (the loaded tile entity list will of course be different in each case.
|
// this is correct (the loaded tile entity list will of course be different in each case.
|
||||||
|
|
||||||
for(TileEntity tileentity : event.world.loadedTileEntityList){
|
// Somehow this was throwing a CME, I have no idea why so I'm just going to cheat and copy the list
|
||||||
|
List<TileEntity> tileEntities = new ArrayList<>(event.world.loadedTileEntityList);
|
||||||
|
|
||||||
|
for(TileEntity tileentity : tileEntities){
|
||||||
if(tileentity instanceof TileEntityDispenser){
|
if(tileentity instanceof TileEntityDispenser){
|
||||||
if(DispenserCastingData.get((TileEntityDispenser)tileentity) != null){
|
if(DispenserCastingData.get((TileEntityDispenser)tileentity) != null){
|
||||||
DispenserCastingData.get((TileEntityDispenser)tileentity).update();
|
DispenserCastingData.get((TileEntityDispenser)tileentity).update();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package electroblob.wizardry.data;
|
package electroblob.wizardry.data;
|
||||||
|
|
||||||
|
import electroblob.wizardry.util.NBTExtras;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
@@ -89,7 +90,7 @@ public interface IStoredVariable<T> extends IVariable<T> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(NBTTagCompound nbt, T value){
|
public void write(NBTTagCompound nbt, T value){
|
||||||
if(value != null) nbt.setTag(key, serialiser.apply(value));
|
if(value != null) NBTExtras.storeTagSafely(nbt, key, serialiser.apply(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public class SpellEmitterData extends WorldSavedData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NBTTagCompound writeToNBT(NBTTagCompound compound){
|
public NBTTagCompound writeToNBT(NBTTagCompound compound){
|
||||||
compound.setTag("emitters", NBTExtras.listToNBT(emitters, SpellEmitter::toNBT));
|
NBTExtras.storeTagSafely(compound, "emitters", NBTExtras.listToNBT(emitters, SpellEmitter::toNBT));
|
||||||
return compound;
|
return compound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import electroblob.wizardry.Wizardry;
|
|||||||
import electroblob.wizardry.packet.PacketGlyphData;
|
import electroblob.wizardry.packet.PacketGlyphData;
|
||||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
|
import electroblob.wizardry.util.NBTExtras;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.nbt.NBTTagList;
|
import net.minecraft.nbt.NBTTagList;
|
||||||
@@ -43,11 +44,11 @@ public class SpellGlyphData extends WorldSavedData {
|
|||||||
/** Generates random names and descriptions for any spells which don't already have them. */
|
/** Generates random names and descriptions for any spells which don't already have them. */
|
||||||
public void generateGlyphNames(World world){
|
public void generateGlyphNames(World world){
|
||||||
|
|
||||||
for(Spell spell : Spell.getSpells(Spell.allSpells)){
|
for(Spell spell : Spell.getAllSpells()){
|
||||||
if(!randomNames.containsKey(spell)) randomNames.put(spell, generateRandomName(world.rand));
|
if(!randomNames.containsKey(spell)) randomNames.put(spell, generateRandomName(world.rand));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Spell spell : Spell.getSpells(Spell.allSpells)){
|
for(Spell spell : Spell.getAllSpells()){
|
||||||
if(!randomDescriptions.containsKey(spell))
|
if(!randomDescriptions.containsKey(spell))
|
||||||
randomDescriptions.put(spell, generateRandomDescription(world.rand));
|
randomDescriptions.put(spell, generateRandomDescription(world.rand));
|
||||||
}
|
}
|
||||||
@@ -161,7 +162,7 @@ public class SpellGlyphData extends WorldSavedData {
|
|||||||
|
|
||||||
NBTTagList tagList = new NBTTagList();
|
NBTTagList tagList = new NBTTagList();
|
||||||
|
|
||||||
for(Spell spell : Spell.getSpells(Spell.allSpells)){
|
for(Spell spell : Spell.getAllSpells()){
|
||||||
// Much like the enchantments tag for items, this stores a list of spell-id-to-name tag pairs
|
// Much like the enchantments tag for items, this stores a list of spell-id-to-name tag pairs
|
||||||
// The description is now also included; there's no point in making a second compound tag!
|
// The description is now also included; there's no point in making a second compound tag!
|
||||||
NBTTagCompound tag = new NBTTagCompound();
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
@@ -171,7 +172,7 @@ public class SpellGlyphData extends WorldSavedData {
|
|||||||
tagList.appendTag(tag);
|
tagList.appendTag(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
nbt.setTag("spellGlyphData", tagList);
|
NBTExtras.storeTagSafely(nbt, "spellGlyphData", tagList);
|
||||||
|
|
||||||
return nbt;
|
return nbt;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -515,12 +515,12 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
|
|||||||
|
|
||||||
NBTTagCompound properties = new NBTTagCompound();
|
NBTTagCompound properties = new NBTTagCompound();
|
||||||
|
|
||||||
properties.setTag("imbuements", NBTExtras.mapToNBT(this.imbuementDurations,
|
NBTExtras.storeTagSafely(properties, "imbuements", NBTExtras.mapToNBT(this.imbuementDurations,
|
||||||
imbuement -> new NBTTagInt(Enchantment.getEnchantmentID((Enchantment)imbuement)), NBTTagInt::new));
|
imbuement -> new NBTTagInt(Enchantment.getEnchantmentID((Enchantment)imbuement)), NBTTagInt::new));
|
||||||
|
|
||||||
// Mmmmmm Java 8....
|
// Mmmmmm Java 8....
|
||||||
properties.setTag("allies", NBTExtras.listToNBT(this.allies, NBTUtil::createUUIDTag));
|
NBTExtras.storeTagSafely(properties, "allies", NBTExtras.listToNBT(this.allies, NBTUtil::createUUIDTag));
|
||||||
properties.setTag("allyNames", NBTExtras.listToNBT(this.allyNames, NBTTagString::new));
|
NBTExtras.storeTagSafely(properties, "allyNames", NBTExtras.listToNBT(this.allyNames, NBTTagString::new));
|
||||||
|
|
||||||
// Might be worth converting this over to WizardryUtilities.listToNBT.
|
// Might be worth converting this over to WizardryUtilities.listToNBT.
|
||||||
int[] spells = new int[this.spellsDiscovered.size()];
|
int[] spells = new int[this.spellsDiscovered.size()];
|
||||||
@@ -531,7 +531,7 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
|
|||||||
}
|
}
|
||||||
properties.setIntArray("discoveredSpells", spells);
|
properties.setIntArray("discoveredSpells", spells);
|
||||||
|
|
||||||
properties.setTag("recentSpells", NBTExtras.listToNBT(recentSpells, s -> new NBTTagInt(s.metadata())));
|
NBTExtras.storeTagSafely(properties, "recentSpells", NBTExtras.listToNBT(recentSpells, s -> new NBTTagInt(s.metadata())));
|
||||||
|
|
||||||
storedVariables.forEach(k -> k.write(properties, this.spellData.get(k)));
|
storedVariables.forEach(k -> k.write(properties, this.spellData.get(k)));
|
||||||
|
|
||||||
|
|||||||
@@ -120,9 +120,9 @@ public interface Imbuement {
|
|||||||
|
|
||||||
ItemStack bow = archer.getHeldItemMainhand();
|
ItemStack bow = archer.getHeldItemMainhand();
|
||||||
|
|
||||||
if(!ImbueWeapon.isBow(bow.getItem())){
|
if(!ImbueWeapon.isBow(bow)){
|
||||||
bow = archer.getHeldItemOffhand();
|
bow = archer.getHeldItemOffhand();
|
||||||
if(!ImbueWeapon.isBow(bow.getItem())) return;
|
if(!ImbueWeapon.isBow(bow)) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Taken directly from ItemBow, so it works exactly the same as the power enchantment.
|
// Taken directly from ItemBow, so it works exactly the same as the power enchantment.
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import electroblob.wizardry.registry.Spells;
|
|||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
import electroblob.wizardry.util.AllyDesignationSystem;
|
import electroblob.wizardry.util.AllyDesignationSystem;
|
||||||
import electroblob.wizardry.util.MagicDamage;
|
import electroblob.wizardry.util.MagicDamage;
|
||||||
|
import electroblob.wizardry.util.NBTExtras;
|
||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
@@ -183,7 +184,7 @@ public class EntityLevitatingBlock extends EntityFallingBlock implements IEntity
|
|||||||
NBTBase nbtbase = this.tileEntityData.getTag(s);
|
NBTBase nbtbase = this.tileEntityData.getTag(s);
|
||||||
|
|
||||||
if(!"x".equals(s) && !"y".equals(s) && !"z".equals(s)){
|
if(!"x".equals(s) && !"y".equals(s) && !"z".equals(s)){
|
||||||
nbttagcompound.setTag(s, nbtbase.copy());
|
NBTExtras.storeTagSafely(nbttagcompound, s, nbtbase.copy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ import electroblob.wizardry.registry.Spells;
|
|||||||
import electroblob.wizardry.registry.WizardryBlocks;
|
import electroblob.wizardry.registry.WizardryBlocks;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.spell.Meteor;
|
import electroblob.wizardry.spell.Meteor;
|
||||||
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.MoverType;
|
import net.minecraft.entity.MoverType;
|
||||||
import net.minecraft.entity.item.EntityFallingBlock;
|
import net.minecraft.entity.item.EntityFallingBlock;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.util.SoundCategory;
|
import net.minecraft.util.SoundCategory;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
@@ -61,9 +63,9 @@ public class EntityMeteor extends EntityFallingBlock {
|
|||||||
this.motionY *= 0.9800000190734863D;
|
this.motionY *= 0.9800000190734863D;
|
||||||
this.motionZ *= 0.9800000190734863D;
|
this.motionZ *= 0.9800000190734863D;
|
||||||
|
|
||||||
if(!this.world.isRemote){
|
if(this.onGround){
|
||||||
|
|
||||||
if(this.onGround){
|
if(!this.world.isRemote){
|
||||||
|
|
||||||
this.motionX *= 0.699999988079071D;
|
this.motionX *= 0.699999988079071D;
|
||||||
this.motionZ *= 0.699999988079071D;
|
this.motionZ *= 0.699999988079071D;
|
||||||
@@ -72,8 +74,13 @@ public class EntityMeteor extends EntityFallingBlock {
|
|||||||
Spells.meteor.getProperty(Meteor.BLAST_STRENGTH).floatValue() * blastMultiplier,
|
Spells.meteor.getProperty(Meteor.BLAST_STRENGTH).floatValue() * blastMultiplier,
|
||||||
damageBlocks, damageBlocks);
|
damageBlocks, damageBlocks);
|
||||||
this.setDead();
|
this.setDead();
|
||||||
|
|
||||||
|
}else{
|
||||||
|
WizardryUtilities.getEntitiesWithinRadius(15, posX, posY, posZ, world, EntityPlayer.class)
|
||||||
|
.forEach(p -> Wizardry.proxy.shakeScreen(p, 10));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public class EntityBubble extends EntityMagicConstruct {
|
|||||||
if(isDarkOrb){
|
if(isDarkOrb){
|
||||||
|
|
||||||
if(WizardryUtilities.getRider(this) != null
|
if(WizardryUtilities.getRider(this) != null
|
||||||
&& this.ticksExisted % Spells.entrapment.getProperty(Entrapment.DAMAGE_INTERVAL).intValue() == 0){
|
&& WizardryUtilities.getRider(this).ticksExisted % Spells.entrapment.getProperty(Entrapment.DAMAGE_INTERVAL).intValue() == 0){
|
||||||
if(this.getCaster() != null){
|
if(this.getCaster() != null){
|
||||||
WizardryUtilities.getRider(this).attackEntityFrom(
|
WizardryUtilities.getRider(this).attackEntityFrom(
|
||||||
MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.MAGIC),
|
MagicDamage.causeIndirectMagicDamage(this, getCaster(), DamageType.MAGIC),
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package electroblob.wizardry.entity.construct;
|
package electroblob.wizardry.entity.construct;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import electroblob.wizardry.util.MagicDamage.DamageType;
|
|||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.item.EntityFallingBlock;
|
import net.minecraft.entity.item.EntityFallingBlock;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
import net.minecraft.init.MobEffects;
|
import net.minecraft.init.MobEffects;
|
||||||
import net.minecraft.network.play.server.SPacketEntityVelocity;
|
import net.minecraft.network.play.server.SPacketEntityVelocity;
|
||||||
@@ -97,18 +96,6 @@ public class EntityEarthquake extends EntityMagicConstruct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!world.isRemote){
|
|
||||||
// Constant 15 blocks for now
|
|
||||||
List<EntityPlayer> targets2 = WizardryUtilities.getEntitiesWithinRadius(15, posX, posY, posZ, world, EntityPlayer.class);
|
|
||||||
|
|
||||||
float magnitude = 10f * ((float)(this.lifetime - this.ticksExisted))/(float)this.lifetime;
|
|
||||||
|
|
||||||
// Makes the screen shake
|
|
||||||
for(EntityPlayer target : targets2){
|
|
||||||
target.rotationPitch += this.ticksExisted % 2 == 0 ? magnitude : -magnitude;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ public class EntityHammer extends EntityMagicConstruct {
|
|||||||
|
|
||||||
if(this.world.isRemote && this.ticksExisted % 3 == 0){
|
if(this.world.isRemote && this.ticksExisted % 3 == 0){
|
||||||
ParticleBuilder.create(Type.SPARK)
|
ParticleBuilder.create(Type.SPARK)
|
||||||
.pos(this.posX - 0.5d + rand.nextDouble(), this.posY + 2 * rand.nextDouble(), this.posZ - 0.5d + rand.nextDouble())
|
.pos(this.posX - 0.5d + rand.nextDouble(), this.posY + 2 * rand.nextDouble(), this.posZ - 0.5d + rand.nextDouble())
|
||||||
.spawn(world);
|
.spawn(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.prevPosX = this.posX;
|
this.prevPosX = this.posX;
|
||||||
@@ -103,39 +103,37 @@ public class EntityHammer extends EntityMagicConstruct {
|
|||||||
this.rotationPitch = 0;
|
this.rotationPitch = 0;
|
||||||
this.spin = false;
|
this.spin = false;
|
||||||
|
|
||||||
if(this.ticksExisted % Spells.lightning_hammer.getProperty(LightningHammer.ATTACK_INTERVAL).floatValue() == 0){
|
double seekerRange = Spells.lightning_hammer.getProperty(Spell.EFFECT_RADIUS).doubleValue();
|
||||||
|
|
||||||
double seekerRange = Spells.lightning_hammer.getProperty(Spell.EFFECT_RADIUS).doubleValue();
|
List<EntityLivingBase> targets = WizardryUtilities.getEntitiesWithinRadius(seekerRange, this.posX,
|
||||||
|
this.posY + 1, this.posZ, world);
|
||||||
|
|
||||||
List<EntityLivingBase> targets = WizardryUtilities.getEntitiesWithinRadius(seekerRange, this.posX,
|
int maxTargets = Spells.lightning_hammer.getProperty(LightningHammer.SECONDARY_MAX_TARGETS).intValue();
|
||||||
this.posY + 1, this.posZ, world);
|
while(targets.size() > maxTargets) targets.remove(targets.size() - 1);
|
||||||
|
|
||||||
int maxTargets = Spells.lightning_hammer.getProperty(LightningHammer.SECONDARY_MAX_TARGETS).intValue();
|
for(EntityLivingBase target : targets){
|
||||||
while(targets.size() > maxTargets) targets.remove(targets.size() - 1);
|
|
||||||
|
|
||||||
for(EntityLivingBase target : targets){
|
if(WizardryUtilities.isLiving(target) && this.isValidTarget(target)
|
||||||
|
&& target.ticksExisted % Spells.lightning_hammer.getProperty(LightningHammer.ATTACK_INTERVAL).floatValue() == 0){
|
||||||
|
|
||||||
if(WizardryUtilities.isLiving(target) && this.isValidTarget(target)){
|
if(world.isRemote){
|
||||||
|
|
||||||
if(world.isRemote){
|
ParticleBuilder.create(Type.LIGHTNING).pos(posX, posY + height - 0.1, posZ) .target(target).spawn(world);
|
||||||
|
|
||||||
ParticleBuilder.create(Type.LIGHTNING).pos(posX, posY + height - 0.1, posZ) .target(target).spawn(world);
|
ParticleBuilder.spawnShockParticles(world, target.posX,
|
||||||
|
target.getEntityBoundingBox().minY + target.height, target.posZ);
|
||||||
|
}
|
||||||
|
|
||||||
ParticleBuilder.spawnShockParticles(world, target.posX,
|
target.playSound(WizardrySounds.ENTITY_HAMMER_ATTACK, 1.0F, rand.nextFloat() * 0.4F + 1.5F);
|
||||||
target.getEntityBoundingBox().minY + target.height, target.posZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
target.playSound(WizardrySounds.ENTITY_HAMMER_ATTACK, 1.0F, rand.nextFloat() * 0.4F + 1.5F);
|
float damage = Spells.lightning_hammer.getProperty(Spell.SPLASH_DAMAGE).floatValue() * damageMultiplier;
|
||||||
|
|
||||||
float damage = Spells.lightning_hammer.getProperty(Spell.SPLASH_DAMAGE).floatValue() * damageMultiplier;
|
if(this.getCaster() != null){
|
||||||
|
WizardryUtilities.attackEntityWithoutKnockback(target, MagicDamage.causeIndirectMagicDamage(
|
||||||
if(this.getCaster() != null){
|
this, getCaster(), DamageType.SHOCK), damage);
|
||||||
WizardryUtilities.attackEntityWithoutKnockback(target, MagicDamage.causeIndirectMagicDamage(
|
WizardryUtilities.applyStandardKnockback(this, target);
|
||||||
this, getCaster(), DamageType.SHOCK), damage);
|
}else{
|
||||||
WizardryUtilities.applyStandardKnockback(this, target);
|
target.attackEntityFrom(DamageSource.MAGIC, damage);
|
||||||
}else{
|
|
||||||
target.attackEntityFrom(DamageSource.MAGIC, damage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,6 +169,7 @@ public class EntityHammer extends EntityMagicConstruct {
|
|||||||
public void fall(float distance, float damageMultiplier){
|
public void fall(float distance, float damageMultiplier){
|
||||||
|
|
||||||
if(world.isRemote){
|
if(world.isRemote){
|
||||||
|
|
||||||
for(int i = 0; i < 40; i++){
|
for(int i = 0; i < 40; i++){
|
||||||
double particleX = this.posX - 1.0d + 2 * rand.nextDouble();
|
double particleX = this.posX - 1.0d + 2 * rand.nextDouble();
|
||||||
double particleZ = this.posZ - 1.0d + 2 * rand.nextDouble();
|
double particleZ = this.posZ - 1.0d + 2 * rand.nextDouble();
|
||||||
@@ -182,6 +181,12 @@ public class EntityHammer extends EntityMagicConstruct {
|
|||||||
particleX - this.posX, 0, particleZ - this.posZ, Block.getStateId(block));
|
particleX - this.posX, 0, particleZ - this.posZ, Block.getStateId(block));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(this.fallDistance > 10){
|
||||||
|
WizardryUtilities.getEntitiesWithinRadius(10, posX, posY, posZ, world, EntityPlayer.class)
|
||||||
|
.forEach(p -> Wizardry.proxy.shakeScreen(p, 6));
|
||||||
|
}
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
// Just to check the hammer has actually fallen from the sky, rather than the block under it being broken.
|
// Just to check the hammer has actually fallen from the sky, rather than the block under it being broken.
|
||||||
if(this.fallDistance > 10){
|
if(this.fallDistance > 10){
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class EntityHealAura extends EntityMagicConstruct {
|
|||||||
target.motionZ = velZ;
|
target.motionZ = velZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
}else if(target.getHealth() < target.getMaxHealth() && this.ticksExisted % 5 == 0){
|
}else if(target.getHealth() < target.getMaxHealth() && target.ticksExisted % 5 == 0){
|
||||||
target.heal(Spells.healing_aura.getProperty(Spell.HEALTH).floatValue() * damageMultiplier);
|
target.heal(Spells.healing_aura.getProperty(Spell.HEALTH).floatValue() * damageMultiplier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,9 +29,9 @@ public class EntityIceSpike extends EntityMagicConstruct {
|
|||||||
this.setRotation(-facing.getHorizontalAngle(), WizardryUtilities.getPitch(facing));
|
this.setRotation(-facing.getHorizontalAngle(), WizardryUtilities.getPitch(facing));
|
||||||
float yaw = (-facing.getHorizontalAngle()) * (float)Math.PI/180;
|
float yaw = (-facing.getHorizontalAngle()) * (float)Math.PI/180;
|
||||||
float pitch = (WizardryUtilities.getPitch(facing) - 90) * (float)Math.PI/180;
|
float pitch = (WizardryUtilities.getPitch(facing) - 90) * (float)Math.PI/180;
|
||||||
Vec3d min = new Vec3d(-width/2, 0, -width/2).rotatePitch(pitch).rotateYaw(yaw);
|
Vec3d min = this.getPositionVector().add(new Vec3d(-width/2, 0, -width/2).rotatePitch(pitch).rotateYaw(yaw));
|
||||||
Vec3d max = new Vec3d(width/2, height, width/2).rotatePitch(pitch).rotateYaw(yaw);
|
Vec3d max = this.getPositionVector().add(new Vec3d(width/2, height, width/2).rotatePitch(pitch).rotateYaw(yaw));
|
||||||
this.setEntityBoundingBox(new AxisAlignedBB(this.getPositionVector().add(min), this.getPositionVector().add(max)));
|
this.setEntityBoundingBox(new AxisAlignedBB(min.x, min.y, min.z, max.x, max.y, max.z));
|
||||||
}
|
}
|
||||||
|
|
||||||
public EnumFacing getFacing(){
|
public EnumFacing getFacing(){
|
||||||
|
|||||||
@@ -213,6 +213,7 @@ public class EntityAIAttackSpell<T extends EntityLiving & ISpellCaster> extends
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is only called when spell casting starts so ticksInUse is always zero
|
||||||
if(spell.cast(attacker.world, attacker, EnumHand.MAIN_HAND, 0, target, modifiers)){
|
if(spell.cast(attacker.world, attacker, EnumHand.MAIN_HAND, 0, target, modifiers)){
|
||||||
|
|
||||||
if(spell.isContinuous){
|
if(spell.isContinuous){
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
|||||||
// Field implementations
|
// Field implementations
|
||||||
private List<Spell> spells = new ArrayList<Spell>(4);
|
private List<Spell> spells = new ArrayList<Spell>(4);
|
||||||
private Spell continuousSpell;
|
private Spell continuousSpell;
|
||||||
|
private int spellCounter;
|
||||||
|
|
||||||
public EntityEvilWizard(World world){
|
public EntityEvilWizard(World world){
|
||||||
|
|
||||||
@@ -175,6 +176,16 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
|||||||
public Spell getContinuousSpell(){
|
public Spell getContinuousSpell(){
|
||||||
return this.continuousSpell;
|
return this.continuousSpell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSpellCounter(int count){
|
||||||
|
spellCounter = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSpellCounter(){
|
||||||
|
return spellCounter;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAimingError(EnumDifficulty difficulty){
|
public int getAimingError(EnumDifficulty difficulty){
|
||||||
@@ -252,7 +263,7 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
|||||||
// When right-clicked with a spell book in creative, sets one of the spells to that spell
|
// When right-clicked with a spell book in creative, sets one of the spells to that spell
|
||||||
if(player.isCreative() && stack.getItem() instanceof ItemSpellBook){
|
if(player.isCreative() && stack.getItem() instanceof ItemSpellBook){
|
||||||
Spell spell = Spell.byMetadata(stack.getItemDamage());
|
Spell spell = Spell.byMetadata(stack.getItemDamage());
|
||||||
if(this.spells.size() >= 4 && spell.canBeCastByNPCs()){
|
if(this.spells.size() >= 4 && spell.canBeCastBy(this, true)){
|
||||||
// The set(...) method returns the element that was replaced - neat!
|
// The set(...) method returns the element that was replaced - neat!
|
||||||
player.sendMessage(new TextComponentTranslation("item." + Wizardry.MODID + ":spell_book.apply_to_wizard",
|
player.sendMessage(new TextComponentTranslation("item." + Wizardry.MODID + ":spell_book.apply_to_wizard",
|
||||||
this.getDisplayName(), this.spells.set(rand.nextInt(3) + 1, spell).getNameForTranslationFormatted(),
|
this.getDisplayName(), this.spells.set(rand.nextInt(3) + 1, spell).getNameForTranslationFormatted(),
|
||||||
@@ -269,9 +280,9 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
|||||||
super.writeEntityToNBT(nbt);
|
super.writeEntityToNBT(nbt);
|
||||||
nbt.setInteger("element", this.getElement().ordinal());
|
nbt.setInteger("element", this.getElement().ordinal());
|
||||||
nbt.setInteger("skin", this.textureIndex);
|
nbt.setInteger("skin", this.textureIndex);
|
||||||
nbt.setTag("spells", NBTExtras.listToNBT(spells, spell -> new NBTTagInt(spell.metadata())));
|
NBTExtras.storeTagSafely(nbt, "spells", NBTExtras.listToNBT(spells, spell -> new NBTTagInt(spell.metadata())));
|
||||||
nbt.setBoolean("hasStructure", this.hasStructure);
|
nbt.setBoolean("hasStructure", this.hasStructure);
|
||||||
nbt.setTag("groupUUIDs", NBTExtras.listToNBT(groupUUIDs, NBTUtil::createUUIDTag));
|
NBTExtras.storeTagSafely(nbt, "groupUUIDs", NBTExtras.listToNBT(groupUUIDs, NBTUtil::createUUIDTag));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -369,7 +380,7 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
|||||||
// All wizards know magic missile, even if it is disabled.
|
// All wizards know magic missile, even if it is disabled.
|
||||||
spells.add(Spells.magic_missile);
|
spells.add(Spells.magic_missile);
|
||||||
|
|
||||||
Tier maxTier = EntityWizard.populateSpells(spells, element, hasStructure, 3, rand);
|
Tier maxTier = EntityWizard.populateSpells(this, spells, element, hasStructure, 3, rand);
|
||||||
|
|
||||||
// Now done after the spells so it can take the tier into account. For evil wizards this is slightly different;
|
// Now done after the spells so it can take the tier into account. For evil wizards this is slightly different;
|
||||||
// it picks a random wand which is at least a high enough tier for the spells the wizard has.
|
// it picks a random wand which is at least a high enough tier for the spells the wizard has.
|
||||||
@@ -392,7 +403,7 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onCheckSpawnEvent(LivingSpawnEvent.CheckSpawn event){
|
public static void onCheckSpawnEvent(LivingSpawnEvent.CheckSpawn event){
|
||||||
// We have no way of checking if it's a spawner in getCanSpawnHere() so this has to be done here instead
|
// We have no way of checking if it's a spawner in getCanSpawnHere() so this has to be done here instead
|
||||||
if(!event.isSpawner()){
|
if(event.getEntityLiving() instanceof EntityEvilWizard && !event.isSpawner()){
|
||||||
if(!ArrayUtils.contains(Wizardry.settings.mobSpawnDimensions, event.getWorld().provider.getDimension()))
|
if(!ArrayUtils.contains(Wizardry.settings.mobSpawnDimensions, event.getWorld().provider.getDimension()))
|
||||||
event.setResult(Event.Result.DENY);
|
event.setResult(Event.Result.DENY);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ public class EntityIceGiant extends EntityIronGolem implements ISummonedCreature
|
|||||||
this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
|
this.tasks.addTask(6, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
|
||||||
this.tasks.addTask(7, new EntityAILookIdle(this));
|
this.tasks.addTask(7, new EntityAILookIdle(this));
|
||||||
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
|
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
|
||||||
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<EntityLivingBase>(this, EntityLivingBase.class,
|
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityLivingBase.class,
|
||||||
0, false, true, this.getTargetSelector()));
|
0, false, true, this.getTargetSelector()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ public class EntityIceWraith extends EntityBlazeMinion {
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onCheckSpawnEvent(LivingSpawnEvent.CheckSpawn event){
|
public static void onCheckSpawnEvent(LivingSpawnEvent.CheckSpawn event){
|
||||||
// We have no way of checking if it's a spawner in getCanSpawnHere() so this has to be done here instead
|
// We have no way of checking if it's a spawner in getCanSpawnHere() so this has to be done here instead
|
||||||
if(!event.isSpawner()){
|
if(event.getEntityLiving() instanceof EntityLightningWraith && !event.isSpawner()){
|
||||||
if(!ArrayUtils.contains(Wizardry.settings.mobSpawnDimensions, event.getWorld().provider.getDimension()))
|
if(!ArrayUtils.contains(Wizardry.settings.mobSpawnDimensions, event.getWorld().provider.getDimension()))
|
||||||
event.setResult(Event.Result.DENY);
|
event.setResult(Event.Result.DENY);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,9 +19,6 @@ import net.minecraftforge.fml.common.eventhandler.Event;
|
|||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.function.IntPredicate;
|
|
||||||
|
|
||||||
@Mod.EventBusSubscriber
|
@Mod.EventBusSubscriber
|
||||||
public class EntityLightningWraith extends EntityBlazeMinion {
|
public class EntityLightningWraith extends EntityBlazeMinion {
|
||||||
|
|
||||||
@@ -89,7 +86,7 @@ public class EntityLightningWraith extends EntityBlazeMinion {
|
|||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onCheckSpawnEvent(LivingSpawnEvent.CheckSpawn event){
|
public static void onCheckSpawnEvent(LivingSpawnEvent.CheckSpawn event){
|
||||||
// We have no way of checking if it's a spawner in getCanSpawnHere() so this has to be done here instead
|
// We have no way of checking if it's a spawner in getCanSpawnHere() so this has to be done here instead
|
||||||
if(!event.isSpawner()){
|
if(event.getEntityLiving() instanceof EntityLightningWraith && !event.isSpawner()){
|
||||||
if(!event.getWorld().isThundering()) event.setResult(Event.Result.DENY);
|
if(!event.getWorld().isThundering()) event.setResult(Event.Result.DENY);
|
||||||
if(!ArrayUtils.contains(Wizardry.settings.mobSpawnDimensions, event.getWorld().provider.getDimension()))
|
if(!ArrayUtils.contains(Wizardry.settings.mobSpawnDimensions, event.getWorld().provider.getDimension()))
|
||||||
event.setResult(Event.Result.DENY);
|
event.setResult(Event.Result.DENY);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public class EntityPhoenix extends EntitySummonedCreature implements ISpellCaste
|
|||||||
private EntityAIAttackSpell<EntityPhoenix> spellAttackAI = new EntityAIAttackSpell<>(this, AISpeed, 15f, 60, 140);
|
private EntityAIAttackSpell<EntityPhoenix> spellAttackAI = new EntityAIAttackSpell<>(this, AISpeed, 15f, 60, 140);
|
||||||
|
|
||||||
private Spell continuousSpell;
|
private Spell continuousSpell;
|
||||||
|
private int spellCounter;
|
||||||
|
|
||||||
private static final List<Spell> attack = Collections.singletonList(Spells.flame_ray);
|
private static final List<Spell> attack = Collections.singletonList(Spells.flame_ray);
|
||||||
|
|
||||||
@@ -50,7 +51,7 @@ public class EntityPhoenix extends EntitySummonedCreature implements ISpellCaste
|
|||||||
this.tasks.addTask(3, new EntityAILookIdle(this));
|
this.tasks.addTask(3, new EntityAILookIdle(this));
|
||||||
// this.targetTasks.addTask(0, new EntityAIMoveTowardsTarget(this, 1, 10));
|
// this.targetTasks.addTask(0, new EntityAIMoveTowardsTarget(this, 1, 10));
|
||||||
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true));
|
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true));
|
||||||
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<EntityLivingBase>(this, EntityLivingBase.class,
|
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityLivingBase.class,
|
||||||
0, false, true, this.getTargetSelector()));
|
0, false, true, this.getTargetSelector()));
|
||||||
|
|
||||||
this.setAIMoveSpeed((float)AISpeed);
|
this.setAIMoveSpeed((float)AISpeed);
|
||||||
@@ -76,6 +77,16 @@ public class EntityPhoenix extends EntitySummonedCreature implements ISpellCaste
|
|||||||
continuousSpell = spell;
|
continuousSpell = spell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSpellCounter(int count){
|
||||||
|
spellCounter = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSpellCounter(){
|
||||||
|
return spellCounter;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasRangedAttack(){
|
public boolean hasRangedAttack(){
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class EntityShadowWraith extends EntitySummonedCreature implements ISpell
|
|||||||
this.tasks.addTask(2, new EntityAIWander(this, AISpeed));
|
this.tasks.addTask(2, new EntityAIWander(this, AISpeed));
|
||||||
this.tasks.addTask(3, new EntityAILookIdle(this));
|
this.tasks.addTask(3, new EntityAILookIdle(this));
|
||||||
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true));
|
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true));
|
||||||
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<EntityLivingBase>(this, EntityLivingBase.class,
|
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityLivingBase.class,
|
||||||
0, false, true, this.getTargetSelector()));
|
0, false, true, this.getTargetSelector()));
|
||||||
|
|
||||||
this.setAIMoveSpeed((float)AISpeed);
|
this.setAIMoveSpeed((float)AISpeed);
|
||||||
@@ -61,21 +61,6 @@ public class EntityShadowWraith extends EntitySummonedCreature implements ISpell
|
|||||||
return attack;
|
return attack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SpellModifiers getModifiers(){
|
|
||||||
return new SpellModifiers();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Spell getContinuousSpell(){
|
|
||||||
return Spells.none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setContinuousSpell(Spell spell){
|
|
||||||
// Doesn't use continuous spells.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void applyEntityAttributes(){
|
protected void applyEntityAttributes(){
|
||||||
super.applyEntityAttributes();
|
super.applyEntityAttributes();
|
||||||
|
|||||||
@@ -59,21 +59,6 @@ public class EntityStormElemental extends EntitySummonedCreature implements ISpe
|
|||||||
return attack;
|
return attack;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SpellModifiers getModifiers(){
|
|
||||||
return new SpellModifiers();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Spell getContinuousSpell(){
|
|
||||||
return Spells.none;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setContinuousSpell(Spell spell){
|
|
||||||
// Doesn't use continuous spells.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void applyEntityAttributes(){
|
protected void applyEntityAttributes(){
|
||||||
super.applyEntityAttributes();
|
super.applyEntityAttributes();
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
|||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
import net.minecraftforge.oredict.OreDictionary;
|
import net.minecraftforge.oredict.OreDictionary;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -83,6 +84,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
|||||||
// Field implementations
|
// Field implementations
|
||||||
private List<Spell> spells = new ArrayList<Spell>(4);
|
private List<Spell> spells = new ArrayList<Spell>(4);
|
||||||
private Spell continuousSpell;
|
private Spell continuousSpell;
|
||||||
|
private int spellCounter;
|
||||||
|
|
||||||
/** A set of the positions of the blocks that are part of this wizard's tower. */
|
/** A set of the positions of the blocks that are part of this wizard's tower. */
|
||||||
private Set<BlockPos> towerBlocks;
|
private Set<BlockPos> towerBlocks;
|
||||||
@@ -187,7 +189,17 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
|||||||
public Spell getContinuousSpell(){
|
public Spell getContinuousSpell(){
|
||||||
return this.continuousSpell;
|
return this.continuousSpell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSpellCounter(int count){
|
||||||
|
spellCounter = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSpellCounter(){
|
||||||
|
return spellCounter;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getAimingError(EnumDifficulty difficulty){
|
public int getAimingError(EnumDifficulty difficulty){
|
||||||
// Being more intelligent than skeletons, wizards are a little more accurate.
|
// Being more intelligent than skeletons, wizards are a little more accurate.
|
||||||
@@ -218,7 +230,8 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
|||||||
// Copied from EntityVillager
|
// Copied from EntityVillager
|
||||||
if(!this.world.isRemote && this.livingSoundTime > -this.getTalkInterval() + 20){
|
if(!this.world.isRemote && this.livingSoundTime > -this.getTalkInterval() + 20){
|
||||||
this.livingSoundTime = -this.getTalkInterval();
|
this.livingSoundTime = -this.getTalkInterval();
|
||||||
this.playSound(stack.isEmpty() ? WizardrySounds.ENTITY_WIZARD_NO : WizardrySounds.ENTITY_WIZARD_YES, this.getSoundVolume(), this.getSoundPitch());
|
SoundEvent yes = Wizardry.tisTheSeason ? WizardrySounds.ENTITY_WIZARD_HOHOHO : WizardrySounds.ENTITY_WIZARD_YES;
|
||||||
|
this.playSound(stack.isEmpty() ? WizardrySounds.ENTITY_WIZARD_NO : yes, this.getSoundVolume(), this.getSoundPitch());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,6 +269,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SoundEvent getAmbientSound(){
|
protected SoundEvent getAmbientSound(){
|
||||||
|
if(Wizardry.tisTheSeason) return WizardrySounds.ENTITY_WIZARD_HOHOHO;
|
||||||
return this.isTrading() ? WizardrySounds.ENTITY_WIZARD_TRADING : WizardrySounds.ENTITY_WIZARD_AMBIENT;
|
return this.isTrading() ? WizardrySounds.ENTITY_WIZARD_TRADING : WizardrySounds.ENTITY_WIZARD_AMBIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,7 +371,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
|||||||
// When right-clicked with a spell book in creative, sets one of the spells to that spell
|
// When right-clicked with a spell book in creative, sets one of the spells to that spell
|
||||||
if(player.isCreative() && stack.getItem() instanceof ItemSpellBook){
|
if(player.isCreative() && stack.getItem() instanceof ItemSpellBook){
|
||||||
Spell spell = Spell.byMetadata(stack.getItemDamage());
|
Spell spell = Spell.byMetadata(stack.getItemDamage());
|
||||||
if(this.spells.size() >= 4 && spell.canBeCastByNPCs()){
|
if(this.spells.size() >= 4 && spell.canBeCastBy(this, true)){
|
||||||
// The set(...) method returns the element that was replaced - neat!
|
// The set(...) method returns the element that was replaced - neat!
|
||||||
player.sendMessage(new TextComponentTranslation("item." + Wizardry.MODID + ":spell_book.apply_to_wizard",
|
player.sendMessage(new TextComponentTranslation("item." + Wizardry.MODID + ":spell_book.apply_to_wizard",
|
||||||
this.getDisplayName(), this.spells.set(rand.nextInt(3) + 1, spell).getNameForTranslationFormatted(),
|
this.getDisplayName(), this.spells.set(rand.nextInt(3) + 1, spell).getNameForTranslationFormatted(),
|
||||||
@@ -387,15 +401,15 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
|||||||
super.writeEntityToNBT(nbt);
|
super.writeEntityToNBT(nbt);
|
||||||
|
|
||||||
if(this.trades != null){
|
if(this.trades != null){
|
||||||
nbt.setTag("trades", this.trades.getRecipiesAsTags());
|
NBTExtras.storeTagSafely(nbt, "trades", this.trades.getRecipiesAsTags());
|
||||||
}
|
}
|
||||||
|
|
||||||
nbt.setInteger("element", this.getElement().ordinal());
|
nbt.setInteger("element", this.getElement().ordinal());
|
||||||
nbt.setInteger("skin", this.textureIndex);
|
nbt.setInteger("skin", this.textureIndex);
|
||||||
nbt.setTag("spells", NBTExtras.listToNBT(spells, spell -> new NBTTagInt(spell.metadata())));
|
NBTExtras.storeTagSafely(nbt, "spells", NBTExtras.listToNBT(spells, spell -> new NBTTagInt(spell.metadata())));
|
||||||
|
|
||||||
if(this.towerBlocks != null && this.towerBlocks.size() > 0){
|
if(this.towerBlocks != null && this.towerBlocks.size() > 0){
|
||||||
nbt.setTag("towerBlocks", NBTExtras.listToNBT(this.towerBlocks, NBTUtil::createPosTag));
|
NBTExtras.storeTagSafely(nbt, "towerBlocks", NBTExtras.listToNBT(this.towerBlocks, NBTUtil::createPosTag));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,7 +428,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
|||||||
this.spells = (List<Spell>)NBTExtras.NBTToList(nbt.getTagList("spells", NBT.TAG_INT),
|
this.spells = (List<Spell>)NBTExtras.NBTToList(nbt.getTagList("spells", NBT.TAG_INT),
|
||||||
(NBTTagInt tag) -> Spell.byMetadata(tag.getInt()));
|
(NBTTagInt tag) -> Spell.byMetadata(tag.getInt()));
|
||||||
|
|
||||||
NBTTagList tagList = nbt.getTagList("towerBlocks", NBT.TAG_LONG);
|
NBTTagList tagList = nbt.getTagList("towerBlocks", NBT.TAG_COMPOUND);
|
||||||
if(!tagList.isEmpty()){
|
if(!tagList.isEmpty()){
|
||||||
this.towerBlocks = new HashSet<>(NBTExtras.NBTToList(tagList, NBTUtil::getPosFromTag));
|
this.towerBlocks = new HashSet<>(NBTExtras.NBTToList(tagList, NBTUtil::getPosFromTag));
|
||||||
}else{
|
}else{
|
||||||
@@ -574,12 +588,14 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
|||||||
|
|
||||||
// TODO: Switch all of this over to some kind of loot pool system?
|
// TODO: Switch all of this over to some kind of loot pool system?
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
private ItemStack getRandomPrice(Tier tier){
|
private ItemStack getRandomPrice(Tier tier){
|
||||||
|
|
||||||
Map<ResourceLocation, Integer> map = Wizardry.settings.currencyItems;
|
Map<Pair<ResourceLocation, Short>, Integer> map = Wizardry.settings.currencyItems;
|
||||||
// This isn't that efficient but it's not called very often really so it doesn't matter
|
// This isn't that efficient but it's not called very often really so it doesn't matter
|
||||||
ResourceLocation itemName = map.keySet().toArray(new ResourceLocation[0])[rand.nextInt(map.size())];
|
Pair<ResourceLocation, Short> itemName = map.keySet().toArray(new Pair[0])[rand.nextInt(map.size())];
|
||||||
Item item = Item.REGISTRY.getObject(itemName);
|
Item item = Item.REGISTRY.getObject(itemName.getLeft());
|
||||||
|
short meta = itemName.getRight();
|
||||||
int value;
|
int value;
|
||||||
|
|
||||||
if(item == null){
|
if(item == null){
|
||||||
@@ -593,7 +609,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
|||||||
// ((tier.ordinal() + 1) * 16 + rand.nextInt(6)) gives a 'value' for the item being bought
|
// ((tier.ordinal() + 1) * 16 + rand.nextInt(6)) gives a 'value' for the item being bought
|
||||||
// This is then divided by the value of the currency item to give a price
|
// This is then divided by the value of the currency item to give a price
|
||||||
// The absolute maximum stack size that can result from this calculation (with value = 1) is 64.
|
// The absolute maximum stack size that can result from this calculation (with value = 1) is 64.
|
||||||
return new ItemStack(item, (8 + tier.ordinal() * 16 + rand.nextInt(9)) / value);
|
return new ItemStack(item, (8 + tier.ordinal() * 16 + rand.nextInt(9)) / value, meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemStack getRandomItemOfTier(Tier tier){
|
private ItemStack getRandomItemOfTier(Tier tier){
|
||||||
@@ -750,7 +766,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
|||||||
// All wizards know magic missile, even if it is disabled.
|
// All wizards know magic missile, even if it is disabled.
|
||||||
spells.add(Spells.magic_missile);
|
spells.add(Spells.magic_missile);
|
||||||
|
|
||||||
Tier maxTier = populateSpells(spells, element, false, 3, rand);
|
Tier maxTier = populateSpells(this, spells, element, false, 3, rand);
|
||||||
|
|
||||||
// Now done after the spells so it can take the tier into account.
|
// Now done after the spells so it can take the tier into account.
|
||||||
ItemStack wand = new ItemStack(WizardryItems.getWand(maxTier, element));
|
ItemStack wand = new ItemStack(WizardryItems.getWand(maxTier, element));
|
||||||
@@ -767,19 +783,21 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
|||||||
/**
|
/**
|
||||||
* Adds n random spells to the given list. The spells will be of the given element if possible. Extracted as a
|
* Adds n random spells to the given list. The spells will be of the given element if possible. Extracted as a
|
||||||
* separate function since it was the same in both EntityWizard and EntityEvilWizard.
|
* separate function since it was the same in both EntityWizard and EntityEvilWizard.
|
||||||
*
|
*
|
||||||
|
* @param wizard The wizard whose spells are to be populated.
|
||||||
* @param spells The spell list to be populated.
|
* @param spells The spell list to be populated.
|
||||||
* @param e The element that the spells should belong to, or {@link Element#MAGIC} for a random element each time.
|
* @param e The element that the spells should belong to, or {@link Element#MAGIC} for a random element each time.
|
||||||
|
* @param master Whether to include master spells.
|
||||||
* @param n The number of spells to add.
|
* @param n The number of spells to add.
|
||||||
* @param random A random number generator to use.
|
* @param random A random number generator to use.
|
||||||
* @return The tier of the highest-tier spell that was added to the list.
|
* @return The tier of the highest-tier spell that was added to the list.
|
||||||
*/
|
*/
|
||||||
static Tier populateSpells(List<Spell> spells, Element e, boolean master, int n, Random random){
|
static Tier populateSpells(final EntityLiving wizard, List<Spell> spells, Element e, boolean master, int n, Random random){
|
||||||
|
|
||||||
// This is the tier of the highest tier spell added.
|
// This is the tier of the highest tier spell added.
|
||||||
Tier maxTier = Tier.NOVICE;
|
Tier maxTier = Tier.NOVICE;
|
||||||
|
|
||||||
List<Spell> npcSpells = Spell.getSpells(Spell.npcSpells);
|
List<Spell> npcSpells = Spell.getSpells(s -> s.canBeCastBy(wizard, false));
|
||||||
npcSpells.removeIf(s -> !s.applicableForItem(WizardryItems.spell_book));
|
npcSpells.removeIf(s -> !s.applicableForItem(WizardryItems.spell_book));
|
||||||
|
|
||||||
for(int i = 0; i < n; i++){
|
for(int i = 0; i < n; i++){
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ import java.util.List;
|
|||||||
* packets) is handled by that class, and all the implementor needs to do is decide which spell(s) to select.
|
* packets) is handled by that class, and all the implementor needs to do is decide which spell(s) to select.
|
||||||
* <p></p>
|
* <p></p>
|
||||||
* This class also allows Wizardry to do all the syncing necessary for continuous spell casting. All the implementor
|
* This class also allows Wizardry to do all the syncing necessary for continuous spell casting. All the implementor
|
||||||
* needs to do is store the actual fields involved.
|
* needs to do is store the actual fields involved, by implementing {@link ISpellCaster#setContinuousSpell(Spell)},
|
||||||
|
* {@link ISpellCaster#getContinuousSpell()}, {@link ISpellCaster#setSpellCounter(int)}, {@link ISpellCaster#getSpellCounter()}
|
||||||
|
* and {@link ISpellCaster#getModifiers()}.
|
||||||
*/
|
*/
|
||||||
/* Perhaps this should be a capability? Though I can't help thinking they're mainly for attaching data to vanilla
|
/* Perhaps this should be a capability? Though I can't help thinking they're mainly for attaching data to vanilla
|
||||||
* classes, rather than custom ones. For now, the main purpose of this is to centralise code within wizardry itself, and
|
* classes, rather than custom ones. For now, the main purpose of this is to centralise code within wizardry itself, and
|
||||||
@@ -36,10 +38,10 @@ public interface ISpellCaster {
|
|||||||
*
|
*
|
||||||
* @return A list of {@link Spell} instances. A random spell from this list will be cast when the entity attacks.
|
* @return A list of {@link Spell} instances. A random spell from this list will be cast when the entity attacks.
|
||||||
* The list will not be modified by the AI class and can therefore be an immutable list. The spells in the
|
* The list will not be modified by the AI class and can therefore be an immutable list. The spells in the
|
||||||
* list <b>must</b> be castable by NPCs (i.e. {@link Spell#canBeCastByNPCs()} returns true).
|
* list <b>must</b> be castable by NPCs (i.e. {@link Spell#canBeCastBy(net.minecraft.entity.EntityLiving, boolean)} returns true).
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public List<Spell> getSpells();
|
List<Spell> getSpells();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called each time the entity attacks to get the modifiers to apply to the spell.
|
* Called each time the entity attacks to get the modifiers to apply to the spell.
|
||||||
@@ -48,31 +50,47 @@ public interface ISpellCaster {
|
|||||||
* required, pass in an empty {@code SpellModifiers} object.
|
* required, pass in an empty {@code SpellModifiers} object.
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public SpellModifiers getModifiers();
|
default SpellModifiers getModifiers(){
|
||||||
|
return new SpellModifiers(); // May seem wasteful but this should never be called so it doesn't matter
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the continuous spell that is currently being cast, or the None spell if there is none. Implementors
|
* Returns the continuous spell that is currently being cast, or the None spell if there is none. Implementors
|
||||||
* should simply store this as a private field and return it here. Will be synced by the AI class, but whether it is
|
* should simply store this as a private field and return it here. Will be synced by the AI class, but whether it is
|
||||||
* saved to NBT is up to you. If the implementing class does not deal with continuous spells, just return
|
* saved to NBT is up to you. If the implementing class only ever uses one continuous spell, do <b>not</b> just
|
||||||
* {@link Spells#none}. If the implementing class only ever uses one continuous spell, do <b>not</b> just return
|
* return that spell; the field must still be stored.
|
||||||
* that spell; the field must still be stored.
|
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public Spell getContinuousSpell();
|
default Spell getContinuousSpell(){
|
||||||
|
return Spells.none;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the continuous spell that is currently being cast, or the None spell if there is none. Implementors should
|
* Sets the continuous spell that is currently being cast, or the None spell if there is none. Implementors should
|
||||||
* simply store this as a private field and assign it here. Will be synced by the AI class, but whether it is saved
|
* simply store this as a private field and assign it here. Will be synced by the AI class, but whether it is saved
|
||||||
* to NBT is up to you. If the implementing class does not deal with continuous spells, leave this method blank.
|
* to NBT is up to you. If the implementing class does not deal with continuous spells, leave this method blank.
|
||||||
*/
|
*/
|
||||||
public void setContinuousSpell(Spell spell);
|
default void setContinuousSpell(Spell spell){
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the number of ticks the current spell has been cast for. Implementors should simply store this as a
|
||||||
|
* private field and return it here. This is only used client-side. */
|
||||||
|
default int getSpellCounter(){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the number of ticks the current spell has been cast for. Implementors should simply store this as a
|
||||||
|
* private field and assign it here. This is only used client-side. */
|
||||||
|
default void setSpellCounter(int count){
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the aiming arror for the given difficulty, used in projectile spells. Defaults to the values used by
|
* Returns the aiming error for the given difficulty, used in projectile spells. Defaults to the values used by
|
||||||
* skeletons, which are: Easy - 10, Normal - 6, Hard - 2, Peaceful - 10 (rarely used).
|
* skeletons, which are: Easy - 10, Normal - 6, Hard - 2, Peaceful - 10 (rarely used).
|
||||||
*/
|
*/
|
||||||
// This is what default methods are actually intended for!
|
default int getAimingError(EnumDifficulty difficulty) {
|
||||||
public default int getAimingError(EnumDifficulty difficulty) {
|
|
||||||
return WizardryUtilities.getDefaultAimingError(difficulty);
|
return WizardryUtilities.getDefaultAimingError(difficulty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -221,7 +221,8 @@ public interface ISummonedCreature extends IEntityAdditionalSpawnData, IEntityOw
|
|||||||
* possible for implementors to override this in order to do something special when selecting a target.
|
* possible for implementors to override this in order to do something special when selecting a target.
|
||||||
*/
|
*/
|
||||||
default Predicate<Entity> getTargetSelector(){
|
default Predicate<Entity> getTargetSelector(){
|
||||||
return entity -> getCaster() == null ? entity instanceof EntityPlayer : !entity.isInvisible() && isValidTarget(entity);
|
return entity -> !entity.isInvisible() && (getCaster() == null ? entity instanceof EntityPlayer &&
|
||||||
|
!((EntityPlayer)entity).isCreative() : isValidTarget(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,11 +9,15 @@ import electroblob.wizardry.util.ParticleBuilder;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLiving;
|
import net.minecraft.entity.EntityLiving;
|
||||||
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.projectile.EntitySmallFireball;
|
import net.minecraft.entity.projectile.EntitySmallFireball;
|
||||||
import net.minecraft.init.Blocks;
|
import net.minecraft.init.Blocks;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.RayTraceResult;
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
@@ -131,6 +135,54 @@ public class EntityMagicFireball extends EntityMagicProjectile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBeCollidedWith(){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getCollisionBorderSize(){
|
||||||
|
return 1.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean attackEntityFrom(DamageSource source, float amount){
|
||||||
|
|
||||||
|
if(this.isEntityInvulnerable(source)){
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
this.markVelocityChanged();
|
||||||
|
|
||||||
|
if(source.getTrueSource() != null){
|
||||||
|
|
||||||
|
Vec3d vec3d = source.getTrueSource().getLookVec();
|
||||||
|
|
||||||
|
if(vec3d != null){
|
||||||
|
|
||||||
|
double speed = MathHelper.sqrt(motionX * motionX + motionY * motionY + motionZ * motionZ);
|
||||||
|
|
||||||
|
this.motionX = vec3d.x * speed;
|
||||||
|
this.motionY = vec3d.y * speed;
|
||||||
|
this.motionZ = vec3d.z * speed;
|
||||||
|
|
||||||
|
this.lifetime = 160;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(source.getTrueSource() instanceof EntityLivingBase){
|
||||||
|
this.setCaster((EntityLivingBase)source.getTrueSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setLifetime(int lifetime){
|
public void setLifetime(int lifetime){
|
||||||
this.lifetime = lifetime;
|
this.lifetime = lifetime;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package electroblob.wizardry.entity.projectile;
|
package electroblob.wizardry.entity.projectile;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
@@ -44,15 +45,34 @@ public class EntityMagicMissile extends EntityMagicArrow {
|
|||||||
public void tickInAir(){
|
public void tickInAir(){
|
||||||
|
|
||||||
if(this.world.isRemote){
|
if(this.world.isRemote){
|
||||||
ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 0.03, true).clr(1, 1, 0.65f).fade(0.7f, 0, 1)
|
|
||||||
.time(20 + rand.nextInt(10)).spawn(world);
|
if(Wizardry.tisTheSeason){
|
||||||
|
|
||||||
if(this.ticksExisted > 1){ // Don't spawn particles behind where it started!
|
ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 0.03, true).clr(0.8f, 0.15f, 0.15f)
|
||||||
double x = posX - motionX/2;
|
.time(20 + rand.nextInt(10)).spawn(world);
|
||||||
double y = posY - motionY/2;
|
|
||||||
double z = posZ - motionZ/2;
|
ParticleBuilder.create(Type.SNOW).pos(posX, posY, posZ).spawn(world);
|
||||||
ParticleBuilder.create(Type.SPARKLE, rand, x, y, z, 0.03, true).clr(1, 1, 0.65f).fade(0.7f, 0, 1)
|
|
||||||
.time(20 + rand.nextInt(10)).spawn(world);
|
if(this.ticksExisted > 1){ // Don't spawn particles behind where it started!
|
||||||
|
double x = posX - motionX / 2;
|
||||||
|
double y = posY - motionY / 2;
|
||||||
|
double z = posZ - motionZ / 2;
|
||||||
|
ParticleBuilder.create(Type.SPARKLE, rand, x, y, z, 0.03, true).clr(0.15f, 0.7f, 0.15f)
|
||||||
|
.time(20 + rand.nextInt(10)).spawn(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
ParticleBuilder.create(Type.SPARKLE, rand, posX, posY, posZ, 0.03, true).clr(1, 1, 0.65f).fade(0.7f, 0, 1)
|
||||||
|
.time(20 + rand.nextInt(10)).spawn(world);
|
||||||
|
|
||||||
|
if(this.ticksExisted > 1){ // Don't spawn particles behind where it started!
|
||||||
|
double x = posX - motionX / 2;
|
||||||
|
double y = posY - motionY / 2;
|
||||||
|
double z = posZ - motionZ / 2;
|
||||||
|
ParticleBuilder.create(Type.SPARKLE, rand, x, y, z, 0.03, true).clr(1, 1, 0.65f).fade(0.7f, 0, 1)
|
||||||
|
.time(20 + rand.nextInt(10)).spawn(world);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public abstract class EntityMagicProjectile extends EntityThrowable implements I
|
|||||||
double dy = !this.hasNoGravity() ? target.getEntityBoundingBox().minY + (double)(target.height / 3.0f) - this.posY
|
double dy = !this.hasNoGravity() ? target.getEntityBoundingBox().minY + (double)(target.height / 3.0f) - this.posY
|
||||||
: target.getEntityBoundingBox().minY + (double)(target.height / 2.0f) - this.posY;
|
: target.getEntityBoundingBox().minY + (double)(target.height / 2.0f) - this.posY;
|
||||||
double dz = target.posZ - caster.posZ;
|
double dz = target.posZ - caster.posZ;
|
||||||
double horizontalDistance = (double)MathHelper.sqrt(dx * dx + dz * dz);
|
double horizontalDistance = MathHelper.sqrt(dx * dx + dz * dz);
|
||||||
|
|
||||||
if(horizontalDistance >= 1.0E-7D){
|
if(horizontalDistance >= 1.0E-7D){
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import electroblob.wizardry.util.ParticleBuilder.Type;
|
|||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.entity.EntityLiving;
|
import net.minecraft.entity.EntityLiving;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
|
||||||
import net.minecraft.init.MobEffects;
|
import net.minecraft.init.MobEffects;
|
||||||
import net.minecraft.potion.PotionEffect;
|
import net.minecraft.potion.PotionEffect;
|
||||||
import net.minecraft.util.EnumParticleTypes;
|
import net.minecraft.util.EnumParticleTypes;
|
||||||
@@ -66,12 +65,11 @@ public class EntitySmokeBomb extends EntityBomb {
|
|||||||
|
|
||||||
for(EntityLivingBase target : targets){
|
for(EntityLivingBase target : targets){
|
||||||
if(target != this.getThrower()){
|
if(target != this.getThrower()){
|
||||||
// Gives the target blindness if it is a player, mind trick otherwise (since this has the desired
|
// Gives the target blindness, and mind trick if it's not a player (since this has the desired
|
||||||
// effect of preventing targeting)
|
// effect of preventing targeting)
|
||||||
if(target instanceof EntityPlayer){
|
target.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, duration, 0));
|
||||||
target.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, duration, 0));
|
|
||||||
}else if(target instanceof EntityLiving){
|
if(target instanceof EntityLiving){
|
||||||
// New AI
|
|
||||||
((EntityLiving)target).setAttackTarget(null);
|
((EntityLiving)target).setAttackTarget(null);
|
||||||
target.addPotionEffect(new PotionEffect(WizardryPotions.mind_trick, duration, 0));
|
target.addPotionEffect(new PotionEffect(WizardryPotions.mind_trick, duration, 0));
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -38,7 +38,7 @@ public class WizardryAntiqueAtlasIntegration {
|
|||||||
* {@link electroblob.wizardry.Settings#autoTowerMarkers} is enabled. Server side only! */
|
* {@link electroblob.wizardry.Settings#autoTowerMarkers} is enabled. Server side only! */
|
||||||
public static void markTower(World world, int x, int z){
|
public static void markTower(World world, int x, int z){
|
||||||
if(enabled() && Wizardry.settings.autoTowerMarkers){
|
if(enabled() && Wizardry.settings.autoTowerMarkers){
|
||||||
AtlasAPI.getMarkerAPI().putGlobalMarker(world, false, TOWER_MARKER.toString(), "integration.antiqueatlas.marker." + TOWER_MARKER.toString(), x, z);
|
AtlasAPI.getMarkerAPI().putGlobalMarker(world, false, TOWER_MARKER.toString().replace(':', '.'), "integration.antiqueatlas.marker." + TOWER_MARKER.toString(), x, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ public class WizardryAntiqueAtlasIntegration {
|
|||||||
* {@link electroblob.wizardry.Settings#autoObeliskMarkers} is enabled. Server side only! */
|
* {@link electroblob.wizardry.Settings#autoObeliskMarkers} is enabled. Server side only! */
|
||||||
public static void markObelisk(World world, int x, int z){
|
public static void markObelisk(World world, int x, int z){
|
||||||
if(enabled() && Wizardry.settings.autoObeliskMarkers){
|
if(enabled() && Wizardry.settings.autoObeliskMarkers){
|
||||||
AtlasAPI.getMarkerAPI().putGlobalMarker(world, false, OBELISK_MARKER.toString(), "integration.antiqueatlas.marker." + OBELISK_MARKER.toString(), x, z);
|
AtlasAPI.getMarkerAPI().putGlobalMarker(world, false, OBELISK_MARKER.toString().replace(':', '.'), "integration.antiqueatlas.marker." + OBELISK_MARKER.toString(), x, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ public class WizardryAntiqueAtlasIntegration {
|
|||||||
* {@link electroblob.wizardry.Settings#autoShrineMarkers} is enabled. Server side only! */
|
* {@link electroblob.wizardry.Settings#autoShrineMarkers} is enabled. Server side only! */
|
||||||
public static void markShrine(World world, int x, int z){
|
public static void markShrine(World world, int x, int z){
|
||||||
if(enabled() && Wizardry.settings.autoShrineMarkers){
|
if(enabled() && Wizardry.settings.autoShrineMarkers){
|
||||||
AtlasAPI.getMarkerAPI().putGlobalMarker(world, false, SHRINE_MARKER.toString(), "integration.antiqueatlas.marker." + SHRINE_MARKER.toString(), x, z);
|
AtlasAPI.getMarkerAPI().putGlobalMarker(world, false, SHRINE_MARKER.toString().replace(':', '.'), "integration.antiqueatlas.marker." + SHRINE_MARKER.toString(), x, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ public interface IConjuredItem {
|
|||||||
*/
|
*/
|
||||||
default int getMaxDamageFromNBT(ItemStack stack, Spell spell){
|
default int getMaxDamageFromNBT(ItemStack stack, Spell spell){
|
||||||
|
|
||||||
|
if(!spell.arePropertiesInitialised()) return 600; // Failsafe, some edge-cases call this during preInit
|
||||||
|
|
||||||
float baseDuration = spell.getProperty(SpellConjuration.ITEM_LIFETIME).floatValue();
|
float baseDuration = spell.getProperty(SpellConjuration.ITEM_LIFETIME).floatValue();
|
||||||
|
|
||||||
if(stack.hasTagCompound() && stack.getTagCompound().hasKey(DURATION_MULTIPLIER_KEY)){
|
if(stack.hasTagCompound() && stack.getTagCompound().hasKey(DURATION_MULTIPLIER_KEY)){
|
||||||
|
|||||||
@@ -61,11 +61,10 @@ public class ItemArcaneTome extends Item {
|
|||||||
|
|
||||||
Tier tier = Tier.values()[stack.getItemDamage()];
|
Tier tier = Tier.values()[stack.getItemDamage()];
|
||||||
Tier tier2 = Tier.values()[stack.getItemDamage() - 1];
|
Tier tier2 = Tier.values()[stack.getItemDamage() - 1];
|
||||||
|
|
||||||
tooltip.add(tier.getDisplayNameWithFormatting());
|
tooltip.add(tier.getDisplayNameWithFormatting());
|
||||||
tooltip.add("\u00A77" + net.minecraft.client.resources.I18n.format("item." + Wizardry.MODID + ":arcane_tome.desc1",
|
Wizardry.proxy.addMultiLineDescription(tooltip, "item." + this.getRegistryName() + ".desc",
|
||||||
tier2.getDisplayNameWithFormatting()));
|
tier2.getDisplayNameWithFormatting() + "\u00A77", tier.getDisplayNameWithFormatting() + "\u00A77");
|
||||||
tooltip.add("\u00A77" + net.minecraft.client.resources.I18n.format("item." + Wizardry.MODID + ":arcane_tome.desc2",
|
|
||||||
tier.getDisplayNameWithFormatting() + "\u00A77"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -375,7 +375,7 @@ public class ItemArtefact extends Item {
|
|||||||
if(artefact == WizardryItems.ring_battlemage){
|
if(artefact == WizardryItems.ring_battlemage){
|
||||||
|
|
||||||
if(player.getHeldItemOffhand().getItem() instanceof ISpellCastingItem
|
if(player.getHeldItemOffhand().getItem() instanceof ISpellCastingItem
|
||||||
&& ImbueWeapon.isSword(player.getHeldItemMainhand().getItem())){
|
&& ImbueWeapon.isSword(player.getHeldItemMainhand())){
|
||||||
modifiers.set(SpellModifiers.POTENCY, 1.1f * potency, false);
|
modifiers.set(SpellModifiers.POTENCY, 1.1f * potency, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -639,6 +639,7 @@ public class ItemArtefact extends Item {
|
|||||||
|
|
||||||
WizardryUtilities.getEntitiesWithinRadius(3, player.posX, player.posY, player.posZ, world).stream()
|
WizardryUtilities.getEntitiesWithinRadius(3, player.posX, player.posY, player.posZ, world).stream()
|
||||||
.filter(WizardryUtilities::isLiving)
|
.filter(WizardryUtilities::isLiving)
|
||||||
|
.filter(e -> e != player)
|
||||||
.min(Comparator.comparingDouble(player::getDistanceSq))
|
.min(Comparator.comparingDouble(player::getDistanceSq))
|
||||||
.ifPresent(target -> {
|
.ifPresent(target -> {
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package electroblob.wizardry.item;
|
package electroblob.wizardry.item;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.constants.Constants;
|
import electroblob.wizardry.constants.Constants;
|
||||||
import electroblob.wizardry.data.WizardData;
|
import electroblob.wizardry.data.WizardData;
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
@@ -11,11 +12,13 @@ import net.minecraft.entity.player.EntityPlayer;
|
|||||||
import net.minecraft.inventory.Slot;
|
import net.minecraft.inventory.Slot;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
|
||||||
public class ItemBlankScroll extends Item implements IWorkbenchItem {
|
public class ItemBlankScroll extends Item implements IWorkbenchItem {
|
||||||
|
|
||||||
public ItemBlankScroll(){
|
public ItemBlankScroll(){
|
||||||
this.setCreativeTab(WizardryTabs.WIZARDRY);
|
this.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||||
|
this.addPropertyOverride(new ResourceLocation("festive"), (s, w, e) -> Wizardry.tisTheSeason ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -45,10 +48,14 @@ public class ItemBlankScroll extends Item implements IWorkbenchItem {
|
|||||||
int cost = spell.getCost() * centre.getStack().getCount();
|
int cost = spell.getCost() * centre.getStack().getCount();
|
||||||
// Continuous spell scrolls require enough mana to cast them for the duration defined in ItemScroll.
|
// Continuous spell scrolls require enough mana to cast them for the duration defined in ItemScroll.
|
||||||
if(spell.isContinuous) cost *= ItemScroll.CASTING_TIME / 20;
|
if(spell.isContinuous) cost *= ItemScroll.CASTING_TIME / 20;
|
||||||
|
|
||||||
|
int manaPerItem = Constants.MANA_PER_CRYSTAL;
|
||||||
|
if(crystals.getStack().getItem() == WizardryItems.crystal_shard) manaPerItem = Constants.MANA_PER_SHARD;
|
||||||
|
if(crystals.getStack().getItem() == WizardryItems.grand_crystal) manaPerItem = Constants.GRAND_CRYSTAL_MANA;
|
||||||
|
|
||||||
if(crystals.getStack().getCount() * Constants.MANA_PER_CRYSTAL > cost){
|
if(crystals.getStack().getCount() * manaPerItem > cost){
|
||||||
// Rounds up to the nearest whole crystal
|
// Rounds up to the nearest whole crystal
|
||||||
crystals.decrStackSize(cost / Constants.MANA_PER_CRYSTAL + 1);
|
crystals.decrStackSize(cost / manaPerItem + 1);
|
||||||
centre.putStack(new ItemStack(WizardryItems.scroll, centre.getStack().getCount(), spell.metadata()));
|
centre.putStack(new ItemStack(WizardryItems.scroll, centre.getStack().getCount(), spell.metadata()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package electroblob.wizardry.item;
|
|||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.registry.WizardryPotions;
|
import electroblob.wizardry.registry.WizardryPotions;
|
||||||
|
import electroblob.wizardry.spell.Spell;
|
||||||
import electroblob.wizardry.util.MagicDamage;
|
import electroblob.wizardry.util.MagicDamage;
|
||||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
@@ -81,6 +82,12 @@ public class ItemFrostAxe extends ItemAxe implements IConjuredItem {
|
|||||||
stack.setItemDamage(damage + 1);
|
stack.setItemDamage(damage + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Multimap<String, AttributeModifier> getItemAttributeModifiers(EntityEquipmentSlot equipmentSlot){
|
||||||
|
attackDamage = Spells.frost_axe.getProperty(Spell.DAMAGE).floatValue();
|
||||||
|
return super.getItemAttributeModifiers(equipmentSlot);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase wielder){
|
public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase wielder){
|
||||||
if(!MagicDamage.isEntityImmune(DamageType.FROST, target))
|
if(!MagicDamage.isEntityImmune(DamageType.FROST, target))
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package electroblob.wizardry.item;
|
package electroblob.wizardry.item;
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.data.SpellGlyphData;
|
|
||||||
import electroblob.wizardry.event.SpellCastEvent;
|
import electroblob.wizardry.event.SpellCastEvent;
|
||||||
import electroblob.wizardry.event.SpellCastEvent.Source;
|
import electroblob.wizardry.event.SpellCastEvent.Source;
|
||||||
import electroblob.wizardry.packet.PacketCastSpell;
|
import electroblob.wizardry.packet.PacketCastSpell;
|
||||||
@@ -14,16 +13,12 @@ import net.minecraft.entity.EntityLivingBase;
|
|||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.ActionResult;
|
import net.minecraft.util.*;
|
||||||
import net.minecraft.util.EnumActionResult;
|
|
||||||
import net.minecraft.util.EnumHand;
|
|
||||||
import net.minecraft.util.NonNullList;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
import net.minecraftforge.common.MinecraftForge;
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
import net.minecraftforge.oredict.OreDictionary;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -37,6 +32,7 @@ public class ItemScroll extends Item implements ISpellCastingItem {
|
|||||||
setHasSubtypes(true);
|
setHasSubtypes(true);
|
||||||
setMaxStackSize(16);
|
setMaxStackSize(16);
|
||||||
setCreativeTab(WizardryTabs.SPELLS);
|
setCreativeTab(WizardryTabs.SPELLS);
|
||||||
|
this.addPropertyOverride(new ResourceLocation("festive"), (s, w, e) -> Wizardry.tisTheSeason ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -54,7 +50,7 @@ public class ItemScroll extends Item implements ISpellCastingItem {
|
|||||||
|
|
||||||
if(tab == WizardryTabs.SPELLS){
|
if(tab == WizardryTabs.SPELLS){
|
||||||
|
|
||||||
List<Spell> spells = Spell.getSpells(Spell.allSpells);
|
List<Spell> spells = Spell.getAllSpells();
|
||||||
spells.removeIf(s -> !s.applicableForItem(this));
|
spells.removeIf(s -> !s.applicableForItem(this));
|
||||||
|
|
||||||
for(Spell spell : spells){
|
for(Spell spell : spells){
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public class ItemSpellBook extends Item {
|
|||||||
setHasSubtypes(true);
|
setHasSubtypes(true);
|
||||||
setMaxStackSize(16);
|
setMaxStackSize(16);
|
||||||
setCreativeTab(WizardryTabs.SPELLS);
|
setCreativeTab(WizardryTabs.SPELLS);
|
||||||
|
this.addPropertyOverride(new ResourceLocation("festive"), (s, w, e) -> Wizardry.tisTheSeason ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -40,7 +41,7 @@ public class ItemSpellBook extends Item {
|
|||||||
|
|
||||||
if(tab == WizardryTabs.SPELLS){
|
if(tab == WizardryTabs.SPELLS){
|
||||||
|
|
||||||
List<Spell> spells = Spell.getSpells(Spell.allSpells);
|
List<Spell> spells = Spell.getAllSpells();
|
||||||
spells.removeIf(s -> !s.applicableForItem(this));
|
spells.removeIf(s -> !s.applicableForItem(this));
|
||||||
|
|
||||||
for(Spell spell : spells){
|
for(Spell spell : spells){
|
||||||
|
|||||||
@@ -400,7 +400,7 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
|||||||
if(MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Tick(Source.WAND, spell, caster, modifiers, castingTick))) return false;
|
if(MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Tick(Source.WAND, spell, caster, modifiers, castingTick))) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cost = (int)(spell.getCost() * modifiers.get(SpellModifiers.COST));
|
int cost = (int)(spell.getCost() * modifiers.get(SpellModifiers.COST) + 0.1f); // Weird floaty rounding
|
||||||
|
|
||||||
// As of wizardry 4.2 mana cost is only divided over two intervals each second
|
// As of wizardry 4.2 mana cost is only divided over two intervals each second
|
||||||
if(spell.isContinuous) cost = getDistributedCost(cost, castingTick);
|
if(spell.isContinuous) cost = getDistributedCost(cost, castingTick);
|
||||||
@@ -436,7 +436,7 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
|||||||
caster.setActiveHand(hand);
|
caster.setActiveHand(hand);
|
||||||
|
|
||||||
// Mana cost
|
// Mana cost
|
||||||
int cost = (int)(spell.getCost() * modifiers.get(SpellModifiers.COST));
|
int cost = (int)(spell.getCost() * modifiers.get(SpellModifiers.COST) + 0.1f); // Weird floaty rounding
|
||||||
// As of wizardry 4.2 mana cost is only divided over two intervals each second
|
// As of wizardry 4.2 mana cost is only divided over two intervals each second
|
||||||
if(spell.isContinuous) cost = getDistributedCost(cost, castingTick);
|
if(spell.isContinuous) cost = getDistributedCost(cost, castingTick);
|
||||||
|
|
||||||
@@ -497,7 +497,7 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
|||||||
|
|
||||||
int castingTick = stack.getMaxItemUseDuration() - timeLeft; // Might as well include this
|
int castingTick = stack.getMaxItemUseDuration() - timeLeft; // Might as well include this
|
||||||
|
|
||||||
int cost = getDistributedCost((int)(spell.getCost() * modifiers.get(SpellModifiers.COST)), castingTick);
|
int cost = getDistributedCost((int)(spell.getCost() * modifiers.get(SpellModifiers.COST) + 0.1f), castingTick);
|
||||||
|
|
||||||
// Still need to check there's enough mana or the spell will finish twice, since running out of mana is
|
// Still need to check there's enough mana or the spell will finish twice, since running out of mana is
|
||||||
// handled separately.
|
// handled separately.
|
||||||
|
|||||||
@@ -57,12 +57,12 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Should only be used by vanilla's armour damage calculations; use {@link ItemWizardArmour#setMana(ItemStack, int)}
|
/** Should only be used by vanilla's armour damage calculations; use {@link ItemWizardArmour#setMana(ItemStack, int)}
|
||||||
* to modify wand mana from elsewhere. */
|
* to modify armour mana from elsewhere. */
|
||||||
@Override
|
@Override
|
||||||
public void setDamage(ItemStack stack, int damage){
|
public void setDamage(ItemStack stack, int damage){
|
||||||
// Overridden to stop repair things from 'repairing' the mana in wizard armour
|
// Overridden to stop repair things from 'repairing' the mana in wizard armour
|
||||||
// This being armour, it's much easier to let its damage increase normally, but block it from being decreased
|
// This being armour, it's much easier to let its damage increase normally, but block it from being decreased
|
||||||
if(stack.getItemDamage() < damage) super.setDamage(stack, damage);
|
if(stack.getItemDamage() < damage) super.setDamage(stack, Math.min(damage, stack.getMaxDamage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -178,9 +178,14 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
|||||||
|
|
||||||
String s = "wizard_armour";
|
String s = "wizard_armour";
|
||||||
|
|
||||||
if(this.element != null) s = s + "_" + this.element.getName();
|
if(Wizardry.tisTheSeason){
|
||||||
|
s = s + "_festive";
|
||||||
|
}else{
|
||||||
|
if(this.element != null) s = s + "_" + this.element.getName();
|
||||||
|
if(stack.hasTagCompound() && stack.getTagCompound().getBoolean("legendary")) s = "legendary_" + s;
|
||||||
|
}
|
||||||
|
|
||||||
if(slot == EntityEquipmentSlot.LEGS) s = s + "_legs";
|
if(slot == EntityEquipmentSlot.LEGS) s = s + "_legs";
|
||||||
if(stack.hasTagCompound() && stack.getTagCompound().getBoolean("legendary")) s = "legendary_" + s;
|
|
||||||
|
|
||||||
return "ebwizardry:textures/armour/" + s + ".png";
|
return "ebwizardry:textures/armour/" + s + ".png";
|
||||||
}
|
}
|
||||||
@@ -325,7 +330,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
|||||||
IAttributeInstance attribute = event.getEntityLiving().getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE);
|
IAttributeInstance attribute = event.getEntityLiving().getEntityAttribute(SharedMonsterAttributes.FOLLOW_RANGE);
|
||||||
double followRange = attribute == null ? 16 : attribute.getAttributeValue();
|
double followRange = attribute == null ? 16 : attribute.getAttributeValue();
|
||||||
if(event.getTarget().isSneaking()) followRange *= 0.8;
|
if(event.getTarget().isSneaking()) followRange *= 0.8;
|
||||||
float f = armourPieces / ((EntityPlayer)event.getTarget()).inventory.armorInventory.size();
|
float f = (float)armourPieces / ((EntityPlayer)event.getTarget()).inventory.armorInventory.size();
|
||||||
if(f < 0.1F) f = 0.1F;
|
if(f < 0.1F) f = 0.1F;
|
||||||
followRange *= (double)(0.7F * f);
|
followRange *= (double)(0.7F * f);
|
||||||
// Don't need to worry about the isSuitableTarget check since it must already have been checked to get this far
|
// Don't need to worry about the isSuitableTarget check since it must already have been checked to get this far
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import electroblob.wizardry.constants.Tier;
|
|||||||
import electroblob.wizardry.data.WizardData;
|
import electroblob.wizardry.data.WizardData;
|
||||||
import electroblob.wizardry.item.ItemScroll;
|
import electroblob.wizardry.item.ItemScroll;
|
||||||
import electroblob.wizardry.item.ItemSpellBook;
|
import electroblob.wizardry.item.ItemSpellBook;
|
||||||
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
import electroblob.wizardry.util.SpellProperties;
|
import electroblob.wizardry.util.SpellProperties;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
@@ -16,9 +17,9 @@ import net.minecraft.util.ResourceLocation;
|
|||||||
import net.minecraft.world.storage.loot.LootContext;
|
import net.minecraft.world.storage.loot.LootContext;
|
||||||
import net.minecraft.world.storage.loot.conditions.LootCondition;
|
import net.minecraft.world.storage.loot.conditions.LootCondition;
|
||||||
import net.minecraft.world.storage.loot.functions.LootFunction;
|
import net.minecraft.world.storage.loot.functions.LootFunction;
|
||||||
import org.apache.commons.lang3.ArrayUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
@@ -76,89 +77,94 @@ public class RandomSpell extends LootFunction {
|
|||||||
if(!(stack.getItem() instanceof ItemSpellBook) && !(stack.getItem() instanceof ItemScroll)) Wizardry.logger
|
if(!(stack.getItem() instanceof ItemSpellBook) && !(stack.getItem() instanceof ItemScroll)) Wizardry.logger
|
||||||
.warn("Applying the random_spell loot function to an item that isn't a spell book or scroll.");
|
.warn("Applying the random_spell loot function to an item that isn't a spell book or scroll.");
|
||||||
|
|
||||||
Tier tier;
|
|
||||||
Element element;
|
|
||||||
|
|
||||||
if(ignoreWeighting){
|
|
||||||
if(tiers == null || tiers.isEmpty()){
|
|
||||||
tier = Tier.values()[random.nextInt(Tier.values().length)];
|
|
||||||
}else{
|
|
||||||
tier = tiers.get(random.nextInt(tiers.size()));
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
if(tiers == null || tiers.isEmpty()){
|
|
||||||
tier = Tier.getWeightedRandomTier(random);
|
|
||||||
}else{
|
|
||||||
tier = Tier.getWeightedRandomTier(random, tiers.toArray(new Tier[0]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Elements aren't weighted
|
|
||||||
if(elements == null || elements.isEmpty()){
|
|
||||||
// Element can only be MAGIC if tier is NOVICE
|
|
||||||
if(tier == Tier.NOVICE){
|
|
||||||
element = Element.values()[random.nextInt(Element.values().length)];
|
|
||||||
}else{
|
|
||||||
Element[] elements = ArrayUtils.removeElement(Element.values(), Element.MAGIC);
|
|
||||||
element = elements[random.nextInt(elements.length)];
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
// In theory, swapping this line to the commented one should make absolutely no difference.
|
|
||||||
element = elements.get(random.nextInt(elements.size()));
|
|
||||||
// element = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
SpellProperties.Context spellContext = context.getLootedEntity() == null ? SpellProperties.Context.TREASURE
|
SpellProperties.Context spellContext = context.getLootedEntity() == null ? SpellProperties.Context.TREASURE
|
||||||
: SpellProperties.Context.LOOTING;
|
: SpellProperties.Context.LOOTING;
|
||||||
|
|
||||||
// Here's a thought: does randomly selecting the element beforehand (as opposed to leaving it null and letting
|
|
||||||
// the spell randomiser use any element) change the overall outcome at all?
|
|
||||||
List<Spell> spellsList = Spell.getSpells(new Spell.TierElementFilter(tier, element, spellContext));
|
|
||||||
|
|
||||||
spellsList.removeIf(s -> !s.applicableForItem(stack.getItem()));
|
|
||||||
if(stack.getItem() instanceof ItemScroll) spellsList.removeIf(s -> !s.isEnabled(SpellProperties.Context.SCROLL));
|
|
||||||
if(stack.getItem() instanceof ItemSpellBook) spellsList.removeIf(s -> !s.isEnabled(SpellProperties.Context.BOOK));
|
|
||||||
|
|
||||||
// Ensures the tier chosen actually has spells in it, and if not uses NOVICE instead. NOVICE always has at least
|
|
||||||
// the NONE spell since this spell cannot be disabled.
|
|
||||||
// Commented out for now because it will interfere with the ability to specify tiers and elements.
|
|
||||||
// To be honest, I may as well just say that if you disable enough spells to make this important, you deserve
|
|
||||||
// less loot!
|
|
||||||
/* if(spells.isEmpty()){ spellsList = Spell.getSpells(new Spell.TierElementFilter(EnumTier.NOVICE, null));
|
|
||||||
* if(stack.getItem() instanceof ItemScroll) spellsList.retainAll(Spell.getSpells(Spell.nonContinuousSpells));
|
|
||||||
* } */
|
|
||||||
|
|
||||||
if(spells != null && !spells.isEmpty()){
|
|
||||||
spellsList.retainAll(spells);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method is badly-named, loot chests pass a player through too, not just mobs
|
// This method is badly-named, loot chests pass a player through too, not just mobs
|
||||||
// (And WHY does it only return an entity?! The underlying field is always a player so I'm casting it anyway)
|
// (And WHY does it only return an entity?! The underlying field is always a player so I'm casting it anyway)
|
||||||
EntityPlayer player = (EntityPlayer)context.getKillerPlayer();
|
EntityPlayer player = (EntityPlayer)context.getKillerPlayer();
|
||||||
|
|
||||||
|
Spell spell = pickRandomSpell(stack, random, spellContext, player);
|
||||||
|
|
||||||
|
if(spell == Spells.none) Wizardry.logger.warn("Tried to apply the random_spell loot function to an item, but no"
|
||||||
|
+ " enabled spells matched the criteria specified. Substituting placeholder (metadata 0) item.");
|
||||||
|
|
||||||
|
stack.setItemDamage(spell.metadata());
|
||||||
|
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Spell pickRandomSpell(ItemStack stack, Random random, SpellProperties.Context spellContext, EntityPlayer player){
|
||||||
|
|
||||||
|
// We're now doing this first because we need to know which spells we have to play with before selecting a tier and element
|
||||||
|
List<Spell> possibleSpells = Spell.getSpells(s -> s.isEnabled(spellContext) && s.applicableForItem(stack.getItem())
|
||||||
|
// Remove excluded tiers/elements immediately (mainly because empty tier checks should account for excluded elements)
|
||||||
|
&& (tiers == null || tiers.contains(s.getTier())) && (elements == null || elements.contains(s.getElement())));
|
||||||
|
|
||||||
|
if(spells != null && !spells.isEmpty()){
|
||||||
|
possibleSpells.retainAll(spells); // Normally you wouldn't specify a spells list AND tiers/elements... but you could!
|
||||||
|
}
|
||||||
|
|
||||||
|
if(stack.getItem() instanceof ItemScroll) possibleSpells.removeIf(s -> !s.isEnabled(SpellProperties.Context.SCROLL));
|
||||||
|
if(stack.getItem() instanceof ItemSpellBook) possibleSpells.removeIf(s -> !s.isEnabled(SpellProperties.Context.BOOK));
|
||||||
|
|
||||||
|
// Select a tier...
|
||||||
|
|
||||||
|
List<Tier> possibleTiers = new ArrayList<>();
|
||||||
|
|
||||||
|
if(tiers == null || tiers.isEmpty()){
|
||||||
|
possibleTiers.addAll(Arrays.asList(Tier.values()));
|
||||||
|
}else{
|
||||||
|
possibleTiers.addAll(tiers);
|
||||||
|
}
|
||||||
|
// Remove all empty tiers
|
||||||
|
possibleTiers.removeIf(t -> possibleSpells.stream().noneMatch(s -> s.getTier() == t)); // Lambdaception!
|
||||||
|
|
||||||
|
if(possibleTiers.isEmpty()) return Spells.none; // Gotta disable a lot of spells for this to happen
|
||||||
|
|
||||||
|
Tier tier = ignoreWeighting ? possibleTiers.get(random.nextInt(possibleTiers.size()))
|
||||||
|
: Tier.getWeightedRandomTier(random, possibleTiers.toArray(new Tier[0]));
|
||||||
|
|
||||||
|
// Remove all spells that aren't of the selected tier
|
||||||
|
possibleSpells.removeIf(s -> s.getTier() != tier);
|
||||||
|
if(possibleSpells.isEmpty()) return Spells.none; // Should be caught by the no-elements check but we might as well
|
||||||
|
|
||||||
|
// Select an element...
|
||||||
|
|
||||||
|
List<Element> possibleElements = new ArrayList<>();
|
||||||
|
|
||||||
|
// Elements aren't weighted
|
||||||
|
if(elements == null || elements.isEmpty()){
|
||||||
|
possibleElements.addAll(Arrays.asList(Element.values()));
|
||||||
|
}else{
|
||||||
|
possibleElements.addAll(elements);
|
||||||
|
}
|
||||||
|
// Remove all empty elements
|
||||||
|
possibleElements.removeIf(e -> possibleSpells.stream().noneMatch(s -> s.getElement() == e));
|
||||||
|
|
||||||
|
if(possibleElements.isEmpty()) return Spells.none; // A bit more likely I guess, but still pretty unlikely
|
||||||
|
|
||||||
|
Element element = possibleElements.get(random.nextInt(possibleElements.size()));
|
||||||
|
|
||||||
|
// Remove all spells that aren't of the selected tier
|
||||||
|
possibleSpells.removeIf(s -> s.getElement() != element);
|
||||||
|
if(possibleSpells.isEmpty()) return Spells.none; // If it fails anywhere, it'll most likely be here
|
||||||
|
|
||||||
// Remove either the undiscovered spells or the discovered ones, depending on the bias
|
// Remove either the undiscovered spells or the discovered ones, depending on the bias
|
||||||
if(undiscoveredBias > 0 && player != null){
|
if(undiscoveredBias > 0 && player != null){
|
||||||
|
|
||||||
WizardData data = WizardData.get(player);
|
WizardData data = WizardData.get(player);
|
||||||
|
|
||||||
int discoveredCount = (int)spellsList.stream().filter(data::hasSpellBeenDiscovered).count();
|
int discoveredCount = (int)possibleSpells.stream().filter(data::hasSpellBeenDiscovered).count();
|
||||||
// If none have been discovered or they've all been discovered, don't bother!
|
// If none have been discovered or they've all been discovered, don't bother!
|
||||||
if(discoveredCount > 0 && discoveredCount < spellsList.size()){
|
if(discoveredCount > 0 && discoveredCount < possibleSpells.size()){
|
||||||
// Kinda unintuitive but it's very neat!
|
// Kinda unintuitive but it's very neat!
|
||||||
boolean keepDiscovered = random.nextFloat() < 0.5f + 0.5f * undiscoveredBias;
|
boolean keepDiscovered = random.nextFloat() < 0.5f + 0.5f * undiscoveredBias;
|
||||||
spellsList.removeIf(s -> keepDiscovered != data.hasSpellBeenDiscovered(s));
|
possibleSpells.removeIf(s -> keepDiscovered != data.hasSpellBeenDiscovered(s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(spellsList.isEmpty()){
|
return possibleSpells.get(random.nextInt(possibleSpells.size())); // Finally pick a spell
|
||||||
Wizardry.logger.warn("Tried to apply the random_spell loot function to an item, but no enabled spells"
|
|
||||||
+ "matched the criteria specified. Substituting placeholder (metadata 0) item.");
|
|
||||||
stack.setItemDamage(0);
|
|
||||||
}else{
|
|
||||||
stack.setItemDamage(spellsList.get(random.nextInt(spellsList.size())).metadata());
|
|
||||||
}
|
|
||||||
|
|
||||||
return stack;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Serializer extends LootFunction.Serializer<RandomSpell> {
|
public static class Serializer extends LootFunction.Serializer<RandomSpell> {
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class BehaviourSpellDispense extends BehaviorDispenseOptional {
|
|||||||
if(world.isSideSolid(source.getBlockPos().offset(direction), direction.getOpposite())) return stack;
|
if(world.isSideSolid(source.getBlockPos().offset(direction), direction.getOpposite())) return stack;
|
||||||
|
|
||||||
// If the scroll can never be cast by a dispenser, it should be dispensed as an item.
|
// If the scroll can never be cast by a dispenser, it should be dispensed as an item.
|
||||||
if(!spell.canBeCastByDispensers()) return super.dispenseStack(source, stack);
|
if(!spell.canBeCastBy(source.getBlockTileEntity())) return super.dispenseStack(source, stack);
|
||||||
|
|
||||||
SpellModifiers modifiers = new SpellModifiers();
|
SpellModifiers modifiers = new SpellModifiers();
|
||||||
|
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
package electroblob.wizardry.packet;
|
|
||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
|
||||||
import io.netty.buffer.ByteBuf;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
|
||||||
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
|
||||||
|
|
||||||
/** <b>[Server -> Client]</b> This packet is sent when the slow time potion effect expires or is removed from an
|
|
||||||
* entity to unblock all nearby entities' updates. */
|
|
||||||
public class PacketEndSlowTime implements IMessageHandler<PacketEndSlowTime.Message, IMessage> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IMessage onMessage(Message message, MessageContext ctx){
|
|
||||||
|
|
||||||
// Just to make sure that the side is correct
|
|
||||||
if(ctx.side.isClient()){
|
|
||||||
net.minecraft.client.Minecraft.getMinecraft().addScheduledTask(() -> Wizardry.proxy.handleEndSlowTimePacket(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Message implements IMessage {
|
|
||||||
|
|
||||||
public int hostID;
|
|
||||||
|
|
||||||
// This constructor is required otherwise you'll get errors (used somewhere in fml through reflection)
|
|
||||||
public Message(){
|
|
||||||
}
|
|
||||||
|
|
||||||
public Message(Entity host){
|
|
||||||
this.hostID = host.getEntityId();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void fromBytes(ByteBuf buf){
|
|
||||||
this.hostID = buf.readInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void toBytes(ByteBuf buf){
|
|
||||||
buf.writeInt(hostID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -26,7 +26,6 @@ public class WizardryPacketHandler {
|
|||||||
registerMessage(PacketSpellProperties.class, PacketSpellProperties.Message.class);
|
registerMessage(PacketSpellProperties.class, PacketSpellProperties.Message.class);
|
||||||
registerMessage(PacketSyncAdvancements.class, PacketSyncAdvancements.Message.class);
|
registerMessage(PacketSyncAdvancements.class, PacketSyncAdvancements.Message.class);
|
||||||
registerMessage(PacketRequestAdvancementSync.class, PacketRequestAdvancementSync.Message.class);
|
registerMessage(PacketRequestAdvancementSync.class, PacketRequestAdvancementSync.Message.class);
|
||||||
registerMessage(PacketEndSlowTime.class, PacketEndSlowTime.Message.class);
|
|
||||||
registerMessage(PacketResurrection.class, PacketResurrection.Message.class);
|
registerMessage(PacketResurrection.class, PacketResurrection.Message.class);
|
||||||
registerMessage(PacketCastSpellAtPos.class, PacketCastSpellAtPos.Message.class);
|
registerMessage(PacketCastSpellAtPos.class, PacketCastSpellAtPos.Message.class);
|
||||||
registerMessage(PacketEmitterData.class, PacketEmitterData.Message.class);
|
registerMessage(PacketEmitterData.class, PacketEmitterData.Message.class);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package electroblob.wizardry.potion;
|
|||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.registry.WizardryPotions;
|
import electroblob.wizardry.registry.WizardryPotions;
|
||||||
|
import electroblob.wizardry.util.NBTExtras;
|
||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
@@ -40,7 +41,7 @@ public class PotionContainment extends PotionMagicEffect {
|
|||||||
|
|
||||||
// Initialise the containment position to the entity's position if it wasn't set already
|
// Initialise the containment position to the entity's position if it wasn't set already
|
||||||
if(!target.getEntityData().hasKey(ENTITY_TAG)){
|
if(!target.getEntityData().hasKey(ENTITY_TAG)){
|
||||||
target.getEntityData().setTag(ENTITY_TAG, NBTUtil.createPosTag(new BlockPos(target.getPositionVector().subtract(0.5, 0.5, 0.5))));
|
NBTExtras.storeTagSafely(target.getEntityData(), ENTITY_TAG, NBTUtil.createPosTag(new BlockPos(target.getPositionVector().subtract(0.5, 0.5, 0.5))));
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3d origin = WizardryUtilities.getCentre(NBTUtil.getPosFromTag(target.getEntityData().getCompoundTag(ENTITY_TAG)));
|
Vec3d origin = WizardryUtilities.getCentre(NBTUtil.getPosFromTag(target.getEntityData().getCompoundTag(ENTITY_TAG)));
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package electroblob.wizardry.potion;
|
|||||||
|
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.item.ItemArtefact;
|
import electroblob.wizardry.item.ItemArtefact;
|
||||||
import electroblob.wizardry.packet.PacketEndSlowTime;
|
|
||||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
|
||||||
import electroblob.wizardry.registry.Spells;
|
import electroblob.wizardry.registry.Spells;
|
||||||
import electroblob.wizardry.registry.WizardryItems;
|
import electroblob.wizardry.registry.WizardryItems;
|
||||||
import electroblob.wizardry.registry.WizardryPotions;
|
import electroblob.wizardry.registry.WizardryPotions;
|
||||||
@@ -17,11 +15,15 @@ import net.minecraft.entity.IProjectile;
|
|||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.entity.projectile.EntityArrow;
|
import net.minecraft.entity.projectile.EntityArrow;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
||||||
import net.minecraftforge.event.entity.living.PotionEvent;
|
import net.minecraftforge.event.entity.living.PotionEvent;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
|
||||||
|
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Mod.EventBusSubscriber
|
@Mod.EventBusSubscriber
|
||||||
@@ -29,6 +31,8 @@ public class PotionSlowTime extends PotionMagicEffect implements ISyncedPotion {
|
|||||||
|
|
||||||
// FIXME: Minecarts with entities in them (and, I suspect, any other ridden entities) go crazy when time-slowed
|
// FIXME: Minecarts with entities in them (and, I suspect, any other ridden entities) go crazy when time-slowed
|
||||||
|
|
||||||
|
public static final String NBT_KEY = "time_slowed";
|
||||||
|
|
||||||
public PotionSlowTime(boolean isBadEffect, int liquidColour){
|
public PotionSlowTime(boolean isBadEffect, int liquidColour){
|
||||||
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icon_slow_time.png"));
|
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icon_slow_time.png"));
|
||||||
this.setPotionName("potion." + Wizardry.MODID + ":slow_time");
|
this.setPotionName("potion." + Wizardry.MODID + ":slow_time");
|
||||||
@@ -61,6 +65,8 @@ public class PotionSlowTime extends PotionMagicEffect implements ISyncedPotion {
|
|||||||
|
|
||||||
for(Entity entity : targetsInRange){
|
for(Entity entity : targetsInRange){
|
||||||
|
|
||||||
|
entity.getEntityData().setBoolean(NBT_KEY, true);
|
||||||
|
|
||||||
// If time is stopped, block all updates; otherwise block all updates except every [interval] ticks
|
// If time is stopped, block all updates; otherwise block all updates except every [interval] ticks
|
||||||
entity.updateBlocked = stopTime || host.ticksExisted % interval != 0;
|
entity.updateBlocked = stopTime || host.ticksExisted % interval != 0;
|
||||||
|
|
||||||
@@ -130,6 +136,29 @@ public class PotionSlowTime extends PotionMagicEffect implements ISyncedPotion {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Goes through every entity in the given world and does the following:<br>
|
||||||
|
* 1. Checks if they have the slow time NBT tag<br>
|
||||||
|
* 2. If so, scans the area nearby for players or NPCs with the slow time effect<br>
|
||||||
|
* 3. If none are found, removes the slow time NBT tag and unblocks the entity's updates
|
||||||
|
*/
|
||||||
|
public static void cleanUpEntities(World world){
|
||||||
|
// Had trouble with accessing loadedTileEntityList from tick events causing random CMEs so I'm making a
|
||||||
|
// copy of this too just in case
|
||||||
|
List<Entity> loadedEntityList = new ArrayList<>(world.loadedEntityList);
|
||||||
|
|
||||||
|
for(Entity entity : loadedEntityList){
|
||||||
|
if(entity.getEntityData().getBoolean(NBT_KEY)){
|
||||||
|
// Currently only players can cast slow time, but you could apply the effect to NPCs with commands
|
||||||
|
List<EntityLivingBase> nearby = WizardryUtilities.getEntitiesWithinRadius(getEffectRadius(), entity.posX, entity.posY, entity.posZ, entity.world, EntityLivingBase.class);
|
||||||
|
if(nearby.stream().noneMatch(e -> e.isPotionActive(WizardryPotions.slow_time))){
|
||||||
|
entity.getEntityData().removeTag(NBT_KEY);
|
||||||
|
entity.updateBlocked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onLivingUpdateEvent(LivingUpdateEvent event){
|
public static void onLivingUpdateEvent(LivingUpdateEvent event){
|
||||||
|
|
||||||
@@ -150,23 +179,16 @@ public class PotionSlowTime extends PotionMagicEffect implements ISyncedPotion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onPotionExpiryEvent(PotionEvent.PotionExpiryEvent event){
|
public static void tick(TickEvent.WorldTickEvent event){
|
||||||
if(event.getPotionEffect() != null && event.getPotionEffect().getPotion() == WizardryPotions.slow_time){
|
if(!event.world.isRemote && event.phase == TickEvent.Phase.END) cleanUpEntities(event.world);
|
||||||
unblockNearbyEntities(event.getEntityLiving());
|
|
||||||
if(!event.getEntity().world.isRemote){
|
|
||||||
WizardryPacketHandler.net.sendToDimension(new PacketEndSlowTime.Message(event.getEntityLiving()), event.getEntity().dimension);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We still need this as well as tick events because the player hasn't moved anywhere, they just logged out
|
||||||
|
// In fact, it won't really matter since the tick event fixes it on login anyway, but if the mod is uninstalled or
|
||||||
|
// something else weird happens...
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onPotionRemoveEvent(PotionEvent.PotionRemoveEvent event){
|
public static void onPlayerLoggedOutEvent(PlayerEvent.PlayerLoggedOutEvent event){
|
||||||
if(event.getPotionEffect() != null && event.getPotionEffect().getPotion() == WizardryPotions.slow_time){
|
if(event.player.updateBlocked) event.player.updateBlocked = false;
|
||||||
unblockNearbyEntities(event.getEntityLiving());
|
|
||||||
if(!event.getEntity().world.isRemote){
|
|
||||||
WizardryPacketHandler.net.sendToDimension(new PacketEndSlowTime.Message(event.getEntityLiving()), event.getEntity().dimension);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import electroblob.wizardry.entity.construct.*;
|
|||||||
import electroblob.wizardry.entity.living.*;
|
import electroblob.wizardry.entity.living.*;
|
||||||
import electroblob.wizardry.entity.projectile.*;
|
import electroblob.wizardry.entity.projectile.*;
|
||||||
import electroblob.wizardry.spell.*;
|
import electroblob.wizardry.spell.*;
|
||||||
|
import net.minecraft.entity.projectile.EntitySnowball;
|
||||||
import net.minecraft.init.MobEffects;
|
import net.minecraft.init.MobEffects;
|
||||||
import net.minecraft.item.EnumAction;
|
import net.minecraft.item.EnumAction;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
@@ -243,10 +244,15 @@ public final class Spells {
|
|||||||
IForgeRegistry<Spell> registry = event.getRegistry();
|
IForgeRegistry<Spell> registry = event.getRegistry();
|
||||||
|
|
||||||
registry.register(new None());
|
registry.register(new None());
|
||||||
registry.register(new SpellArrow<>("magic_missile", EntityMagicMissile::new).addProperties(Spell.DAMAGE).soundValues(1, 1.4f, 0.4f));
|
registry.register(new SpellArrow<EntityMagicMissile>("magic_missile", EntityMagicMissile::new){
|
||||||
|
@Override
|
||||||
|
protected String getTranslationKey(){
|
||||||
|
return Wizardry.tisTheSeason ? super.getTranslationKey() + "_festive" : super.getTranslationKey();
|
||||||
|
}
|
||||||
|
}.addProperties(Spell.DAMAGE).soundValues(1, 1.4f, 0.4f));
|
||||||
registry.register(new Ignite());
|
registry.register(new Ignite());
|
||||||
registry.register(new Freeze());
|
registry.register(new Freeze());
|
||||||
registry.register(new Snowball());
|
registry.register(new SpellThrowable<>("snowball", EntitySnowball::new).npcSelector((e, o) -> o).soundValues(0.5f, 0.4f, 0.2f)); // Let's spare wizards the pain of the snowball spell
|
||||||
registry.register(new Arc());
|
registry.register(new Arc());
|
||||||
registry.register(new SpellProjectile<>("thunderbolt", EntityThunderbolt::new).addProperties(Spell.DAMAGE, EntityThunderbolt.KNOCKBACK_STRENGTH).soundValues(0.8f, 0.9f, 0.2f));
|
registry.register(new SpellProjectile<>("thunderbolt", EntityThunderbolt::new).addProperties(Spell.DAMAGE, EntityThunderbolt.KNOCKBACK_STRENGTH).soundValues(0.8f, 0.9f, 0.2f));
|
||||||
registry.register(new SummonZombie());
|
registry.register(new SummonZombie());
|
||||||
@@ -316,7 +322,7 @@ public final class Spells {
|
|||||||
registry.register(new SpellProjectile<>("darkness_orb", EntityDarknessOrb::new).addProperties(Spell.DAMAGE, Spell.EFFECT_DURATION, Spell.EFFECT_STRENGTH).soundValues(0.5f, 0.4f, 0.2f));
|
registry.register(new SpellProjectile<>("darkness_orb", EntityDarknessOrb::new).addProperties(Spell.DAMAGE, Spell.EFFECT_DURATION, Spell.EFFECT_STRENGTH).soundValues(0.5f, 0.4f, 0.2f));
|
||||||
registry.register(new ShadowWard());
|
registry.register(new ShadowWard());
|
||||||
registry.register(new Decay());
|
registry.register(new Decay());
|
||||||
registry.register(new SpellBuff("water_breathing", 0.3f, 0.3f, 1, () -> MobEffects.WATER_BREATHING){ @Override public boolean canBeCastByNPCs(){ return false; } }.soundValues(0.7f, 1.2f, 0.4f));
|
registry.register(new SpellBuff("water_breathing", 0.3f, 0.3f, 1, () -> MobEffects.WATER_BREATHING).npcSelector((e, o) -> false).soundValues(0.7f, 1.2f, 0.4f));
|
||||||
registry.register(new Tornado());
|
registry.register(new Tornado());
|
||||||
registry.register(new Glide());
|
registry.register(new Glide());
|
||||||
registry.register(new SummonSpiritHorse());
|
registry.register(new SummonSpiritHorse());
|
||||||
@@ -367,7 +373,7 @@ public final class Spells {
|
|||||||
registry.register(new Intimidate());
|
registry.register(new Intimidate());
|
||||||
registry.register(new Banish());
|
registry.register(new Banish());
|
||||||
registry.register(new SixthSense());
|
registry.register(new SixthSense());
|
||||||
registry.register(new SpellBuff("darkvision", 0, 0.4f, 0.7f, () -> MobEffects.NIGHT_VISION){ @Override public boolean canBeCastByNPCs(){ return false; } }.soundValues(0.7f, 1.2f, 0.4f));
|
registry.register(new SpellBuff("darkvision", 0, 0.4f, 0.7f, () -> MobEffects.NIGHT_VISION).npcSelector((e, o) -> false).soundValues(0.7f, 1.2f, 0.4f));
|
||||||
registry.register(new Clairvoyance());
|
registry.register(new Clairvoyance());
|
||||||
registry.register(new PocketWorkbench());
|
registry.register(new PocketWorkbench());
|
||||||
registry.register(new ImbueWeapon());
|
registry.register(new ImbueWeapon());
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import electroblob.wizardry.constants.Tier;
|
|||||||
import electroblob.wizardry.loot.RandomSpell;
|
import electroblob.wizardry.loot.RandomSpell;
|
||||||
import electroblob.wizardry.loot.WizardSpell;
|
import electroblob.wizardry.loot.WizardSpell;
|
||||||
import electroblob.wizardry.spell.Spell;
|
import electroblob.wizardry.spell.Spell;
|
||||||
import net.minecraft.entity.EntityList;
|
|
||||||
import net.minecraft.entity.EnumCreatureType;
|
import net.minecraft.entity.EnumCreatureType;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.storage.loot.*;
|
import net.minecraft.world.storage.loot.*;
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ public final class WizardrySounds {
|
|||||||
public static final SoundEvent ENTITY_WIZARD_TRADING = createSound("entity.wizard.trading");
|
public static final SoundEvent ENTITY_WIZARD_TRADING = createSound("entity.wizard.trading");
|
||||||
public static final SoundEvent ENTITY_WIZARD_HURT = createSound("entity.wizard.hurt");
|
public static final SoundEvent ENTITY_WIZARD_HURT = createSound("entity.wizard.hurt");
|
||||||
public static final SoundEvent ENTITY_WIZARD_DEATH = createSound("entity.wizard.death");
|
public static final SoundEvent ENTITY_WIZARD_DEATH = createSound("entity.wizard.death");
|
||||||
|
public static final SoundEvent ENTITY_WIZARD_HOHOHO = createSound("entity.wizard.hohoho");
|
||||||
|
|
||||||
public static final SoundEvent ENTITY_DARKNESS_ORB_HIT = createSound("entity.darkness_orb.hit");
|
public static final SoundEvent ENTITY_DARKNESS_ORB_HIT = createSound("entity.darkness_orb.hit");
|
||||||
public static final SoundEvent ENTITY_DART_HIT = createSound("entity.dart.hit");
|
public static final SoundEvent ENTITY_DART_HIT = createSound("entity.dart.hit");
|
||||||
@@ -132,10 +133,17 @@ public final class WizardrySounds {
|
|||||||
public static final SoundEvent MISC_PAGE_TURN = createSound("misc.page_turn");
|
public static final SoundEvent MISC_PAGE_TURN = createSound("misc.page_turn");
|
||||||
public static final SoundEvent MISC_FREEZE = createSound("misc.freeze");
|
public static final SoundEvent MISC_FREEZE = createSound("misc.freeze");
|
||||||
|
|
||||||
/** Trick borrowed from the Twilight Forest, makes things neater. */
|
// Trick borrowed from the Twilight Forest, makes things neater.
|
||||||
|
|
||||||
|
/** Overload for {@link WizardrySounds#createSound(String, String)} which assigns wizardry's mod ID automatically. */
|
||||||
public static SoundEvent createSound(String name){
|
public static SoundEvent createSound(String name){
|
||||||
|
return createSound(Wizardry.MODID, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates a sound with the given name, to be read from {@code assets/[modID]/sounds.json}. */
|
||||||
|
public static SoundEvent createSound(String modID, String name){
|
||||||
// All the setRegistryName methods delegate to this one, it doesn't matter which you use.
|
// All the setRegistryName methods delegate to this one, it doesn't matter which you use.
|
||||||
return new SoundEvent(new ResourceLocation(Wizardry.MODID, name)).setRegistryName(name);
|
return new SoundEvent(new ResourceLocation(modID, name)).setRegistryName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For some reason, sound events seem to work even when they aren't registered, without even so much as a warning.
|
// For some reason, sound events seem to work even when they aren't registered, without even so much as a warning.
|
||||||
@@ -250,7 +258,7 @@ public final class WizardrySounds {
|
|||||||
event.getRegistry().register(MISC_PAGE_TURN);
|
event.getRegistry().register(MISC_PAGE_TURN);
|
||||||
event.getRegistry().register(MISC_FREEZE);
|
event.getRegistry().register(MISC_FREEZE);
|
||||||
|
|
||||||
for(Spell spell : Spell.getSpells(Spell.allSpells)){
|
for(Spell spell : Spell.getAllSpells()){
|
||||||
event.getRegistry().registerAll(spell.getSounds());
|
event.getRegistry().registerAll(spell.getSounds());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ import electroblob.wizardry.util.NBTExtras;
|
|||||||
import electroblob.wizardry.util.SpellModifiers;
|
import electroblob.wizardry.util.SpellModifiers;
|
||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityLiving;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.EnumAction;
|
import net.minecraft.item.EnumAction;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.tileentity.TileEntityDispenser;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
@@ -32,9 +34,9 @@ public class ArcaneLock extends SpellRay {
|
|||||||
|
|
||||||
@Override public boolean requiresPacket(){ return true; }
|
@Override public boolean requiresPacket(){ return true; }
|
||||||
|
|
||||||
@Override public boolean canBeCastByDispensers(){ return false; }
|
@Override public boolean canBeCastBy(TileEntityDispenser dispenser){ return false; }
|
||||||
|
|
||||||
@Override public boolean canBeCastByNPCs(){ return false; }
|
@Override public boolean canBeCastBy(EntityLiving npc, boolean override){ return false; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package electroblob.wizardry.spell;
|
package electroblob.wizardry.spell;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.registry.WizardryItems;
|
import electroblob.wizardry.registry.WizardryItems;
|
||||||
import electroblob.wizardry.util.ParticleBuilder;
|
import electroblob.wizardry.util.ParticleBuilder;
|
||||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||||
@@ -7,6 +8,7 @@ import electroblob.wizardry.util.SpellModifiers;
|
|||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.EnumAction;
|
import net.minecraft.item.EnumAction;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.EnumParticleTypes;
|
import net.minecraft.util.EnumParticleTypes;
|
||||||
@@ -78,9 +80,7 @@ public class Banish extends SpellRay {
|
|||||||
world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5);
|
world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't be bothered to route this through the proxies!
|
if(entity instanceof EntityPlayer) Wizardry.proxy.playBlinkEffect((EntityPlayer)entity);
|
||||||
if(entity == net.minecraft.client.Minecraft.getMinecraft().player)
|
|
||||||
electroblob.wizardry.client.WizardryClientEventHandler.playBlinkEffect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(y != null){
|
if(y != null){
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package electroblob.wizardry.spell;
|
package electroblob.wizardry.spell;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.registry.WizardryItems;
|
import electroblob.wizardry.registry.WizardryItems;
|
||||||
import electroblob.wizardry.util.RayTracer;
|
import electroblob.wizardry.util.RayTracer;
|
||||||
import electroblob.wizardry.util.SpellModifiers;
|
import electroblob.wizardry.util.SpellModifiers;
|
||||||
@@ -41,9 +42,8 @@ public class Blink extends Spell {
|
|||||||
world.spawnParticle(EnumParticleTypes.PORTAL, dx, dy, dz, world.rand.nextDouble() - 0.5,
|
world.spawnParticle(EnumParticleTypes.PORTAL, dx, dy, dz, world.rand.nextDouble() - 0.5,
|
||||||
world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5);
|
world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't be bothered to route this through the proxies!
|
Wizardry.proxy.playBlinkEffect(caster);
|
||||||
electroblob.wizardry.client.WizardryClientEventHandler.playBlinkEffect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
|
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
|
||||||
@@ -136,7 +136,7 @@ public class Blink extends Spell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canBeCastByNPCs(){
|
public boolean canBeCastBy(EntityLiving npc, boolean override){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import electroblob.wizardry.registry.WizardryItems;
|
|||||||
import electroblob.wizardry.util.ParticleBuilder;
|
import electroblob.wizardry.util.ParticleBuilder;
|
||||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||||
import electroblob.wizardry.util.SpellModifiers;
|
import electroblob.wizardry.util.SpellModifiers;
|
||||||
|
import net.minecraft.entity.EntityLiving;
|
||||||
import net.minecraft.entity.SharedMonsterAttributes;
|
import net.minecraft.entity.SharedMonsterAttributes;
|
||||||
import net.minecraft.entity.monster.EntityZombie;
|
import net.minecraft.entity.monster.EntityZombie;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
@@ -21,6 +22,7 @@ import net.minecraft.item.ItemStack;
|
|||||||
import net.minecraft.pathfinding.Path;
|
import net.minecraft.pathfinding.Path;
|
||||||
import net.minecraft.pathfinding.PathNodeType;
|
import net.minecraft.pathfinding.PathNodeType;
|
||||||
import net.minecraft.pathfinding.PathPoint;
|
import net.minecraft.pathfinding.PathPoint;
|
||||||
|
import net.minecraft.tileentity.TileEntityDispenser;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.text.TextComponentTranslation;
|
import net.minecraft.util.text.TextComponentTranslation;
|
||||||
@@ -44,8 +46,8 @@ public class Clairvoyance extends Spell {
|
|||||||
WizardData.registerStoredVariables(LOCATION_KEY, DIMENSION_KEY);
|
WizardData.registerStoredVariables(LOCATION_KEY, DIMENSION_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean canBeCastByNPCs() { return false; }
|
@Override public boolean canBeCastBy(EntityLiving npc, boolean override) { return false; }
|
||||||
@Override public boolean canBeCastByDispensers() { return false; }
|
@Override public boolean canBeCastBy(TileEntityDispenser dispenser) { return false; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
|
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package electroblob.wizardry.spell;
|
|||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import electroblob.wizardry.item.IConjuredItem;
|
import electroblob.wizardry.item.IConjuredItem;
|
||||||
import electroblob.wizardry.registry.WizardryItems;
|
import electroblob.wizardry.registry.WizardryItems;
|
||||||
|
import electroblob.wizardry.util.NBTExtras;
|
||||||
import electroblob.wizardry.util.SpellModifiers;
|
import electroblob.wizardry.util.SpellModifiers;
|
||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
@@ -40,7 +41,7 @@ public class ConjureArmour extends SpellConjuration {
|
|||||||
armour = new ItemStack(SPECTRAL_ARMOUR_MAP.get(slot));
|
armour = new ItemStack(SPECTRAL_ARMOUR_MAP.get(slot));
|
||||||
IConjuredItem.setDurationMultiplier(armour, modifiers.get(WizardryItems.duration_upgrade));
|
IConjuredItem.setDurationMultiplier(armour, modifiers.get(WizardryItems.duration_upgrade));
|
||||||
// Sets a blank "ench" tag to trick the renderer into showing the enchantment effect on the armour model
|
// Sets a blank "ench" tag to trick the renderer into showing the enchantment effect on the armour model
|
||||||
armour.getTagCompound().setTag("ench", new NBTTagList());
|
NBTExtras.storeTagSafely(armour.getTagCompound(), "ench", new NBTTagList());
|
||||||
caster.setItemStackToSlot(slot, armour);
|
caster.setItemStackToSlot(slot, armour);
|
||||||
flag = true;
|
flag = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,14 @@ import electroblob.wizardry.registry.WizardrySounds;
|
|||||||
import electroblob.wizardry.util.*;
|
import electroblob.wizardry.util.*;
|
||||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityLiving;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.EnumAction;
|
import net.minecraft.item.EnumAction;
|
||||||
import net.minecraft.nbt.NBTTagList;
|
import net.minecraft.nbt.NBTTagList;
|
||||||
import net.minecraft.nbt.NBTUtil;
|
import net.minecraft.nbt.NBTUtil;
|
||||||
import net.minecraft.potion.PotionEffect;
|
import net.minecraft.potion.PotionEffect;
|
||||||
|
import net.minecraft.tileentity.TileEntityDispenser;
|
||||||
import net.minecraft.util.DamageSource;
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@@ -45,9 +47,9 @@ public class CurseOfSoulbinding extends SpellRay {
|
|||||||
WizardData.registerStoredVariables(TARGETS_KEY);
|
WizardData.registerStoredVariables(TARGETS_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean canBeCastByNPCs() { return false; }
|
@Override public boolean canBeCastBy(EntityLiving npc, boolean override) { return false; }
|
||||||
// You can't damage a dispenser so this would be nonsense!
|
// You can't damage a dispenser so this would be nonsense!
|
||||||
@Override public boolean canBeCastByDispensers() { return false; }
|
@Override public boolean canBeCastBy(TileEntityDispenser dispenser) { return false; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public class Decoy extends Spell {
|
|||||||
addProperties(DECOY_LIFETIME, MOB_TRICK_CHANCE);
|
addProperties(DECOY_LIFETIME, MOB_TRICK_CHANCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean canBeCastByNPCs(){ return true; }
|
@Override public boolean canBeCastBy(EntityLiving npc, boolean override){ return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
|
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package electroblob.wizardry.spell;
|
package electroblob.wizardry.spell;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Settings;
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.block.BlockCrystalOre;
|
import electroblob.wizardry.block.BlockCrystalOre;
|
||||||
import electroblob.wizardry.registry.WizardryItems;
|
import electroblob.wizardry.registry.WizardryItems;
|
||||||
@@ -21,6 +22,7 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.text.TextComponentTranslation;
|
import net.minecraft.util.text.TextComponentTranslation;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
@@ -65,11 +67,13 @@ public class Divination extends Spell {
|
|||||||
|
|
||||||
List<BlockPos> sphere = WizardryUtilities.getBlockSphere(caster.getPosition(), range);
|
List<BlockPos> sphere = WizardryUtilities.getBlockSphere(caster.getPosition(), range);
|
||||||
|
|
||||||
sphere.removeIf(b -> !(world.getBlockState(b).getBlock() instanceof BlockOre
|
sphere.removeIf(b -> {
|
||||||
|| world.getBlockState(b).getBlock() instanceof BlockRedstoneOre
|
Block block = world.getBlockState(b).getBlock();
|
||||||
|| world.getBlockState(b).getBlock() instanceof BlockCrystalOre
|
return !(block instanceof BlockOre
|
||||||
|| Arrays.asList(Wizardry.settings.divinationOreWhitelist)
|
|| block instanceof BlockRedstoneOre
|
||||||
.contains(world.getBlockState(b).getBlock().getRegistryName())));
|
|| block instanceof BlockCrystalOre
|
||||||
|
|| Settings.containsMetaBlock(Wizardry.settings.divinationOreWhitelist, world.getBlockState(b)));
|
||||||
|
});
|
||||||
|
|
||||||
Strength strength = Strength.NOTHING;
|
Strength strength = Strength.NOTHING;
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ public class DragonFireball extends Spell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canBeCastByNPCs(){
|
public boolean canBeCastBy(EntityLiving npc, boolean override){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package electroblob.wizardry.spell;
|
package electroblob.wizardry.spell;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.entity.construct.EntityEarthquake;
|
import electroblob.wizardry.entity.construct.EntityEarthquake;
|
||||||
import electroblob.wizardry.registry.WizardryItems;
|
import electroblob.wizardry.registry.WizardryItems;
|
||||||
import electroblob.wizardry.util.SpellModifiers;
|
import electroblob.wizardry.util.SpellModifiers;
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.EnumAction;
|
import net.minecraft.item.EnumAction;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.EnumParticleTypes;
|
import net.minecraft.util.EnumParticleTypes;
|
||||||
@@ -53,6 +55,10 @@
|
|||||||
world.spawnParticle(EnumParticleTypes.BLOCK_DUST, particleX, y,
|
world.spawnParticle(EnumParticleTypes.BLOCK_DUST, particleX, y,
|
||||||
particleZ, particleX - x, 0, particleZ - z, Block.getStateId(block));
|
particleZ, particleX - x, 0, particleZ - z, Block.getStateId(block));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WizardryUtilities.getEntitiesWithinRadius(15, x, y, z, world, EntityPlayer.class)
|
||||||
|
.forEach(p -> Wizardry.proxy.shakeScreen(p, 12));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.spawnConstruct(world, x, y, z, side, caster, modifiers);
|
return super.spawnConstruct(world, x, y, z, side, caster, modifiers);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package electroblob.wizardry.spell;
|
package electroblob.wizardry.spell;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.constants.Constants;
|
import electroblob.wizardry.constants.Constants;
|
||||||
import electroblob.wizardry.event.SpellCastEvent;
|
import electroblob.wizardry.event.SpellCastEvent;
|
||||||
import electroblob.wizardry.registry.WizardryItems;
|
import electroblob.wizardry.registry.WizardryItems;
|
||||||
@@ -66,10 +67,16 @@ public class EmpoweringPresence extends Spell {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTranslationKey(){
|
||||||
|
return Wizardry.tisTheSeason ? super.getTranslationKey() + "_festive" : super.getTranslationKey();
|
||||||
|
}
|
||||||
|
|
||||||
@SubscribeEvent(priority = EventPriority.LOW) // Doesn't really matter but there's no point processing it if casting is blocked
|
@SubscribeEvent(priority = EventPriority.LOW) // Doesn't really matter but there's no point processing it if casting is blocked
|
||||||
public static void onSpellCastPreEvent(SpellCastEvent.Pre event){
|
public static void onSpellCastPreEvent(SpellCastEvent.Pre event){
|
||||||
// Empowerment stacks extra potency on top of the existing potency.
|
// Empowerment stacks extra potency on top of the existing potency.
|
||||||
if(event.getCaster() != null && event.getCaster().isPotionActive(WizardryPotions.empowerment)){
|
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 + Constants.EMPOWERMENT_POTENCY_PER_LEVEL
|
||||||
* (event.getCaster().getActivePotionEffect(WizardryPotions.empowerment).getAmplifier() + 1);
|
* (event.getCaster().getActivePotionEffect(WizardryPotions.empowerment).getAmplifier() + 1);
|
||||||
@@ -78,4 +85,5 @@ public class EmpoweringPresence extends Spell {
|
|||||||
event.getModifiers().get(SpellModifiers.POTENCY) * potency, true);
|
event.getModifiers().get(SpellModifiers.POTENCY) * potency, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -31,7 +31,7 @@ public class FlamingWeapon extends Spell {
|
|||||||
|
|
||||||
for(ItemStack stack : WizardryUtilities.getPrioritisedHotbarAndOffhand(caster)){
|
for(ItemStack stack : WizardryUtilities.getPrioritisedHotbarAndOffhand(caster)){
|
||||||
|
|
||||||
if((ImbueWeapon.isSword(stack.getItem()) || ImbueWeapon.isBow(stack.getItem()))
|
if((ImbueWeapon.isSword(stack) || ImbueWeapon.isBow(stack))
|
||||||
&& !EnchantmentHelper.getEnchantments(stack).containsKey(WizardryEnchantments.flaming_weapon)){
|
&& !EnchantmentHelper.getEnchantments(stack).containsKey(WizardryEnchantments.flaming_weapon)){
|
||||||
// The enchantment level as determined by the damage multiplier. The + 0.5f is so that
|
// The enchantment level as determined by the damage multiplier. The + 0.5f is so that
|
||||||
// weird float processing doesn't incorrectly round it down.
|
// weird float processing doesn't incorrectly round it down.
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import net.minecraft.entity.EntityLivingBase;
|
|||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.EnumAction;
|
import net.minecraft.item.EnumAction;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.tileentity.TileEntityDispenser;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@@ -29,8 +30,8 @@ public class ForestOfThorns extends Spell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean requiresPacket(){ return false; }
|
@Override public boolean requiresPacket(){ return false; }
|
||||||
@Override public boolean canBeCastByNPCs(){ return true; }
|
@Override public boolean canBeCastBy(EntityLiving npc, boolean override){ return true; }
|
||||||
@Override public boolean canBeCastByDispensers(){ return true; }
|
@Override public boolean canBeCastBy(TileEntityDispenser dispenser){ return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
|
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class FreezingWeapon extends Spell {
|
|||||||
|
|
||||||
for(ItemStack stack : WizardryUtilities.getPrioritisedHotbarAndOffhand(caster)){
|
for(ItemStack stack : WizardryUtilities.getPrioritisedHotbarAndOffhand(caster)){
|
||||||
|
|
||||||
if((ImbueWeapon.isSword(stack.getItem()) || ImbueWeapon.isBow(stack.getItem()))
|
if((ImbueWeapon.isSword(stack) || ImbueWeapon.isBow(stack))
|
||||||
&& !EnchantmentHelper.getEnchantments(stack).containsKey(WizardryEnchantments.freezing_weapon)){
|
&& !EnchantmentHelper.getEnchantments(stack).containsKey(WizardryEnchantments.freezing_weapon)){
|
||||||
// The enchantment level as determined by the damage multiplier. The + 0.5f is so that
|
// The enchantment level as determined by the damage multiplier. The + 0.5f is so that
|
||||||
// weird float processing doesn't incorrectly round it down.
|
// weird float processing doesn't incorrectly round it down.
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ public class FrostAxe extends SpellConjuration {
|
|||||||
|
|
||||||
public FrostAxe(){
|
public FrostAxe(){
|
||||||
super("frost_axe", WizardryItems.frost_axe);
|
super("frost_axe", WizardryItems.frost_axe);
|
||||||
|
addProperties(DAMAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import net.minecraft.entity.EntityLivingBase;
|
|||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.EnumAction;
|
import net.minecraft.item.EnumAction;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.SoundEvent;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class Glide extends Spell {
|
public class Glide extends Spell {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import net.minecraft.entity.player.EntityPlayer;
|
|||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
import net.minecraft.item.EnumAction;
|
import net.minecraft.item.EnumAction;
|
||||||
import net.minecraft.network.play.server.SPacketEntityVelocity;
|
import net.minecraft.network.play.server.SPacketEntityVelocity;
|
||||||
|
import net.minecraft.tileentity.TileEntityDispenser;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.SoundEvent;
|
import net.minecraft.util.SoundEvent;
|
||||||
@@ -58,12 +59,12 @@ public class Grapple extends Spell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canBeCastByNPCs(){
|
public boolean canBeCastBy(EntityLiving npc, boolean override){
|
||||||
return super.canBeCastByNPCs();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canBeCastByDispensers(){
|
public boolean canBeCastBy(TileEntityDispenser dispenser){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,12 +9,14 @@ import electroblob.wizardry.util.ParticleBuilder.Type;
|
|||||||
import electroblob.wizardry.util.SpellModifiers;
|
import electroblob.wizardry.util.SpellModifiers;
|
||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityLiving;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.item.EntityTNTPrimed;
|
import net.minecraft.entity.item.EntityTNTPrimed;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
import net.minecraft.item.EnumAction;
|
import net.minecraft.item.EnumAction;
|
||||||
import net.minecraft.network.play.server.SPacketEntityVelocity;
|
import net.minecraft.network.play.server.SPacketEntityVelocity;
|
||||||
|
import net.minecraft.tileentity.TileEntityDispenser;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.SoundEvent;
|
import net.minecraft.util.SoundEvent;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@@ -41,8 +43,8 @@ public class GreaterTelekinesis extends SpellRay {
|
|||||||
this.soundValues(0.8f, 1, 0.2f);
|
this.soundValues(0.8f, 1, 0.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean canBeCastByNPCs() { return false; }
|
@Override public boolean canBeCastBy(EntityLiving npc, boolean override) { return false; }
|
||||||
@Override public boolean canBeCastByDispensers() { return false; }
|
@Override public boolean canBeCastBy(TileEntityDispenser dispenser) { return false; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected SoundEvent[] createSounds(){
|
protected SoundEvent[] createSounds(){
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package electroblob.wizardry.spell;
|
package electroblob.wizardry.spell;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Settings;
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.constants.Constants;
|
import electroblob.wizardry.constants.Constants;
|
||||||
import electroblob.wizardry.data.WizardData;
|
import electroblob.wizardry.data.WizardData;
|
||||||
@@ -11,9 +12,13 @@ import electroblob.wizardry.util.SpellModifiers;
|
|||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.enchantment.EnchantmentHelper;
|
import net.minecraft.enchantment.EnchantmentHelper;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.*;
|
import net.minecraft.item.EnumAction;
|
||||||
|
import net.minecraft.item.ItemBow;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.ItemSword;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@@ -32,7 +37,7 @@ public class ImbueWeapon extends Spell {
|
|||||||
|
|
||||||
for(ItemStack stack : WizardryUtilities.getPrioritisedHotbarAndOffhand(caster)){
|
for(ItemStack stack : WizardryUtilities.getPrioritisedHotbarAndOffhand(caster)){
|
||||||
|
|
||||||
if(isSword(stack.getItem())
|
if(isSword(stack)
|
||||||
&& !EnchantmentHelper.getEnchantments(stack).containsKey(WizardryEnchantments.magic_sword)
|
&& !EnchantmentHelper.getEnchantments(stack).containsKey(WizardryEnchantments.magic_sword)
|
||||||
&& WizardData.get(caster).getImbuementDuration(WizardryEnchantments.magic_sword) <= 0){
|
&& WizardData.get(caster).getImbuementDuration(WizardryEnchantments.magic_sword) <= 0){
|
||||||
// The enchantment level as determined by the damage multiplier. The + 0.5f is so that
|
// The enchantment level as determined by the damage multiplier. The + 0.5f is so that
|
||||||
@@ -44,7 +49,7 @@ public class ImbueWeapon extends Spell {
|
|||||||
WizardData.get(caster).setImbuementDuration(WizardryEnchantments.magic_sword,
|
WizardData.get(caster).setImbuementDuration(WizardryEnchantments.magic_sword,
|
||||||
(int)(getProperty(EFFECT_DURATION).floatValue() * modifiers.get(WizardryItems.duration_upgrade)));
|
(int)(getProperty(EFFECT_DURATION).floatValue() * modifiers.get(WizardryItems.duration_upgrade)));
|
||||||
|
|
||||||
}else if(isBow(stack.getItem())
|
}else if(isBow(stack)
|
||||||
&& !EnchantmentHelper.getEnchantments(stack).containsKey(WizardryEnchantments.magic_bow)
|
&& !EnchantmentHelper.getEnchantments(stack).containsKey(WizardryEnchantments.magic_bow)
|
||||||
&& WizardData.get(caster).getImbuementDuration(WizardryEnchantments.magic_bow) <= 0){
|
&& WizardData.get(caster).getImbuementDuration(WizardryEnchantments.magic_bow) <= 0){
|
||||||
// The enchantment level as determined by the damage multiplier. The + 0.5f is so that
|
// The enchantment level as determined by the damage multiplier. The + 0.5f is so that
|
||||||
@@ -77,13 +82,13 @@ public class ImbueWeapon extends Spell {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if the given item counts as a sword, i.e. it extends {@link ItemSword} or is in the whitelist. */
|
/** Returns true if the given item counts as a sword, i.e. it extends {@link ItemSword} or is in the whitelist. */
|
||||||
public static boolean isSword(Item item){
|
public static boolean isSword(ItemStack stack){
|
||||||
return item instanceof ItemSword || Arrays.asList(Wizardry.settings.swordItemWhitelist).contains(item.getRegistryName());
|
return stack.getItem() instanceof ItemSword || Settings.containsMetaItem(Wizardry.settings.swordItemWhitelist, stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns true if the given item counts as a bow, i.e. it extends {@link ItemBow} or is in the whitelist. */
|
/** Returns true if the given item counts as a bow, i.e. it extends {@link ItemBow} or is in the whitelist. */
|
||||||
public static boolean isBow(Item item){
|
public static boolean isBow(ItemStack stack){
|
||||||
return item instanceof ItemBow || Arrays.asList(Wizardry.settings.bowItemWhitelist).contains(item.getRegistryName());
|
return stack.getItem() instanceof ItemBow || Settings.containsMetaItem(Wizardry.settings.bowItemWhitelist, stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package electroblob.wizardry.spell;
|
package electroblob.wizardry.spell;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.registry.WizardryItems;
|
import electroblob.wizardry.registry.WizardryItems;
|
||||||
import electroblob.wizardry.util.AllyDesignationSystem;
|
import electroblob.wizardry.util.AllyDesignationSystem;
|
||||||
import electroblob.wizardry.util.ParticleBuilder;
|
import electroblob.wizardry.util.ParticleBuilder;
|
||||||
@@ -62,4 +63,9 @@ public class InvigoratingPresence extends Spell {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTranslationKey(){
|
||||||
|
return Wizardry.tisTheSeason ? super.getTranslationKey() + "_festive" : super.getTranslationKey();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import electroblob.wizardry.util.ParticleBuilder.Type;
|
|||||||
import electroblob.wizardry.util.SpellModifiers;
|
import electroblob.wizardry.util.SpellModifiers;
|
||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityLiving;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.monster.*;
|
import net.minecraft.entity.monster.*;
|
||||||
import net.minecraft.entity.passive.*;
|
import net.minecraft.entity.passive.*;
|
||||||
@@ -52,7 +53,7 @@ public class Metamorphosis extends SpellRay {
|
|||||||
this.soundValues(0.5f, 1f, 0);
|
this.soundValues(0.5f, 1f, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean canBeCastByNPCs() { return false; }
|
@Override public boolean canBeCastBy(EntityLiving npc, boolean override) { return false; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import net.minecraft.item.EnumAction;
|
|||||||
import net.minecraft.item.EnumDyeColor;
|
import net.minecraft.item.EnumDyeColor;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.potion.PotionEffect;
|
import net.minecraft.potion.PotionEffect;
|
||||||
|
import net.minecraft.tileentity.TileEntityDispenser;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
@@ -43,8 +44,8 @@ public class MindControl extends SpellRay {
|
|||||||
addProperties(EFFECT_DURATION);
|
addProperties(EFFECT_DURATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean canBeCastByNPCs() { return false; }
|
@Override public boolean canBeCastBy(EntityLiving npc, boolean override) { return false; }
|
||||||
@Override public boolean canBeCastByDispensers() { return false; }
|
@Override public boolean canBeCastBy(TileEntityDispenser dispenser) { return false; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
||||||
|
|||||||
@@ -43,8 +43,7 @@ public class PhaseStep extends Spell {
|
|||||||
world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5);
|
world.rand.nextDouble() - 0.5, world.rand.nextDouble() - 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can't be bothered to route this through the proxies!
|
Wizardry.proxy.playBlinkEffect(caster);
|
||||||
electroblob.wizardry.client.WizardryClientEventHandler.playBlinkEffect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
|
if(rayTrace != null && rayTrace.typeOfHit == RayTraceResult.Type.BLOCK){
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package electroblob.wizardry.spell;
|
package electroblob.wizardry.spell;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Settings;
|
||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.util.SpellModifiers;
|
import electroblob.wizardry.util.SpellModifiers;
|
||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
@@ -10,8 +11,6 @@ import net.minecraft.util.EnumHand;
|
|||||||
import net.minecraft.util.EnumParticleTypes;
|
import net.minecraft.util.EnumParticleTypes;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
public class PocketFurnace extends Spell {
|
public class PocketFurnace extends Spell {
|
||||||
|
|
||||||
public static final String ITEMS_SMELTED = "items_smelted";
|
public static final String ITEMS_SMELTED = "items_smelted";
|
||||||
@@ -37,9 +36,9 @@ public class PocketFurnace extends Spell {
|
|||||||
|
|
||||||
result = FurnaceRecipes.instance().getSmeltingResult(stack);
|
result = FurnaceRecipes.instance().getSmeltingResult(stack);
|
||||||
|
|
||||||
if(!result.isEmpty() && !(result.getItem() instanceof ItemTool) && !(result.getItem() instanceof ItemSword)
|
if(!result.isEmpty() && !(stack.getItem() instanceof ItemTool) && !(stack.getItem() instanceof ItemSword)
|
||||||
&& !(result.getItem() instanceof ItemArmor)
|
&& !(stack.getItem() instanceof ItemArmor)
|
||||||
&& !Arrays.asList(Wizardry.settings.pocketFurnaceItemBlacklist).contains(result.getItem().getRegistryName())){
|
&& !Settings.containsMetaItem(Wizardry.settings.pocketFurnaceItemBlacklist, stack)){
|
||||||
|
|
||||||
if(stack.getCount() <= usesLeft){
|
if(stack.getCount() <= usesLeft){
|
||||||
ItemStack stack2 = new ItemStack(result.getItem(), stack.getCount(), result.getItemDamage());
|
ItemStack stack2 = new ItemStack(result.getItem(), stack.getCount(), result.getItemDamage());
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import electroblob.wizardry.util.ParticleBuilder.Type;
|
|||||||
import electroblob.wizardry.util.SpellModifiers;
|
import electroblob.wizardry.util.SpellModifiers;
|
||||||
import electroblob.wizardry.util.WizardryUtilities;
|
import electroblob.wizardry.util.WizardryUtilities;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityLiving;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.init.MobEffects;
|
import net.minecraft.init.MobEffects;
|
||||||
@@ -28,7 +29,7 @@ public class Poison extends SpellRay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canBeCastByNPCs(){
|
public boolean canBeCastBy(EntityLiving npc, boolean override){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user