Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4cde8c60bc | |||
| 9924e10f13 | |||
| eeb0640525 | |||
| 693c11ada0 | |||
| 038fd7225f | |||
| 999e32f37c | |||
| 8c2ac5adbb | |||
| 9c1e2e08c3 | |||
| e7f7960540 | |||
| a46bad4497 | |||
| 06d02ad45d | |||
| c39a213e62 | |||
| 2caca39a22 | |||
| 8d46191ff8 | |||
| fb7af9328d | |||
| 0991baf964 | |||
| bdefecbe9b | |||
| eef48f319a | |||
| 3a788c867c | |||
| 1ba723ade1 | |||
| c06105cd00 | |||
| 97c72685bb | |||
| 23fccaac9c | |||
| 74b6bdba0f | |||
| d69e3a253d | |||
| 744c7a2331 | |||
| c355cb034c | |||
| 5e321cc4cf | |||
| fbecce0543 | |||
| a6c24e9cb6 | |||
| 14a624db3f | |||
| 16a4c8231f | |||
| 931c99617c | |||
| 037f340a03 | |||
| b6cc417641 | |||
| 6565a0734a | |||
| 0aac70c5fb | |||
| 8551dc407b | |||
| 1eec7921ce | |||
| 18920a24c5 | |||
| e0c6f0f00f | |||
| a4f6391fac | |||
| a570bd57d0 | |||
| f1ff179b98 | |||
| 6d09acc78e | |||
| 960d97de49 | |||
| ebe64b06e3 | |||
| 99887f95e2 | |||
| 2e5a9fce3e |
@@ -10,7 +10,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/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.2 [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.]
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
name: Question
|
||||||
|
about: Ask a question about the mod or the code
|
||||||
|
title: "[Give a brief, relevant title here]"
|
||||||
|
labels: question
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting.
|
||||||
|
|
||||||
|
Minecraft version: 1.12.2 [change as necessary]
|
||||||
|
Wizardry version: 4.2.2 [change as necessary]
|
||||||
|
|
||||||
|
Question details: [explain your question here]
|
||||||
|
|
||||||
|
Other mods involved: [if this question involves other mods, list them here]
|
||||||
+10
-3
@@ -18,11 +18,18 @@ In addition, I'd like to thank the following individuals for their contributions
|
|||||||
- 12foo
|
- 12foo
|
||||||
- Shadows-of-Fire
|
- Shadows-of-Fire
|
||||||
- HellFirePvP
|
- HellFirePvP
|
||||||
|
- Tora-B
|
||||||
|
- Avatair
|
||||||
|
- Aeronica
|
||||||
|
|
||||||
#### Translations
|
#### Translations
|
||||||
|
|
||||||
- Russian: VilagVil
|
- Spanish and Mexican Spanish: MadWrist
|
||||||
- Spanish and Mexican Spanish: MadWrist
|
- Russian: VilagVil, kellixon
|
||||||
- Chinese: ZHENGLOC and dragon-evol
|
- French: Hahdrim
|
||||||
|
- Brazilian Portuguese: lorrampi
|
||||||
|
- Chinese: ZHENGLOC, dragon-evol
|
||||||
|
- Korean: shejery, rewi_wire
|
||||||
|
- Polish: Trozuu
|
||||||
|
|
||||||
Lightning ray sound effect from OhhWowProductions
|
Lightning ray sound effect from OhhWowProductions
|
||||||
|
|||||||
+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.1" // There, it matches semver, happy now?
|
version = "4.2.2" // 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"
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ When submitting an issue, I would be grateful if you could follow these few guid
|
|||||||
|
|
||||||
- Please stick to the issue template, it's there to help you provide the right information so I can fix the problem more easily. If you're not sure what to put for anything, that's ok, just leave it as it is.
|
- Please stick to the issue template, it's there to help you provide the right information so I can fix the problem more easily. If you're not sure what to put for anything, that's ok, just leave it as it is.
|
||||||
|
|
||||||
|
- One issue per issue please! Make a separate issue for each bug/suggestion. If you think multiple different issues may be related, reference between them using # followed by the issue number.
|
||||||
|
|
||||||
- Please give me as much information about the issue as you can, but keep it relevant. "This is really annoying me and my friend" does not help me fix the problem!
|
- Please give me as much information about the issue as you can, but keep it relevant. "This is really annoying me and my friend" does not help me fix the problem!
|
||||||
|
|
||||||
- Make sure your wizardry and Forge versions are both up-to-date for the game version you are using.
|
- Make sure your wizardry and Forge versions are both up-to-date for the game version you are using.
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ public final class Settings {
|
|||||||
/** <b>[Server-only]</b> List of dimension ids in which to generate wizard towers. */
|
/** <b>[Server-only]</b> List of dimension ids in which to generate wizard towers. */
|
||||||
public int[] towerDimensions = {0};
|
public int[] towerDimensions = {0};
|
||||||
/** <b>[Server-only]</b> The rarity of wizard towers, used by the world generator. Larger numbers are rarer. */
|
/** <b>[Server-only]</b> The rarity of wizard towers, used by the world generator. Larger numbers are rarer. */
|
||||||
public int towerRarity = 600;
|
public int towerRarity = 900;
|
||||||
/** <b>[Server-only]</b> List of structure file locations for wizard towers without loot chests. */
|
/** <b>[Server-only]</b> List of structure file locations for wizard towers without loot chests. */
|
||||||
public ResourceLocation[] towerFiles = {new ResourceLocation(Wizardry.MODID, "wizard_tower_0"),
|
public ResourceLocation[] towerFiles = {new ResourceLocation(Wizardry.MODID, "wizard_tower_0"),
|
||||||
new ResourceLocation(Wizardry.MODID, "wizard_tower_1"),
|
new ResourceLocation(Wizardry.MODID, "wizard_tower_1"),
|
||||||
@@ -103,7 +103,7 @@ public final class Settings {
|
|||||||
/** <b>[Server-only]</b> List of dimension ids in which to generate obelisks. */
|
/** <b>[Server-only]</b> List of dimension ids in which to generate obelisks. */
|
||||||
public int[] obeliskDimensions = {0, -1};
|
public int[] obeliskDimensions = {0, -1};
|
||||||
/** <b>[Server-only]</b> The rarity of obelisks, used by the world generator. Larger numbers are rarer. */
|
/** <b>[Server-only]</b> The rarity of obelisks, used by the world generator. Larger numbers are rarer. */
|
||||||
public int obeliskRarity = 550;
|
public int obeliskRarity = 800;
|
||||||
/** <b>[Server-only]</b> List of structure file locations for obelisks. */
|
/** <b>[Server-only]</b> List of structure file locations for obelisks. */
|
||||||
public ResourceLocation[] obeliskFiles = {new ResourceLocation(Wizardry.MODID, "obelisk_0"),
|
public ResourceLocation[] obeliskFiles = {new ResourceLocation(Wizardry.MODID, "obelisk_0"),
|
||||||
new ResourceLocation(Wizardry.MODID, "obelisk_1"),
|
new ResourceLocation(Wizardry.MODID, "obelisk_1"),
|
||||||
@@ -113,7 +113,7 @@ public final class Settings {
|
|||||||
/** <b>[Server-only]</b> List of dimension ids in which to generate shrines. */
|
/** <b>[Server-only]</b> List of dimension ids in which to generate shrines. */
|
||||||
public int[] shrineDimensions = {0, -1};
|
public int[] shrineDimensions = {0, -1};
|
||||||
/** <b>[Server-only]</b> The rarity of shrines, used by the world generator. Larger numbers are rarer. */
|
/** <b>[Server-only]</b> The rarity of shrines, used by the world generator. Larger numbers are rarer. */
|
||||||
public int shrineRarity = 1000;
|
public int shrineRarity = 1500;
|
||||||
/** <b>[Server-only]</b> List of structure file locations for shrines. */
|
/** <b>[Server-only]</b> List of structure file locations for shrines. */
|
||||||
public ResourceLocation[] shrineFiles = {new ResourceLocation(Wizardry.MODID, "shrine_0"),
|
public ResourceLocation[] shrineFiles = {new ResourceLocation(Wizardry.MODID, "shrine_0"),
|
||||||
new ResourceLocation(Wizardry.MODID, "shrine_1"),
|
new ResourceLocation(Wizardry.MODID, "shrine_1"),
|
||||||
@@ -706,7 +706,7 @@ public final class Settings {
|
|||||||
towerDimensions = property.getIntList();
|
towerDimensions = property.getIntList();
|
||||||
propOrder.add(property.getName());
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
property = config.get(WORLDGEN_CATEGORY, "towerRarity", 600, "Rarity of wizard towers. 1 in this many chunks will contain a wizard tower, meaning higher numbers are rarer.", 20, 5000);
|
property = config.get(WORLDGEN_CATEGORY, "towerRarity", 900, "Rarity of wizard towers. 1 in this many chunks will contain a wizard tower, meaning higher numbers are rarer.", 20, 5000);
|
||||||
property.setLanguageKey("config." + Wizardry.MODID + ".tower_rarity");
|
property.setLanguageKey("config." + Wizardry.MODID + ".tower_rarity");
|
||||||
property.setRequiresWorldRestart(true);
|
property.setRequiresWorldRestart(true);
|
||||||
Wizardry.proxy.setToNumberSliderEntry(property);
|
Wizardry.proxy.setToNumberSliderEntry(property);
|
||||||
@@ -744,7 +744,7 @@ public final class Settings {
|
|||||||
obeliskDimensions = property.getIntList();
|
obeliskDimensions = property.getIntList();
|
||||||
propOrder.add(property.getName());
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
property = config.get(WORLDGEN_CATEGORY, "obeliskRarity", 550, "Rarity of obelisks. 1 in this many chunks will contain an obelisk, meaning higher numbers are rarer.", 20, 5000);
|
property = config.get(WORLDGEN_CATEGORY, "obeliskRarity", 800, "Rarity of obelisks. 1 in this many chunks will contain an obelisk, meaning higher numbers are rarer.", 20, 5000);
|
||||||
property.setLanguageKey("config." + Wizardry.MODID + ".obelisk_rarity");
|
property.setLanguageKey("config." + Wizardry.MODID + ".obelisk_rarity");
|
||||||
property.setRequiresWorldRestart(true);
|
property.setRequiresWorldRestart(true);
|
||||||
Wizardry.proxy.setToNumberSliderEntry(property);
|
Wizardry.proxy.setToNumberSliderEntry(property);
|
||||||
@@ -764,7 +764,7 @@ public final class Settings {
|
|||||||
shrineDimensions = property.getIntList();
|
shrineDimensions = property.getIntList();
|
||||||
propOrder.add(property.getName());
|
propOrder.add(property.getName());
|
||||||
|
|
||||||
property = config.get(WORLDGEN_CATEGORY, "shrineRarity", 1000, "Rarity of shrines. 1 in this many chunks will contain a shrine, meaning higher numbers are rarer.", 20, 5000);
|
property = config.get(WORLDGEN_CATEGORY, "shrineRarity", 1500, "Rarity of shrines. 1 in this many chunks will contain a shrine, meaning higher numbers are rarer.", 20, 5000);
|
||||||
property.setLanguageKey("config." + Wizardry.MODID + ".shrine_rarity");
|
property.setLanguageKey("config." + Wizardry.MODID + ".shrine_rarity");
|
||||||
property.setRequiresWorldRestart(true);
|
property.setRequiresWorldRestart(true);
|
||||||
Wizardry.proxy.setToNumberSliderEntry(property);
|
Wizardry.proxy.setToNumberSliderEntry(property);
|
||||||
|
|||||||
@@ -41,7 +41,10 @@ import org.apache.logging.log4j.Logger;
|
|||||||
* @author Electroblob
|
* @author Electroblob
|
||||||
* @since Wizardry 1.0
|
* @since Wizardry 1.0
|
||||||
*/
|
*/
|
||||||
@Mod(modid = Wizardry.MODID, name = Wizardry.NAME, version = Wizardry.VERSION, guiFactory = "electroblob.wizardry.WizardryGuiFactory")
|
|
||||||
|
@Mod(modid = Wizardry.MODID, name = Wizardry.NAME, version = Wizardry.VERSION, acceptedMinecraftVersions = "[1.12.2]",
|
||||||
|
guiFactory = "electroblob.wizardry.WizardryGuiFactory", dependencies = "required-after:forge@[14.23.5.2814,)")
|
||||||
|
|
||||||
public class Wizardry {
|
public class Wizardry {
|
||||||
|
|
||||||
/** Wizardry's mod ID. */
|
/** Wizardry's mod ID. */
|
||||||
@@ -51,14 +54,14 @@ public class Wizardry {
|
|||||||
/**
|
/**
|
||||||
* The version number for this version of wizardry. The following system is used for version numbers:
|
* The version number for this version of wizardry. The following system is used for version numbers:
|
||||||
* <p></p>
|
* <p></p>
|
||||||
* <center><b>[major Minecraft version].[major mod version].[minor mod version/patch]
|
* <center><b>[major Minecraft version].[major mod version].[minor mod version/patch]</b>
|
||||||
* <p></p>
|
* <p></p>
|
||||||
* </center></b> The major mod version is consistent across Minecraft versions, i.e. Wizardry 1.1 has the same
|
* </center> The major mod version is consistent across Minecraft versions, i.e. Wizardry 1.1 has the same
|
||||||
* features as Wizardry 2.1, but they are for different versions of Minecraft and have separate minor versioning.
|
* features as Wizardry 2.1, but they are for different versions of Minecraft and have separate minor versioning.
|
||||||
* 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.1";
|
public static final String VERSION = "4.2.2";
|
||||||
|
|
||||||
// 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
|
||||||
@@ -110,6 +113,8 @@ public class Wizardry {
|
|||||||
proxy.registerRenderers();
|
proxy.registerRenderers();
|
||||||
proxy.registerKeyBindings();
|
proxy.registerKeyBindings();
|
||||||
|
|
||||||
|
WizardrySounds.SPELLS = CustomSoundCategory.add(Wizardry.MODID + "_spells");
|
||||||
|
|
||||||
WizardryBaublesIntegration.init();
|
WizardryBaublesIntegration.init();
|
||||||
WizardryAntiqueAtlasIntegration.init();
|
WizardryAntiqueAtlasIntegration.init();
|
||||||
|
|
||||||
@@ -148,8 +153,6 @@ public class Wizardry {
|
|||||||
proxy.initGuiBits();
|
proxy.initGuiBits();
|
||||||
proxy.registerParticles();
|
proxy.registerParticles();
|
||||||
proxy.registerSoundEventListener();
|
proxy.registerSoundEventListener();
|
||||||
|
|
||||||
WizardrySounds.SPELLS = CustomSoundCategory.add(Wizardry.MODID + ":spells");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import net.minecraft.block.material.Material;
|
|||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.BlockRenderLayer;
|
import net.minecraft.util.BlockRenderLayer;
|
||||||
import net.minecraft.util.EnumBlockRenderType;
|
|
||||||
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.world.IBlockAccess;
|
import net.minecraft.world.IBlockAccess;
|
||||||
@@ -34,26 +33,16 @@ public class BlockSpectral extends Block implements ITileEntityProvider {
|
|||||||
|
|
||||||
// Replaces getRenderBlockPass
|
// Replaces getRenderBlockPass
|
||||||
@Override
|
@Override
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
public BlockRenderLayer getRenderLayer(){
|
public BlockRenderLayer getRenderLayer(){
|
||||||
return BlockRenderLayer.TRANSLUCENT;
|
return BlockRenderLayer.TRANSLUCENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// See BlockTransportationStone for what all these do
|
||||||
public EnumBlockRenderType getRenderType(IBlockState state){
|
@Override public boolean isFullCube(IBlockState state){ return false; }
|
||||||
return EnumBlockRenderType.MODEL;
|
@Override public boolean isBlockNormalCube(IBlockState state){ return false; }
|
||||||
}
|
@Override public boolean isNormalCube(IBlockState state){ return false; }
|
||||||
|
@Override public boolean isOpaqueCube(IBlockState state){ return false; }
|
||||||
// Apparently it's OK to override this, despite it being deprecated. More importantly, it being deprecated is not
|
|
||||||
// Forge's doing, rather it is Mojang themselves misusing the @Deprecated annotation to mean 'internal, don't call'.
|
|
||||||
@Override
|
|
||||||
public boolean isOpaqueCube(IBlockState state){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random){
|
public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random){
|
||||||
@@ -67,12 +56,12 @@ public class BlockSpectral extends Block implements ITileEntityProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overriden to make the block always look full brightness despite not emitting
|
// // Overriden to make the block always look full brightness despite not emitting
|
||||||
// full light.
|
// // full light.
|
||||||
@Override
|
// @Override
|
||||||
public int getPackedLightmapCoords(IBlockState state, IBlockAccess source, BlockPos pos){
|
// public int getPackedLightmapCoords(IBlockState state, IBlockAccess source, BlockPos pos){
|
||||||
return 15;
|
// return 15;
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTileEntity(IBlockState state){
|
public boolean hasTileEntity(IBlockState state){
|
||||||
|
|||||||
@@ -62,18 +62,12 @@ public class BlockTransportationStone extends Block {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forge version of the above method. I still need to override both though because vanilla uses the other one.
|
|
||||||
@Override
|
|
||||||
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... and this one is for rendering.
|
// ... and this one is for rendering.
|
||||||
@Override
|
@Override
|
||||||
public boolean isOpaqueCube(IBlockState state){
|
public boolean isOpaqueCube(IBlockState state){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSideSolid(IBlockState base_state, IBlockAccess world, BlockPos pos, EnumFacing side){
|
public boolean isSideSolid(IBlockState base_state, IBlockAccess world, BlockPos pos, EnumFacing side){
|
||||||
return side == EnumFacing.DOWN;
|
return side == EnumFacing.DOWN;
|
||||||
@@ -147,7 +141,7 @@ 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(locations.size() - 1, here);
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -425,14 +425,15 @@ public class ClientProxy extends CommonProxy {
|
|||||||
// Again, no need to check if the spell succeeded, because the packet is only ever sent when it
|
// Again, no need to check if the spell succeeded, because the packet is only ever sent when it
|
||||||
// succeeds.
|
// succeeds.
|
||||||
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(Source.NPC, spell, (EntityLiving)caster, message.modifiers));
|
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(Source.NPC, spell, (EntityLiving)caster, message.modifiers));
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
((EntityLiving)caster).setAttackTarget((EntityLivingBase)target);
|
((EntityLiving)caster).setAttackTarget((EntityLivingBase)target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}else if(caster != null){
|
}else if(caster != null){
|
||||||
Wizardry.logger.warn("Recieved a PacketNPCCastSpell, but the caster ID was not the ID of an EntityLiving");
|
Wizardry.logger.warn("Recieved a PacketNPCCastSpell, but the caster ID was not the ID of an EntityLiving");
|
||||||
}
|
}
|
||||||
@@ -474,6 +475,9 @@ public class ClientProxy extends CommonProxy {
|
|||||||
|
|
||||||
World world = Minecraft.getMinecraft().world;
|
World world = Minecraft.getMinecraft().world;
|
||||||
Entity caster = world.getEntityByID(message.casterID);
|
Entity caster = world.getEntityByID(message.casterID);
|
||||||
|
|
||||||
|
if(caster == null) return; // Shouldn't happen
|
||||||
|
|
||||||
// Moved from when the packet is sent to when it is received; fixes the sound not playing in first person.
|
// Moved from when the packet is sent to when it is received; fixes the sound not playing in first person.
|
||||||
caster.playSound(WizardrySounds.SPELL_TRANSPORTATION_TRAVEL, 1, 1);
|
caster.playSound(WizardrySounds.SPELL_TRANSPORTATION_TRAVEL, 1, 1);
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ package electroblob.wizardry.client.gui;
|
|||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.client.DrawingUtils;
|
import electroblob.wizardry.client.DrawingUtils;
|
||||||
import electroblob.wizardry.constants.Element;
|
import electroblob.wizardry.constants.Element;
|
||||||
|
import electroblob.wizardry.constants.Tier;
|
||||||
import electroblob.wizardry.data.SpellGlyphData;
|
import electroblob.wizardry.data.SpellGlyphData;
|
||||||
import electroblob.wizardry.data.WizardData;
|
import electroblob.wizardry.data.WizardData;
|
||||||
import electroblob.wizardry.item.IManaStoringItem;
|
import electroblob.wizardry.item.IManaStoringItem;
|
||||||
import electroblob.wizardry.item.ISpellCastingItem;
|
import electroblob.wizardry.item.ISpellCastingItem;
|
||||||
import electroblob.wizardry.item.IWorkbenchItem;
|
import electroblob.wizardry.item.IWorkbenchItem;
|
||||||
|
import electroblob.wizardry.item.ItemWand;
|
||||||
import electroblob.wizardry.packet.PacketControlInput;
|
import electroblob.wizardry.packet.PacketControlInput;
|
||||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||||
import electroblob.wizardry.registry.WizardrySounds;
|
import electroblob.wizardry.registry.WizardrySounds;
|
||||||
@@ -29,6 +31,8 @@ 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.minecraftforge.client.event.TextureStitchEvent;
|
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||||
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;
|
||||||
@@ -47,21 +51,25 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
|||||||
private IInventory arcaneWorkbenchInventory;
|
private IInventory arcaneWorkbenchInventory;
|
||||||
|
|
||||||
private static final int TOOLTIP_WIDTH = 164;
|
private static final int TOOLTIP_WIDTH = 164;
|
||||||
|
private static final int TOOLTIP_TEXT_INSET = 6;
|
||||||
|
|
||||||
/** We report the actual size of the GUI to Minecraft when a wand is in so JEI doesn't overdraw it.
|
/** We report the actual size of the GUI to Minecraft when a wand is in so JEI doesn't overdraw it.
|
||||||
* For calculations, we use the size without the tooltip, which is stored in this constant. */
|
* For calculations, we use the size without the tooltip, which is stored in this constant. */
|
||||||
private static final int MAIN_GUI_WIDTH = 176;
|
private static final int MAIN_GUI_WIDTH = 176;
|
||||||
|
|
||||||
private static final int RUNE_LEFT = 38;
|
private static final int RUNE_LEFT = 38;
|
||||||
private static final int RUNE_TOP = 22;
|
private static final int RUNE_TOP = 22;
|
||||||
private static final int RUNE_WIDTH = 100;
|
private static final int RUNE_WIDTH = 100;
|
||||||
private static final int RUNE_HEIGHT = 100;
|
private static final int RUNE_HEIGHT = 100;
|
||||||
|
|
||||||
|
private static final int PROGRESSION_BAR_WIDTH = 152;
|
||||||
|
private static final int PROGRESSION_BAR_HEIGHT = 3;
|
||||||
|
|
||||||
private static final int HALO_DIAMETER = 156;
|
private static final int HALO_DIAMETER = 156;
|
||||||
|
|
||||||
private static final int TEXTURE_WIDTH = 512;
|
private static final int TEXTURE_WIDTH = 512;
|
||||||
private static final int TEXTURE_HEIGHT = 256;
|
private static final int TEXTURE_HEIGHT = 256;
|
||||||
|
|
||||||
private int animationTimer = 0;
|
private int animationTimer = 0;
|
||||||
private static final int ANIMATION_DURATION = 20;
|
private static final int ANIMATION_DURATION = 20;
|
||||||
|
|
||||||
@@ -113,28 +121,28 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
|||||||
|
|
||||||
GlStateManager.color(1, 1, 1, 1);
|
GlStateManager.color(1, 1, 1, 1);
|
||||||
Minecraft.getMinecraft().renderEngine.bindTexture(texture);
|
Minecraft.getMinecraft().renderEngine.bindTexture(texture);
|
||||||
|
|
||||||
// Animation
|
// Animation
|
||||||
|
|
||||||
// Grey background
|
// Grey background
|
||||||
DrawingUtils.drawTexturedRect(guiLeft + RUNE_LEFT, guiTop + RUNE_TOP, MAIN_GUI_WIDTH + TOOLTIP_WIDTH, 0,
|
DrawingUtils.drawTexturedRect(guiLeft + RUNE_LEFT, guiTop + RUNE_TOP, MAIN_GUI_WIDTH + TOOLTIP_WIDTH, 0,
|
||||||
RUNE_WIDTH, RUNE_HEIGHT, TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
RUNE_WIDTH, RUNE_HEIGHT, TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
||||||
|
|
||||||
// Yellow 'halo'
|
// Yellow 'halo'
|
||||||
if(animationTimer > 0){
|
if(animationTimer > 0){
|
||||||
|
|
||||||
GlStateManager.pushMatrix();
|
GlStateManager.pushMatrix();
|
||||||
GlStateManager.enableBlend();
|
GlStateManager.enableBlend();
|
||||||
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
int x = guiLeft + RUNE_LEFT + RUNE_WIDTH/2;
|
int x = guiLeft + RUNE_LEFT + RUNE_WIDTH/2;
|
||||||
int y = guiTop + RUNE_TOP + RUNE_HEIGHT/2;
|
int y = guiTop + RUNE_TOP + RUNE_HEIGHT/2;
|
||||||
|
|
||||||
float scale = (animationTimer + partialTicks)/ANIMATION_DURATION;
|
float scale = (animationTimer + partialTicks)/ANIMATION_DURATION;
|
||||||
scale = (float)(1 - Math.pow(1-scale, 1.4f)); // Makes it slower at the start and speed up
|
scale = (float)(1 - Math.pow(1-scale, 1.4f)); // Makes it slower at the start and speed up
|
||||||
GlStateManager.scale(scale, scale, 1);
|
GlStateManager.scale(scale, scale, 1);
|
||||||
GlStateManager.translate(x/scale, y/scale, 0);
|
GlStateManager.translate(x/scale, y/scale, 0);
|
||||||
|
|
||||||
DrawingUtils.drawTexturedRect(-HALO_DIAMETER /2, -HALO_DIAMETER /2, MAIN_GUI_WIDTH + TOOLTIP_WIDTH, RUNE_HEIGHT,
|
DrawingUtils.drawTexturedRect(-HALO_DIAMETER /2, -HALO_DIAMETER /2, MAIN_GUI_WIDTH + TOOLTIP_WIDTH, RUNE_HEIGHT,
|
||||||
HALO_DIAMETER, HALO_DIAMETER, TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
HALO_DIAMETER, HALO_DIAMETER, TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
||||||
|
|
||||||
@@ -232,6 +240,26 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
|||||||
y += 14;
|
y += 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Progression bar
|
||||||
|
if(stack.getItem() instanceof ItemWand && !Wizardry.settings.legacyWandLevelling){
|
||||||
|
|
||||||
|
y += 10;
|
||||||
|
|
||||||
|
Tier tier = ((ItemWand)stack.getItem()).tier;
|
||||||
|
|
||||||
|
float progressFraction = 1;
|
||||||
|
|
||||||
|
if(tier != Tier.MASTER){
|
||||||
|
progressFraction = (float)WandHelper.getProgression(stack) / Tier.values()[tier.level + 1].progression;
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawingUtils.drawTexturedRect(guiLeft + MAIN_GUI_WIDTH + TOOLTIP_TEXT_INSET, y, MAIN_GUI_WIDTH, ySize + PROGRESSION_BAR_HEIGHT, PROGRESSION_BAR_WIDTH, PROGRESSION_BAR_HEIGHT, TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
||||||
|
int width = (int)(PROGRESSION_BAR_WIDTH * progressFraction);
|
||||||
|
DrawingUtils.drawTexturedRect(guiLeft + MAIN_GUI_WIDTH + TOOLTIP_TEXT_INSET, y, MAIN_GUI_WIDTH, ySize, width, PROGRESSION_BAR_HEIGHT, TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
||||||
|
|
||||||
|
y += 8;
|
||||||
|
}
|
||||||
|
|
||||||
if(stack.getItem() instanceof ISpellCastingItem && ((ISpellCastingItem)stack.getItem()).showSpellsInWorkbench(this.mc.player, stack)){
|
if(stack.getItem() instanceof ISpellCastingItem && ((ISpellCastingItem)stack.getItem()).showSpellsInWorkbench(this.mc.player, stack)){
|
||||||
|
|
||||||
Spell[] spells = ((ISpellCastingItem)stack.getItem()).getSpells(stack);
|
Spell[] spells = ((ISpellCastingItem)stack.getItem()).getSpells(stack);
|
||||||
@@ -251,7 +279,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
|||||||
.bindTexture(discovered ? spell.getElement().getIcon() : Element.MAGIC.getIcon());
|
.bindTexture(discovered ? spell.getElement().getIcon() : Element.MAGIC.getIcon());
|
||||||
|
|
||||||
// Renders the little element icon
|
// Renders the little element icon
|
||||||
DrawingUtils.drawTexturedRect(guiLeft + MAIN_GUI_WIDTH + 5, y, 8, 8);
|
DrawingUtils.drawTexturedRect(guiLeft + MAIN_GUI_WIDTH + TOOLTIP_TEXT_INSET - 1, y, 8, 8);
|
||||||
|
|
||||||
y += 10;
|
y += 10;
|
||||||
}
|
}
|
||||||
@@ -270,8 +298,8 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
|||||||
if(level > 0){
|
if(level > 0){
|
||||||
ItemStack stack1 = new ItemStack(item, level);
|
ItemStack stack1 = new ItemStack(item, level);
|
||||||
GlStateManager.enableDepth();
|
GlStateManager.enableDepth();
|
||||||
this.itemRender.renderItemAndEffectIntoGUI(stack1, guiLeft + MAIN_GUI_WIDTH + 6 + x, y);
|
this.itemRender.renderItemAndEffectIntoGUI(stack1, guiLeft + MAIN_GUI_WIDTH + TOOLTIP_TEXT_INSET + x, y);
|
||||||
this.itemRender.renderItemOverlayIntoGUI(this.fontRenderer, stack1, guiLeft + MAIN_GUI_WIDTH + 6 + x, y,
|
this.itemRender.renderItemOverlayIntoGUI(this.fontRenderer, stack1, guiLeft + MAIN_GUI_WIDTH + TOOLTIP_TEXT_INSET + x, y,
|
||||||
null);
|
null);
|
||||||
x += 18;
|
x += 18;
|
||||||
GlStateManager.disableDepth();
|
GlStateManager.disableDepth();
|
||||||
@@ -311,7 +339,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
|||||||
|
|
||||||
int y = 6;
|
int y = 6;
|
||||||
|
|
||||||
this.fontRenderer.drawStringWithShadow("\u00A7f" + stack.getDisplayName(), MAIN_GUI_WIDTH + 6, y, 0);
|
this.fontRenderer.drawStringWithShadow("\u00A7f" + stack.getDisplayName(), MAIN_GUI_WIDTH + TOOLTIP_TEXT_INSET, y, 0);
|
||||||
|
|
||||||
if(stack.getItem() instanceof IManaStoringItem && ((IManaStoringItem)stack.getItem()).showManaInWorkbench(this.mc.player, stack)){
|
if(stack.getItem() instanceof IManaStoringItem && ((IManaStoringItem)stack.getItem()).showManaInWorkbench(this.mc.player, stack)){
|
||||||
y += 14;
|
y += 14;
|
||||||
@@ -319,7 +347,27 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
|||||||
"\u00A77" + I18n.format("container." + Wizardry.MODID + ":arcane_workbench.mana")
|
"\u00A77" + I18n.format("container." + Wizardry.MODID + ":arcane_workbench.mana")
|
||||||
+ " " + ((IManaStoringItem)stack.getItem()).getMana(stack) + "/"
|
+ " " + ((IManaStoringItem)stack.getItem()).getMana(stack) + "/"
|
||||||
+ ((IManaStoringItem)stack.getItem()).getManaCapacity(stack),
|
+ ((IManaStoringItem)stack.getItem()).getManaCapacity(stack),
|
||||||
MAIN_GUI_WIDTH + 6, y, 0);
|
MAIN_GUI_WIDTH + TOOLTIP_TEXT_INSET, y, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Progression tier text
|
||||||
|
if(stack.getItem() instanceof ItemWand && !Wizardry.settings.legacyWandLevelling){
|
||||||
|
|
||||||
|
y += 14;
|
||||||
|
|
||||||
|
Tier tier = ((ItemWand)stack.getItem()).tier;
|
||||||
|
|
||||||
|
this.fontRenderer.drawStringWithShadow(tier.getDisplayNameWithFormatting(), MAIN_GUI_WIDTH + TOOLTIP_TEXT_INSET, y, 0);
|
||||||
|
|
||||||
|
if(tier != Tier.MASTER){
|
||||||
|
Tier nextTier = Tier.values()[tier.level + 1];
|
||||||
|
String s = TextFormatting.DARK_GRAY.toString() + nextTier.getDisplayName();
|
||||||
|
if(WandHelper.getProgression(stack) >= nextTier.progression) s = nextTier.getDisplayNameWithFormatting();
|
||||||
|
this.fontRenderer.drawStringWithShadow(s, MAIN_GUI_WIDTH + TOOLTIP_WIDTH
|
||||||
|
- TOOLTIP_TEXT_INSET - fontRenderer.getStringWidth(s), y, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
y += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
y += 14;
|
y += 14;
|
||||||
@@ -337,10 +385,10 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(discovered){
|
if(discovered){
|
||||||
this.fontRenderer.drawStringWithShadow(spell.getDisplayNameWithFormatting(), MAIN_GUI_WIDTH + 16, y, 0);
|
this.fontRenderer.drawStringWithShadow(spell.getDisplayNameWithFormatting(), MAIN_GUI_WIDTH + TOOLTIP_TEXT_INSET + 10, y, 0);
|
||||||
}else{
|
}else{
|
||||||
this.mc.standardGalacticFontRenderer.drawStringWithShadow(
|
this.mc.standardGalacticFontRenderer.drawStringWithShadow(
|
||||||
"\u00A79" + SpellGlyphData.getGlyphName(spell, this.mc.world), MAIN_GUI_WIDTH + 16, y, 0);
|
"\u00A79" + SpellGlyphData.getGlyphName(spell, this.mc.world), MAIN_GUI_WIDTH + TOOLTIP_TEXT_INSET + 10, y, 0);
|
||||||
}
|
}
|
||||||
y += 10;
|
y += 10;
|
||||||
}
|
}
|
||||||
@@ -351,7 +399,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
|||||||
y += 6;
|
y += 6;
|
||||||
|
|
||||||
this.fontRenderer.drawStringWithShadow("\u00A7f" + I18n.format("container."
|
this.fontRenderer.drawStringWithShadow("\u00A7f" + I18n.format("container."
|
||||||
+ Wizardry.MODID + ":arcane_workbench.upgrades"), MAIN_GUI_WIDTH + 6, y, 0);
|
+ Wizardry.MODID + ":arcane_workbench.upgrades"), MAIN_GUI_WIDTH + TOOLTIP_TEXT_INSET, y, 0);
|
||||||
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
y += 10;
|
y += 10;
|
||||||
@@ -364,7 +412,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
|||||||
if(level > 0){
|
if(level > 0){
|
||||||
// The javadoc for isPointInRegion is ambiguous; what it means is that the REGION is
|
// The javadoc for isPointInRegion is ambiguous; what it means is that the REGION is
|
||||||
// relative to the GUI but the POINT isn't.
|
// relative to the GUI but the POINT isn't.
|
||||||
if(isPointInRegion(MAIN_GUI_WIDTH + 6 + x, y, 16, 16, mouseX, mouseY)){
|
if(isPointInRegion(MAIN_GUI_WIDTH + TOOLTIP_TEXT_INSET + x, y, 16, 16, mouseX, mouseY)){
|
||||||
ItemStack stack1 = new ItemStack(item, level);
|
ItemStack stack1 = new ItemStack(item, level);
|
||||||
this.renderToolTip(stack1, mouseX - guiLeft, mouseY - guiTop);
|
this.renderToolTip(stack1, mouseX - guiLeft, mouseY - guiTop);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ public class GuiWizardHandbook extends GuiScreen {
|
|||||||
addFormatTag("advanced_max_charge", "" + Tier.ADVANCED.maxCharge);
|
addFormatTag("advanced_max_charge", "" + Tier.ADVANCED.maxCharge);
|
||||||
addFormatTag("master_max_charge", "" + Tier.MASTER.maxCharge);
|
addFormatTag("master_max_charge", "" + Tier.MASTER.maxCharge);
|
||||||
addFormatTag("version", Wizardry.VERSION);
|
addFormatTag("version", Wizardry.VERSION);
|
||||||
addFormatTag("mcversion", Minecraft.getMinecraft().getVersion());
|
addFormatTag("mcversion", "1.12.2");
|
||||||
|
|
||||||
addFormatTag("colour_novice", "\u00A77");
|
addFormatTag("colour_novice", "\u00A77");
|
||||||
addFormatTag("colour_apprentice", Tier.APPRENTICE.getFormattingCode());
|
addFormatTag("colour_apprentice", Tier.APPRENTICE.getFormattingCode());
|
||||||
|
|||||||
@@ -282,6 +282,9 @@ public final class WizardryModels {
|
|||||||
if(location.getPath().contains("runestone") || location.getPath().contains("runestone_pedestal")){
|
if(location.getPath().contains("runestone") || location.getPath().contains("runestone_pedestal")){
|
||||||
IBakedModel original = event.getModelRegistry().getObject(location);
|
IBakedModel original = event.getModelRegistry().getObject(location);
|
||||||
event.getModelRegistry().putObject(location, new BakedModelGlowingOverlay(original, "overlay"));
|
event.getModelRegistry().putObject(location, new BakedModelGlowingOverlay(original, "overlay"));
|
||||||
|
}else if(location.getPath().contains("spectral_block")){
|
||||||
|
IBakedModel original = event.getModelRegistry().getObject(location);
|
||||||
|
event.getModelRegistry().putObject(location, new BakedModelGlowingOverlay(original, "spectral_block"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,8 +40,6 @@ public class ParticlePath extends ParticleWizardry {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdate(){
|
public void onUpdate(){
|
||||||
|
|
||||||
super.onUpdate();
|
|
||||||
|
|
||||||
this.prevPosX = this.posX;
|
this.prevPosX = this.posX;
|
||||||
this.prevPosY = this.posY;
|
this.prevPosY = this.posY;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class ParticleTornado extends ParticleDigging {
|
|||||||
public ParticleTornado(World world, int maxAge, double originX, double originZ, double radius, double yPos,
|
public ParticleTornado(World world, int maxAge, double originX, double originZ, double radius, double yPos,
|
||||||
double velX, double velZ, IBlockState block){
|
double velX, double velZ, IBlockState block){
|
||||||
super(world, 0, 0, 0, 0, 0, 0, block);
|
super(world, 0, 0, 0, 0, 0, 0, block);
|
||||||
float angle = this.rand.nextFloat() * (float)Math.PI * 2;
|
this.angle = this.rand.nextFloat() * (float)Math.PI * 2;
|
||||||
double x = originX - MathHelper.cos(angle) * radius;
|
double x = originX - MathHelper.cos(angle) * radius;
|
||||||
double z = originZ + radius * MathHelper.sin(angle);
|
double z = originZ + radius * MathHelper.sin(angle);
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
|||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Mod.EventBusSubscriber(Side.CLIENT)
|
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||||
public class RenderArcaneLock {
|
public class RenderArcaneLock {
|
||||||
|
|
||||||
@@ -54,9 +57,14 @@ public class RenderArcaneLock {
|
|||||||
BufferBuilder buffer = tessellator.getBuffer();
|
BufferBuilder buffer = tessellator.getBuffer();
|
||||||
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
|
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
|
||||||
|
|
||||||
for(TileEntity tileentity : world.loadedTileEntityList){
|
// Someone managed to get a CME here so let's just copy the list to be safe
|
||||||
|
// It's only cosmetic so if a tileentity somehow gets removed while we're rendering them it's not a big deal
|
||||||
|
List<TileEntity> tileentities = new ArrayList<>(world.loadedTileEntityList);
|
||||||
|
|
||||||
if(tileentity.getDistanceSq(origin.x, origin.y, origin.z) <= 64*64 && tileentity.getTileData().hasUniqueId(ArcaneLock.NBT_KEY)){
|
for(TileEntity tileentity : tileentities){
|
||||||
|
|
||||||
|
if(tileentity.getDistanceSq(origin.x, origin.y, origin.z) <= tileentity.getMaxRenderDistanceSquared()
|
||||||
|
&& tileentity.getTileData().hasUniqueId(ArcaneLock.NBT_KEY)){
|
||||||
|
|
||||||
Vec3d[] vertices = WizardryUtilities.getVertices(world.getBlockState(tileentity.getPos()).getBoundingBox(world, tileentity.getPos()).grow(0.05).offset(tileentity.getPos()));
|
Vec3d[] vertices = WizardryUtilities.getVertices(world.getBlockState(tileentity.getPos()).getBoundingBox(world, tileentity.getPos()).grow(0.05).offset(tileentity.getPos()));
|
||||||
|
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ import java.util.Random;
|
|||||||
public enum Tier {
|
public enum Tier {
|
||||||
|
|
||||||
NOVICE(700, 3, 12, 0, new Style().setColor(TextFormatting.WHITE), "novice"),
|
NOVICE(700, 3, 12, 0, new Style().setColor(TextFormatting.WHITE), "novice"),
|
||||||
APPRENTICE(1000, 5, 5, 6000, new Style().setColor(TextFormatting.AQUA), "apprentice"),
|
APPRENTICE(1000, 5, 5, 4000, new Style().setColor(TextFormatting.AQUA), "apprentice"),
|
||||||
ADVANCED(1500, 7, 2, 9000, new Style().setColor(TextFormatting.DARK_BLUE), "advanced"),
|
ADVANCED(1500, 7, 2, 6000, new Style().setColor(TextFormatting.DARK_BLUE), "advanced"),
|
||||||
MASTER(2500, 9, 1, 15000, new Style().setColor(TextFormatting.DARK_PURPLE), "master");
|
MASTER(2500, 9, 1, 10000, new Style().setColor(TextFormatting.DARK_PURPLE), "master");
|
||||||
|
|
||||||
/** Maximum mana a wand of this tier can store. */
|
/** Maximum mana a wand of this tier can store. */
|
||||||
public final int maxCharge;
|
public final int maxCharge;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import electroblob.wizardry.enchantment.Imbuement;
|
|||||||
import electroblob.wizardry.entity.living.ISummonedCreature;
|
import electroblob.wizardry.entity.living.ISummonedCreature;
|
||||||
import electroblob.wizardry.event.SpellCastEvent;
|
import electroblob.wizardry.event.SpellCastEvent;
|
||||||
import electroblob.wizardry.event.SpellCastEvent.Source;
|
import electroblob.wizardry.event.SpellCastEvent.Source;
|
||||||
|
import electroblob.wizardry.item.ItemWand;
|
||||||
import electroblob.wizardry.packet.PacketCastContinuousSpell;
|
import electroblob.wizardry.packet.PacketCastContinuousSpell;
|
||||||
import electroblob.wizardry.packet.PacketPlayerSync;
|
import electroblob.wizardry.packet.PacketPlayerSync;
|
||||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||||
@@ -71,7 +72,7 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
|
|||||||
private static final Set<IStoredVariable> storedVariables = new HashSet<>();
|
private static final Set<IStoredVariable> storedVariables = new HashSet<>();
|
||||||
|
|
||||||
/** The maximum number of recent spells to track. */
|
/** The maximum number of recent spells to track. */
|
||||||
public static final int MAX_RECENT_SPELLS = 10;
|
public static final int MAX_RECENT_SPELLS = ItemWand.BASE_SPELL_SLOTS;
|
||||||
|
|
||||||
/** The player this WizardData instance belongs to. */
|
/** The player this WizardData instance belongs to. */
|
||||||
private final EntityPlayer player;
|
private final EntityPlayer player;
|
||||||
@@ -140,7 +141,7 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
|
|||||||
// All players can recognise magic missile. This is not done using discoverSpell because that seems to cause
|
// All players can recognise magic missile. This is not done using discoverSpell because that seems to cause
|
||||||
// a crash on load occasionally (probably something to do with achievements being initialised)
|
// a crash on load occasionally (probably something to do with achievements being initialised)
|
||||||
this.spellsDiscovered.add(Spells.magic_missile);
|
this.spellsDiscovered.add(Spells.magic_missile);
|
||||||
this.recentSpells = EvictingQueue.create(MAX_RECENT_SPELLS); // Only keeps a reference to the last 10 spells cast
|
this.recentSpells = EvictingQueue.create(MAX_RECENT_SPELLS); // Only keeps a reference to the last 5 spells cast
|
||||||
this.castCommandSpell = Spells.none;
|
this.castCommandSpell = Spells.none;
|
||||||
this.castCommandModifiers = new SpellModifiers();
|
this.castCommandModifiers = new SpellModifiers();
|
||||||
this.castCommandTick = 0;
|
this.castCommandTick = 0;
|
||||||
@@ -272,7 +273,7 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
|
|||||||
* @param spell The spell to count casts for.
|
* @param spell The spell to count casts for.
|
||||||
*/
|
*/
|
||||||
public int countRecentCasts(Spell spell){
|
public int countRecentCasts(Spell spell){
|
||||||
return (int)this.recentSpells.stream().filter(s -> s == spell).count(); // We know this can't be more than 10
|
return (int)this.recentSpells.stream().filter(s -> s == spell).count(); // We know this can't be more than 5
|
||||||
}
|
}
|
||||||
|
|
||||||
// Imbuements
|
// Imbuements
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
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;
|
||||||
@@ -33,7 +34,8 @@ public class EntityCombustionRune extends EntityMagicConstruct {
|
|||||||
|
|
||||||
float strength = Spells.combustion_rune.getProperty(Spell.BLAST_RADIUS).floatValue();
|
float strength = Spells.combustion_rune.getProperty(Spell.BLAST_RADIUS).floatValue();
|
||||||
|
|
||||||
world.newExplosion(this.getCaster(), this.posX, this.posY, this.posZ, strength, true, true);
|
world.newExplosion(this.getCaster(), this.posX, this.posY, this.posZ, strength, true,
|
||||||
|
getCaster() != null && WizardryUtilities.canDamageBlocks(getCaster(), world));
|
||||||
|
|
||||||
// The trap is destroyed once triggered.
|
// The trap is destroyed once triggered.
|
||||||
this.setDead();
|
this.setDead();
|
||||||
|
|||||||
@@ -81,7 +81,9 @@ public class ItemLightningHammer extends Item implements IConjuredItem {
|
|||||||
Multimap<String, AttributeModifier> multimap = super.getItemAttributeModifiers(slot);
|
Multimap<String, AttributeModifier> multimap = super.getItemAttributeModifiers(slot);
|
||||||
|
|
||||||
if(slot == EntityEquipmentSlot.MAINHAND){
|
if(slot == EntityEquipmentSlot.MAINHAND){
|
||||||
multimap.put(SharedMonsterAttributes.ATTACK_DAMAGE.getName(), new AttributeModifier(ATTACK_DAMAGE_MODIFIER, "Weapon modifier", Spells.lightning_hammer.getProperty(Spell.DIRECT_DAMAGE).floatValue(), WizardryUtilities.Operations.ADD));
|
float attackDamage = Spells.lightning_hammer.arePropertiesInitialised() ?
|
||||||
|
Spells.lightning_hammer.getProperty(Spell.DIRECT_DAMAGE).floatValue() : 10; // Fallback for search tree init, value doesn't really matter
|
||||||
|
multimap.put(SharedMonsterAttributes.ATTACK_DAMAGE.getName(), new AttributeModifier(ATTACK_DAMAGE_MODIFIER, "Weapon modifier", attackDamage, WizardryUtilities.Operations.ADD));
|
||||||
multimap.put(SharedMonsterAttributes.ATTACK_SPEED.getName(), new AttributeModifier(ATTACK_SPEED_MODIFIER, "Weapon modifier", ATTACK_SPEED, WizardryUtilities.Operations.ADD));
|
multimap.put(SharedMonsterAttributes.ATTACK_SPEED.getName(), new AttributeModifier(ATTACK_SPEED_MODIFIER, "Weapon modifier", ATTACK_SPEED, WizardryUtilities.Operations.ADD));
|
||||||
multimap.put(SharedMonsterAttributes.MOVEMENT_SPEED.getName(), new AttributeModifier(MOVEMENT_SPEED_MODIFIER, "Weapon modifier", MOVEMENT_SPEED_REDUCTION, WizardryUtilities.Operations.MULTIPLY_FLAT));
|
multimap.put(SharedMonsterAttributes.MOVEMENT_SPEED.getName(), new AttributeModifier(MOVEMENT_SPEED_MODIFIER, "Weapon modifier", MOVEMENT_SPEED_REDUCTION, WizardryUtilities.Operations.MULTIPLY_FLAT));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
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;
|
||||||
@@ -22,6 +23,9 @@ 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;
|
||||||
|
|
||||||
public class ItemScroll extends Item implements ISpellCastingItem {
|
public class ItemScroll extends Item implements ISpellCastingItem {
|
||||||
|
|
||||||
@@ -80,6 +84,25 @@ public class ItemScroll extends Item implements ISpellCastingItem {
|
|||||||
return Wizardry.proxy.getScrollDisplayName(stack);
|
return Wizardry.proxy.getScrollDisplayName(stack);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SideOnly(Side.CLIENT)
|
||||||
|
public void addInformation(ItemStack itemstack, World world, List<String> tooltip, net.minecraft.client.util.ITooltipFlag advanced){
|
||||||
|
|
||||||
|
if(world != null){
|
||||||
|
|
||||||
|
Spell spell = Spell.byMetadata(itemstack.getItemDamage());
|
||||||
|
|
||||||
|
boolean discovered = Wizardry.proxy.shouldDisplayDiscovered(spell, itemstack);
|
||||||
|
|
||||||
|
// Advanced tooltips display more information, mainly for searching purposes in creative
|
||||||
|
if(discovered && advanced.isAdvanced()){ // No cheating!
|
||||||
|
tooltip.add(spell.getTier().getDisplayName());
|
||||||
|
tooltip.add(spell.getElement().getDisplayName());
|
||||||
|
tooltip.add(spell.getType().getDisplayName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getMaxItemUseDuration(ItemStack stack){
|
public int getMaxItemUseDuration(ItemStack stack){
|
||||||
|
|||||||
@@ -71,9 +71,10 @@ public class ItemSpectralBow extends ItemBow implements IConjuredItem {
|
|||||||
|
|
||||||
if(!oldStack.isEmpty() || !newStack.isEmpty()){
|
if(!oldStack.isEmpty() || !newStack.isEmpty()){
|
||||||
// We only care about the situation where we specifically want the animation NOT to play.
|
// We only care about the situation where we specifically want the animation NOT to play.
|
||||||
if(oldStack.getItem() == newStack.getItem() && !slotChanged
|
if(oldStack.getItem() == newStack.getItem() && !slotChanged)
|
||||||
// This code should only run on the client side, so using Minecraft is ok.
|
// This code should only run on the client side, so using Minecraft is ok.
|
||||||
&& !net.minecraft.client.Minecraft.getMinecraft().player.isHandActive())
|
// Why the heck was this here?
|
||||||
|
//&& !net.minecraft.client.Minecraft.getMinecraft().player.isHandActive())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,10 +64,13 @@ public class ItemSpellBook extends Item {
|
|||||||
: "#\u00A79" + SpellGlyphData.getGlyphName(spell, world));
|
: "#\u00A79" + SpellGlyphData.getGlyphName(spell, world));
|
||||||
|
|
||||||
tooltip.add(spell.getTier().getDisplayNameWithFormatting());
|
tooltip.add(spell.getTier().getDisplayNameWithFormatting());
|
||||||
|
|
||||||
|
// Advanced tooltips display more information, mainly for searching purposes in creative
|
||||||
|
if(discovered && advanced.isAdvanced()){ // No cheating!
|
||||||
|
tooltip.add(spell.getElement().getDisplayName());
|
||||||
|
tooltip.add(spell.getType().getDisplayName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Removed to streamline the tooltip a bit. Information is now within the book. if(spell.isContinuous){
|
|
||||||
* tooltip.add("\u00A79Mana Cost: " + spell.cost + " per second"); }else{ tooltip.add("\u00A79Mana Cost: " +
|
|
||||||
* spell.cost); } */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
|||||||
private static final int CONTINUOUS_TRACKING_INTERVAL = 20;
|
private static final int CONTINUOUS_TRACKING_INTERVAL = 20;
|
||||||
/** The increase in progression for casting spells of the matching element. */
|
/** The increase in progression for casting spells of the matching element. */
|
||||||
private static final float ELEMENTAL_PROGRESSION_MODIFIER = 1.2f;
|
private static final float ELEMENTAL_PROGRESSION_MODIFIER = 1.2f;
|
||||||
|
/** The increase in progression for casting an undiscovered spell (can only happen once per spell for each player). */
|
||||||
|
private static final float DISCOVERY_PROGRESSION_MODIFIER = 5f;
|
||||||
/** The fraction of progression lost when all recently-cast spells are the same as the one being cast. */
|
/** The fraction of progression lost when all recently-cast spells are the same as the one being cast. */
|
||||||
private static final float MAX_PROGRESSION_REDUCTION = 0.75f;
|
private static final float MAX_PROGRESSION_REDUCTION = 0.75f;
|
||||||
|
|
||||||
@@ -573,6 +575,11 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
|||||||
progressionModifier *= ELEMENTAL_PROGRESSION_MODIFIER;
|
progressionModifier *= ELEMENTAL_PROGRESSION_MODIFIER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(WizardData.get(player) != null && !WizardData.get(player).hasSpellBeenDiscovered(spell)){
|
||||||
|
// Casting an undiscovered spell now grants 5x progression
|
||||||
|
progressionModifier *= DISCOVERY_PROGRESSION_MODIFIER;
|
||||||
|
}
|
||||||
|
|
||||||
modifiers.set(SpellModifiers.PROGRESSION, progressionModifier, false);
|
modifiers.set(SpellModifiers.PROGRESSION, progressionModifier, false);
|
||||||
|
|
||||||
return modifiers;
|
return modifiers;
|
||||||
@@ -635,6 +642,8 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
|||||||
// WandHelper.setProgression(centre.getStack(), WandHelper.getProgression(centre.getStack()) - tier.progression);
|
// WandHelper.setProgression(centre.getStack(), WandHelper.getProgression(centre.getStack()) - tier.progression);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
WandHelper.setProgression(centre.getStack(), 0);
|
||||||
|
|
||||||
ItemStack newWand = new ItemStack(WizardryItems.getWand(tier, this.element));
|
ItemStack newWand = new ItemStack(WizardryItems.getWand(tier, this.element));
|
||||||
newWand.setTagCompound(centre.getStack().getTagCompound());
|
newWand.setTagCompound(centre.getStack().getTagCompound());
|
||||||
// This needs to be done after copying the tag compound so the mana capacity for the new wand
|
// This needs to be done after copying the tag compound so the mana capacity for the new wand
|
||||||
|
|||||||
@@ -375,7 +375,7 @@ public abstract class Forfeit {
|
|||||||
if(!w.isRemote){
|
if(!w.isRemote){
|
||||||
for(EnumFacing direction : EnumFacing.HORIZONTALS){
|
for(EnumFacing direction : EnumFacing.HORIZONTALS){
|
||||||
BlockPos pos = p.getPosition().offset(direction);
|
BlockPos pos = p.getPosition().offset(direction);
|
||||||
w.setBlockState(pos, WizardryBlocks.snare.getDefaultState());
|
if(WizardryUtilities.canBlockBeReplaced(w, pos)) w.setBlockState(pos, WizardryBlocks.snare.getDefaultState());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
@@ -410,6 +410,7 @@ public abstract class Forfeit {
|
|||||||
if(!w.isRemote){
|
if(!w.isRemote){
|
||||||
List<BlockPos> sphere = WizardryUtilities.getBlockSphere(p.getPosition(), 4);
|
List<BlockPos> sphere = WizardryUtilities.getBlockSphere(p.getPosition(), 4);
|
||||||
sphere.removeIf(pos -> !w.getBlockState(pos).isFullCube());
|
sphere.removeIf(pos -> !w.getBlockState(pos).isFullCube());
|
||||||
|
sphere.removeIf(pos -> WizardryUtilities.isBlockUnbreakable(w, pos));
|
||||||
sphere.forEach(pos -> {
|
sphere.forEach(pos -> {
|
||||||
EntityFallingBlock block = new EntityFallingBlock(w, pos.getX() + 0.5, pos.getY() + 0.5,
|
EntityFallingBlock block = new EntityFallingBlock(w, pos.getX() + 0.5, pos.getY() + 0.5,
|
||||||
pos.getZ() + 0.5, w.getBlockState(pos));
|
pos.getZ() + 0.5, w.getBlockState(pos));
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
package electroblob.wizardry.misc;
|
||||||
|
|
||||||
|
import electroblob.wizardry.Wizardry;
|
||||||
|
import electroblob.wizardry.item.IManaStoringItem;
|
||||||
|
import electroblob.wizardry.item.ItemManaFlask;
|
||||||
|
import net.minecraft.inventory.InventoryCrafting;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.crafting.CraftingManager;
|
||||||
|
import net.minecraft.item.crafting.IRecipe;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.gameevent.PlayerEvent;
|
||||||
|
import net.minecraftforge.oredict.OreDictionary;
|
||||||
|
import net.minecraftforge.oredict.ShapelessOreRecipe;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements a dynamic crafting recipe for recharging items with mana flasks.
|
||||||
|
*
|
||||||
|
* @author Corail31, Electroblob
|
||||||
|
* @since Wizardry 4.2.2
|
||||||
|
*/
|
||||||
|
@Mod.EventBusSubscriber
|
||||||
|
public class RecipeRechargeWithFlask extends ShapelessOreRecipe {
|
||||||
|
|
||||||
|
private final IManaStoringItem chargeable;
|
||||||
|
private final ItemManaFlask flask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new charging recipe for the given chargeable item using the given flask item.
|
||||||
|
* @param chargeable The type of item to be charged
|
||||||
|
* @param flask The mana flask used to charge the item
|
||||||
|
*/
|
||||||
|
public RecipeRechargeWithFlask(Item chargeable, ItemManaFlask flask){
|
||||||
|
super(null, new ItemStack(chargeable, 1, OreDictionary.WILDCARD_VALUE),
|
||||||
|
new ItemStack(chargeable, 1, OreDictionary.WILDCARD_VALUE), flask);
|
||||||
|
if(!(chargeable instanceof IManaStoringItem)) throw new IllegalArgumentException("Item to be charged must be an instance of IManaStoringItem");
|
||||||
|
this.chargeable = (IManaStoringItem)chargeable;
|
||||||
|
this.flask = flask;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public ItemStack getRecipeOutput(){
|
||||||
|
return ItemStack.EMPTY; // According to the javadoc, dynamic recipes are supposed to return an empty stack here
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getCraftingResult(InventoryCrafting inv){
|
||||||
|
ItemStack result = super.getCraftingResult(inv);
|
||||||
|
rechargeItem(result, inv);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(InventoryCrafting inv, World world){
|
||||||
|
ItemStack stack = findItemToCharge(inv);
|
||||||
|
if(!stack.isEmpty() && chargeable.isManaFull(stack)) return false;
|
||||||
|
return super.matches(inv, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rechargeItem(ItemStack toCharge, InventoryCrafting inv){
|
||||||
|
if(toCharge.getItem() == chargeable){
|
||||||
|
ItemStack stack = findItemToCharge(inv);
|
||||||
|
if(!stack.isEmpty()) chargeable.setMana(toCharge, chargeable.getMana(stack));
|
||||||
|
chargeable.rechargeMana(toCharge, flask.size.capacity);
|
||||||
|
}else{
|
||||||
|
Wizardry.logger.warn("Tried to recharge item {} with mana flask, but it did not match the recipe result {}!", toCharge.getItem(), chargeable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack findItemToCharge(InventoryCrafting inv){
|
||||||
|
for(int i=0; i<inv.getSizeInventory(); i++){
|
||||||
|
ItemStack ingredient = inv.getStackInSlot(i);
|
||||||
|
if(ingredient.getItem() == chargeable) return ingredient;
|
||||||
|
}
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDynamic(){
|
||||||
|
return true; // Stops it appearing in the recipe book
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void onItemCraftedEvent(PlayerEvent.ItemCraftedEvent event){
|
||||||
|
// getCraftingResult seems to only work for the result that's displayed, not once it is actually taken
|
||||||
|
// This means that although I no longer have to replace the result every tick, I still need to do it here
|
||||||
|
// ... I thought the whole point of the new recipe system was so that I DIDN'T have to do this?!
|
||||||
|
if(event.craftMatrix instanceof InventoryCrafting){
|
||||||
|
for(IRecipe recipe : CraftingManager.REGISTRY){
|
||||||
|
if(recipe instanceof RecipeRechargeWithFlask
|
||||||
|
&& recipe.matches((InventoryCrafting)event.craftMatrix, event.player.world)){
|
||||||
|
// Have to modify the itemstack in the actual event, it cannot be replaced
|
||||||
|
((RecipeRechargeWithFlask)recipe).rechargeItem(event.crafting, (InventoryCrafting)event.craftMatrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -86,7 +86,7 @@ public final class WizardryBlocks {
|
|||||||
registerBlock(registry, "crystal_flower", new BlockCrystalFlower(Material.PLANTS).setHardness(0.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
registerBlock(registry, "crystal_flower", new BlockCrystalFlower(Material.PLANTS).setHardness(0.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||||
registerBlock(registry, "snare", new BlockSnare(Material.PLANTS).setHardness(0.0F));
|
registerBlock(registry, "snare", new BlockSnare(Material.PLANTS).setHardness(0.0F));
|
||||||
registerBlock(registry, "transportation_stone", new BlockTransportationStone(Material.ROCK).setHardness(0.3F).setLightLevel(0.5f).setLightOpacity(0).setCreativeTab(WizardryTabs.WIZARDRY));
|
registerBlock(registry, "transportation_stone", new BlockTransportationStone(Material.ROCK).setHardness(0.3F).setLightLevel(0.5f).setLightOpacity(0).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||||
registerBlock(registry, "spectral_block", new BlockSpectral(Material.GLASS).setLightLevel(0.7f).setLightOpacity(0).setBlockUnbreakable().setResistance(6000000.0F));
|
registerBlock(registry, "spectral_block", new BlockSpectral(Material.GLASS).setLightOpacity(1).setBlockUnbreakable().setResistance(6000000.0F));
|
||||||
registerBlock(registry, "crystal_block", new BlockCrystal(Material.IRON).setHardness(5.0F).setResistance(10.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
registerBlock(registry, "crystal_block", new BlockCrystal(Material.IRON).setHardness(5.0F).setResistance(10.0F).setCreativeTab(WizardryTabs.WIZARDRY));
|
||||||
registerBlock(registry, "meteor", new Block(Material.ROCK).setLightLevel(1));
|
registerBlock(registry, "meteor", new Block(Material.ROCK).setLightLevel(1));
|
||||||
registerBlock(registry, "vanishing_cobweb", new BlockVanishingCobweb(Material.WEB).setLightOpacity(1).setHardness(4.0F));
|
registerBlock(registry, "vanishing_cobweb", new BlockVanishingCobweb(Material.WEB).setLightOpacity(1).setHardness(4.0F));
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import net.minecraft.enchantment.Enchantment;
|
|||||||
import net.minecraftforge.event.RegistryEvent;
|
import net.minecraftforge.event.RegistryEvent;
|
||||||
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.registry.GameRegistry.ObjectHolder;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
@@ -18,6 +19,7 @@ import javax.annotation.Nonnull;
|
|||||||
* @author Electroblob
|
* @author Electroblob
|
||||||
* @since Wizardry 2.1
|
* @since Wizardry 2.1
|
||||||
*/
|
*/
|
||||||
|
@ObjectHolder(Wizardry.MODID)
|
||||||
@Mod.EventBusSubscriber
|
@Mod.EventBusSubscriber
|
||||||
public final class WizardryEnchantments {
|
public final class WizardryEnchantments {
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ package electroblob.wizardry.registry;
|
|||||||
import electroblob.wizardry.Wizardry;
|
import electroblob.wizardry.Wizardry;
|
||||||
import electroblob.wizardry.item.IManaStoringItem;
|
import electroblob.wizardry.item.IManaStoringItem;
|
||||||
import electroblob.wizardry.item.ItemManaFlask;
|
import electroblob.wizardry.item.ItemManaFlask;
|
||||||
import net.minecraft.inventory.ContainerPlayer;
|
import electroblob.wizardry.misc.RecipeRechargeWithFlask;
|
||||||
import net.minecraft.inventory.ContainerWorkbench;
|
|
||||||
import net.minecraft.inventory.IInventory;
|
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.item.crafting.FurnaceRecipes;
|
import net.minecraft.item.crafting.FurnaceRecipes;
|
||||||
@@ -14,9 +12,6 @@ import net.minecraft.util.ResourceLocation;
|
|||||||
import net.minecraftforge.event.RegistryEvent;
|
import net.minecraftforge.event.RegistryEvent;
|
||||||
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.TickEvent;
|
|
||||||
import net.minecraftforge.oredict.OreDictionary;
|
|
||||||
import net.minecraftforge.oredict.ShapelessOreRecipe;
|
|
||||||
import net.minecraftforge.registries.IForgeRegistry;
|
import net.minecraftforge.registries.IForgeRegistry;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@@ -54,84 +49,22 @@ public final class WizardryRecipes {
|
|||||||
|
|
||||||
// Mana flask recipes
|
// Mana flask recipes
|
||||||
|
|
||||||
ItemStack smallFlaskStack = new ItemStack(WizardryItems.small_mana_flask);
|
Item chargeable;
|
||||||
ItemStack mediumFlaskStack = new ItemStack(WizardryItems.medium_mana_flask);
|
|
||||||
ItemStack largeFlaskStack = new ItemStack(WizardryItems.large_mana_flask);
|
|
||||||
|
|
||||||
ItemStack chargeable;
|
|
||||||
|
|
||||||
while(!chargingRecipeQueue.isEmpty()){
|
while(!chargingRecipeQueue.isEmpty()){
|
||||||
// Use remove() and not poll() because the queue shouldn't be empty in here
|
// Use remove() and not poll() because the queue shouldn't be empty in here
|
||||||
chargeable = new ItemStack(chargingRecipeQueue.remove(), 1, OreDictionary.WILDCARD_VALUE);
|
chargeable = chargingRecipeQueue.remove();
|
||||||
|
|
||||||
registry.register(new ShapelessOreRecipe(null, chargeable, chargeable, smallFlaskStack){
|
registry.register(new RecipeRechargeWithFlask(chargeable, (ItemManaFlask)WizardryItems.small_mana_flask)
|
||||||
@Override public boolean isDynamic(){ return true; } // Stops it appearing in the recipe book
|
.setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/small_flask_" + chargeable.getRegistryName().getPath())));
|
||||||
}.setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/small_flask_" + chargeable.getItem().getRegistryName().getPath())));
|
|
||||||
|
|
||||||
registry.register(new ShapelessOreRecipe(null, chargeable, chargeable, mediumFlaskStack){
|
registry.register(new RecipeRechargeWithFlask(chargeable, (ItemManaFlask)WizardryItems.medium_mana_flask)
|
||||||
@Override public boolean isDynamic(){ return true; }
|
.setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/medium_flask_" + chargeable.getRegistryName().getPath())));
|
||||||
}.setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/medium_flask_" + chargeable.getItem().getRegistryName().getPath())));
|
|
||||||
|
|
||||||
registry.register(new ShapelessOreRecipe(null, chargeable, chargeable, largeFlaskStack){
|
registry.register(new RecipeRechargeWithFlask(chargeable, (ItemManaFlask)WizardryItems.large_mana_flask)
|
||||||
@Override public boolean isDynamic(){ return true; }
|
.setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/large_flask_" + chargeable.getRegistryName().getPath())));
|
||||||
}.setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/large_flask_" + chargeable.getItem().getRegistryName().getPath())));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public static void onPlayerTickEvent(TickEvent.PlayerTickEvent event){
|
|
||||||
|
|
||||||
if(event.phase == TickEvent.Phase.START){
|
|
||||||
|
|
||||||
if(event.player.openContainer instanceof ContainerWorkbench){
|
|
||||||
|
|
||||||
IInventory craftMatrix = ((ContainerWorkbench)event.player.openContainer).craftMatrix;
|
|
||||||
ItemStack output = ((ContainerWorkbench)event.player.openContainer).craftResult.getStackInSlot(0);
|
|
||||||
processManaFlaskCrafting(craftMatrix, output);
|
|
||||||
|
|
||||||
}else if(event.player.openContainer instanceof ContainerPlayer){
|
|
||||||
|
|
||||||
IInventory craftMatrix = ((ContainerPlayer)event.player.openContainer).craftMatrix;
|
|
||||||
ItemStack output = ((ContainerPlayer)event.player.openContainer).craftResult.getStackInSlot(0);
|
|
||||||
// Unfortunately I have no choice but to call this method every tick when the player isn't using another
|
|
||||||
// inventory, since the only thing tracking whether the player is looking at their inventory is the GUI
|
|
||||||
// itself, which is client-side only.
|
|
||||||
processManaFlaskCrafting(craftMatrix, output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void processManaFlaskCrafting(IInventory craftMatrix, ItemStack output){
|
|
||||||
|
|
||||||
// Charges wand using mana flask
|
|
||||||
|
|
||||||
ItemManaFlask flask = null;
|
|
||||||
ItemStack input = ItemStack.EMPTY;
|
|
||||||
|
|
||||||
for(int i = 0; i < craftMatrix.getSizeInventory(); i++){
|
|
||||||
|
|
||||||
ItemStack stack = craftMatrix.getStackInSlot(i);
|
|
||||||
|
|
||||||
if(stack.getItem() instanceof ItemManaFlask){
|
|
||||||
flask = (ItemManaFlask)stack.getItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stack.getItem() instanceof IManaStoringItem){
|
|
||||||
input = stack;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(flask == null) return;
|
|
||||||
|
|
||||||
if(output.getItem() instanceof IManaStoringItem && !input.isEmpty()){
|
|
||||||
|
|
||||||
output.setTagCompound((input.getTagCompound()));
|
|
||||||
|
|
||||||
int currentMana = ((IManaStoringItem)input.getItem()).getMana(input);
|
|
||||||
|
|
||||||
((IManaStoringItem)output.getItem()).setMana(output, Math.min(currentMana + flask.size.capacity,
|
|
||||||
((IManaStoringItem)input.getItem()).getManaCapacity(input)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,11 +18,14 @@ public class ArrowRain extends SpellConstructRanged<EntityArrowRain> {
|
|||||||
|
|
||||||
// Moves the entity back towards the caster a bit, so the area of effect is better centred on the position.
|
// Moves the entity back towards the caster a bit, so the area of effect is better centred on the position.
|
||||||
// 3 is the distance to move the entity back towards the caster.
|
// 3 is the distance to move the entity back towards the caster.
|
||||||
double dx = caster.posX - x;
|
double dx = caster == null ? side.getDirectionVec().getX() : caster.posX - x;
|
||||||
double dz = caster.posZ - z;
|
double dz = caster == null ? side.getDirectionVec().getZ() : caster.posZ - z;
|
||||||
double distRatio = 3 / Math.sqrt(dx * dx + dz * dz);
|
double dist = Math.sqrt(dx * dx + dz * dz);
|
||||||
x += dx * distRatio;
|
if(dist != 0){
|
||||||
z += dz * distRatio;
|
double distRatio = 3 / dist;
|
||||||
|
x += dx * distRatio;
|
||||||
|
z += dz * distRatio;
|
||||||
|
}
|
||||||
// Moves the entity up 5 blocks so that it is above mobs' heads.
|
// Moves the entity up 5 blocks so that it is above mobs' heads.
|
||||||
y += 5;
|
y += 5;
|
||||||
|
|
||||||
@@ -32,7 +35,11 @@ public class ArrowRain extends SpellConstructRanged<EntityArrowRain> {
|
|||||||
@Override
|
@Override
|
||||||
protected void addConstructExtras(EntityArrowRain construct, EnumFacing side, EntityLivingBase caster, SpellModifiers modifiers){
|
protected void addConstructExtras(EntityArrowRain construct, EnumFacing side, EntityLivingBase caster, SpellModifiers modifiers){
|
||||||
// Makes the arrows shoot in the direction the caster was looking when they cast the spell.
|
// Makes the arrows shoot in the direction the caster was looking when they cast the spell.
|
||||||
construct.rotationYaw = caster.rotationYawHead;
|
if(caster != null){
|
||||||
|
construct.rotationYaw = caster.rotationYawHead;
|
||||||
|
}else{
|
||||||
|
construct.rotationYaw = side.getHorizontalAngle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class ConjureBlock extends SpellRay {
|
|||||||
@Override
|
@Override
|
||||||
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
||||||
|
|
||||||
if(world.getBlockState(pos).getBlock() == WizardryBlocks.spectral_block){
|
if(caster.isSneaking() && world.getBlockState(pos).getBlock() == WizardryBlocks.spectral_block){
|
||||||
|
|
||||||
if(!world.isRemote){
|
if(!world.isRemote){
|
||||||
// Dispelling of blocks
|
// Dispelling of blocks
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ public class Decay extends SpellConstructRanged<EntityDecay> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean spawnConstruct(World world, double x, double y, double z, EnumFacing side, EntityLivingBase caster, SpellModifiers modifiers){
|
protected boolean spawnConstruct(World world, double x, double y, double z, EnumFacing side, EntityLivingBase caster, SpellModifiers modifiers){
|
||||||
|
|
||||||
if(world.getBlockState(new BlockPos(x, y, z)).isNormalCube()) return false;
|
BlockPos origin = new BlockPos(x, y, z);
|
||||||
|
|
||||||
|
if(world.getBlockState(origin).isNormalCube()) return false;
|
||||||
|
|
||||||
super.spawnConstruct(world, x, y, z, side, caster, modifiers);
|
super.spawnConstruct(world, x, y, z, side, caster, modifiers);
|
||||||
|
|
||||||
@@ -35,7 +37,7 @@ public class Decay extends SpellConstructRanged<EntityDecay> {
|
|||||||
int verticalRange = (int)(6 * modifiers.get(WizardryItems.blast_upgrade));
|
int verticalRange = (int)(6 * modifiers.get(WizardryItems.blast_upgrade));
|
||||||
|
|
||||||
for(int i=0; i<quantity; i++){
|
for(int i=0; i<quantity; i++){
|
||||||
BlockPos pos = WizardryUtilities.findNearbyFloorSpace(caster, horizontalRange, verticalRange);
|
BlockPos pos = WizardryUtilities.findNearbyFloorSpace(world, origin, horizontalRange, verticalRange);
|
||||||
if(pos == null) break;
|
if(pos == null) break;
|
||||||
super.spawnConstruct(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, side, caster, modifiers);
|
super.spawnConstruct(world, pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, side, caster, modifiers);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,9 @@ public class Disintegration extends SpellRay {
|
|||||||
double z = (world.rand.nextDouble() - 0.5) * target.width;
|
double z = (world.rand.nextDouble() - 0.5) * target.width;
|
||||||
ember.setPosition(target.posX + x, target.posY + y, target.posZ + z);
|
ember.setPosition(target.posX + x, target.posY + y, target.posZ + z);
|
||||||
float speed = 0.2f;
|
float speed = 0.2f;
|
||||||
ember.setVelocity(x * speed, y * 0.5f * speed, z * speed);
|
ember.motionX = x * speed;
|
||||||
|
ember.motionY = y * 0.5f * speed;
|
||||||
|
ember.motionZ = z * speed;
|
||||||
world.spawnEntity(ember);
|
world.spawnEntity(ember);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,20 +40,18 @@
|
|||||||
|
|
||||||
if(world.isRemote){
|
if(world.isRemote){
|
||||||
|
|
||||||
world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, caster.posX,
|
world.spawnParticle(EnumParticleTypes.EXPLOSION_LARGE, x, y + 0.1, z, 0, 0, 0);
|
||||||
caster.getEntityBoundingBox().minY + 0.1, caster.posZ, 0, 0, 0);
|
|
||||||
|
|
||||||
double particleX, particleZ;
|
double particleX, particleZ;
|
||||||
|
|
||||||
for(int i=0; i<40; i++){
|
for(int i=0; i<40; i++){
|
||||||
|
|
||||||
particleX = caster.posX - 1.0d + 2 * world.rand.nextDouble();
|
particleX = x - 1.0d + 2 * world.rand.nextDouble();
|
||||||
particleZ = caster.posZ - 1.0d + 2 * world.rand.nextDouble();
|
particleZ = z - 1.0d + 2 * world.rand.nextDouble();
|
||||||
|
|
||||||
IBlockState block = WizardryUtilities.getBlockEntityIsStandingOn(caster);
|
IBlockState block = WizardryUtilities.getBlockEntityIsStandingOn(caster);
|
||||||
world.spawnParticle(EnumParticleTypes.BLOCK_DUST, particleX, caster.getEntityBoundingBox().minY,
|
world.spawnParticle(EnumParticleTypes.BLOCK_DUST, particleX, y,
|
||||||
particleZ, particleX - caster.posX, 0, particleZ - caster.posZ,
|
particleZ, particleX - x, 0, particleZ - z, Block.getStateId(block));
|
||||||
Block.getStateId(block));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import net.minecraft.entity.EntityLivingBase;
|
|||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class Hailstorm extends SpellConstructRanged<EntityHailstorm> {
|
public class Hailstorm extends SpellConstructRanged<EntityHailstorm> {
|
||||||
|
|
||||||
public Hailstorm(){
|
public Hailstorm(){
|
||||||
@@ -14,15 +16,18 @@ public class Hailstorm extends SpellConstructRanged<EntityHailstorm> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean spawnConstruct(World world, double x, double y, double z, EnumFacing side, EntityLivingBase caster, SpellModifiers modifiers){
|
protected boolean spawnConstruct(World world, double x, double y, double z, EnumFacing side, @Nullable EntityLivingBase caster, SpellModifiers modifiers){
|
||||||
|
|
||||||
// Moves the entity back towards the caster a bit, so the area of effect is better centred on the position.
|
// Moves the entity back towards the caster a bit, so the area of effect is better centred on the position.
|
||||||
// 3 is the distance to move the entity back towards the caster.
|
// 3 is the distance to move the entity back towards the caster.
|
||||||
double dx = caster.posX - x;
|
double dx = caster == null ? side.getDirectionVec().getX() : caster.posX - x;
|
||||||
double dz = caster.posZ - z;
|
double dz = caster == null ? side.getDirectionVec().getZ() : caster.posZ - z;
|
||||||
double distRatio = 3 / Math.sqrt(dx * dx + dz * dz);
|
double dist = Math.sqrt(dx * dx + dz * dz);
|
||||||
x += dx * distRatio;
|
if(dist != 0){
|
||||||
z += dz * distRatio;
|
double distRatio = 3 / dist;
|
||||||
|
x += dx * distRatio;
|
||||||
|
z += dz * distRatio;
|
||||||
|
}
|
||||||
// Moves the entity up 5 blocks so that it is above mobs' heads.
|
// Moves the entity up 5 blocks so that it is above mobs' heads.
|
||||||
y += 5;
|
y += 5;
|
||||||
|
|
||||||
@@ -32,7 +37,11 @@ public class Hailstorm extends SpellConstructRanged<EntityHailstorm> {
|
|||||||
@Override
|
@Override
|
||||||
protected void addConstructExtras(EntityHailstorm construct, EnumFacing side, EntityLivingBase caster, SpellModifiers modifiers){
|
protected void addConstructExtras(EntityHailstorm construct, EnumFacing side, EntityLivingBase caster, SpellModifiers modifiers){
|
||||||
// Makes the arrows shoot in the direction the caster was looking when they cast the spell.
|
// Makes the arrows shoot in the direction the caster was looking when they cast the spell.
|
||||||
if(caster != null) construct.rotationYaw = caster.rotationYawHead;
|
if(caster != null){
|
||||||
|
construct.rotationYaw = caster.rotationYawHead;
|
||||||
|
}else{
|
||||||
|
construct.rotationYaw = side.getHorizontalAngle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,8 +23,10 @@ public class IceSpikes extends SpellConstructRanged<EntityIceSpike> {
|
|||||||
@Override
|
@Override
|
||||||
protected boolean spawnConstruct(World world, double x, double y, double z, EnumFacing side, EntityLivingBase caster, SpellModifiers modifiers){
|
protected boolean spawnConstruct(World world, double x, double y, double z, EnumFacing side, EntityLivingBase caster, SpellModifiers modifiers){
|
||||||
|
|
||||||
|
if(side == null) return false;
|
||||||
|
|
||||||
BlockPos blockHit = new BlockPos(x, y, z);
|
BlockPos blockHit = new BlockPos(x, y, z);
|
||||||
if(side != null && side.getAxisDirection() == EnumFacing.AxisDirection.NEGATIVE) blockHit = blockHit.offset(side);
|
if(side.getAxisDirection() == EnumFacing.AxisDirection.NEGATIVE) blockHit = blockHit.offset(side);
|
||||||
|
|
||||||
if(world.getBlockState(blockHit).isNormalCube()) return false;
|
if(world.getBlockState(blockHit).isNormalCube()) return false;
|
||||||
|
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ public class Possession extends SpellRay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(possessor.world.isRemote){
|
if(possessor.world.isRemote && possessor == net.minecraft.client.Minecraft.getMinecraft().player){
|
||||||
// Shaders and effects
|
// Shaders and effects
|
||||||
if(Wizardry.settings.useShaders) net.minecraft.client.Minecraft.getMinecraft().entityRenderer.loadShader(SHADER);
|
if(Wizardry.settings.useShaders) net.minecraft.client.Minecraft.getMinecraft().entityRenderer.loadShader(SHADER);
|
||||||
electroblob.wizardry.client.WizardryClientEventHandler.playBlinkEffect(); // Looks quite nice...
|
electroblob.wizardry.client.WizardryClientEventHandler.playBlinkEffect(); // Looks quite nice...
|
||||||
@@ -342,7 +342,7 @@ public class Possession extends SpellRay {
|
|||||||
player.capabilities.isFlying = false;
|
player.capabilities.isFlying = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(player.world.isRemote){
|
if(player.world.isRemote && player == net.minecraft.client.Minecraft.getMinecraft().player){
|
||||||
net.minecraft.client.Minecraft.getMinecraft().entityRenderer.stopUseShader();
|
net.minecraft.client.Minecraft.getMinecraft().entityRenderer.stopUseShader();
|
||||||
electroblob.wizardry.client.WizardryClientEventHandler.playBlinkEffect(); // Looks quite nice...
|
electroblob.wizardry.client.WizardryClientEventHandler.playBlinkEffect(); // Looks quite nice...
|
||||||
}
|
}
|
||||||
@@ -624,7 +624,7 @@ public class Possession extends SpellRay {
|
|||||||
EntityLiving possessee = getPossessee((EntityPlayer)event.getTarget());
|
EntityLiving possessee = getPossessee((EntityPlayer)event.getTarget());
|
||||||
EntityLiving attacker = (EntityLiving)event.getEntityLiving();
|
EntityLiving attacker = (EntityLiving)event.getEntityLiving();
|
||||||
if(possessee != null && !attacker.canAttackClass(possessee.getClass())){
|
if(possessee != null && !attacker.canAttackClass(possessee.getClass())){
|
||||||
event.setCanceled(true); // Mobs can't target a player possessing an entity they don't normally attack
|
((EntityLiving)event.getEntityLiving()).setAttackTarget(null); // Mobs can't target a player possessing an entity they don't normally attack
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
|||||||
// Conversely, general spell classes ONLY EVER define the properties they ACTUALLY USE.
|
// Conversely, general spell classes ONLY EVER define the properties they ACTUALLY USE.
|
||||||
public final Spell addProperties(String... keys){
|
public final Spell addProperties(String... keys){
|
||||||
|
|
||||||
if(properties != null) throw new IllegalStateException("Tried to add spell properties after they were initialised");
|
if(arePropertiesInitialised()) throw new IllegalStateException("Tried to add spell properties after they were initialised");
|
||||||
|
|
||||||
for(String key : keys) if(propertyKeys.contains(key)) Wizardry.logger.warn("Tried to add a duplicate property key '"
|
for(String key : keys) if(propertyKeys.contains(key)) Wizardry.logger.warn("Tried to add a duplicate property key '"
|
||||||
+ key + "' to spell " + this.getRegistryName());
|
+ key + "' to spell " + this.getRegistryName());
|
||||||
@@ -236,11 +236,17 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
|||||||
return propertyKeys.toArray(new String[0]);
|
return propertyKeys.toArray(new String[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns true if this spell's properties have been initialised, false if not. Check this if you're attempting
|
||||||
|
* to access them from code that could be called before wizardry's {@code init()} method (e.g. item attributes). */
|
||||||
|
public final boolean arePropertiesInitialised(){
|
||||||
|
return properties != null;
|
||||||
|
}
|
||||||
|
|
||||||
/** Sets this spell's properties to the given {@link SpellProperties} object, but only if it doesn't already
|
/** Sets this spell's properties to the given {@link SpellProperties} object, but only if it doesn't already
|
||||||
* have one. This prevents spell properties from being changed after initialisation. */
|
* have one. This prevents spell properties from being changed after initialisation. */
|
||||||
public void setProperties(@Nonnull SpellProperties properties){
|
public void setProperties(@Nonnull SpellProperties properties){
|
||||||
|
|
||||||
if(this.properties == null){
|
if(!arePropertiesInitialised()){
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
}else{
|
}else{
|
||||||
Wizardry.logger.info("A mod attempted to set a spell's properties, but they were already initialised.");
|
Wizardry.logger.info("A mod attempted to set a spell's properties, but they were already initialised.");
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ public class SpellConstruct<T extends EntityMagicConstruct> extends Spell {
|
|||||||
* @param modifiers The modifiers with which the spell was cast.
|
* @param modifiers The modifiers with which the spell was cast.
|
||||||
* @return false to cause the spell to fail, true to continue with casting.
|
* @return false to cause the spell to fail, true to continue with casting.
|
||||||
*/
|
*/
|
||||||
protected boolean spawnConstruct(World world, double x, double y, double z, @Nullable EnumFacing side, EntityLivingBase caster, SpellModifiers modifiers){
|
protected boolean spawnConstruct(World world, double x, double y, double z, @Nullable EnumFacing side, @Nullable EntityLivingBase caster, SpellModifiers modifiers){
|
||||||
|
|
||||||
if(!world.isRemote){
|
if(!world.isRemote){
|
||||||
// Creates a new construct using the supplied factory
|
// Creates a new construct using the supplied factory
|
||||||
|
|||||||
@@ -5,6 +5,10 @@ import electroblob.wizardry.util.SpellModifiers;
|
|||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.item.EnumAction;
|
import net.minecraft.item.EnumAction;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class Tornado extends SpellConstruct<EntityTornado> {
|
public class Tornado extends SpellConstruct<EntityTornado> {
|
||||||
|
|
||||||
@@ -19,7 +23,8 @@ public class Tornado extends SpellConstruct<EntityTornado> {
|
|||||||
@Override
|
@Override
|
||||||
protected void addConstructExtras(EntityTornado construct, EnumFacing side, EntityLivingBase caster, SpellModifiers modifiers){
|
protected void addConstructExtras(EntityTornado construct, EnumFacing side, EntityLivingBase caster, SpellModifiers modifiers){
|
||||||
float speed = getProperty(SPEED).floatValue();
|
float speed = getProperty(SPEED).floatValue();
|
||||||
construct.setHorizontalVelocity(caster.getLookVec().x * speed, caster.getLookVec().z * speed);
|
Vec3d direction = caster == null ? new Vec3d(side.getDirectionVec()) : caster.getLookVec();
|
||||||
|
construct.setHorizontalVelocity(direction.x * speed, direction.z * speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,12 +142,17 @@ public class TileEntityShrineCore extends TileEntity implements ITickable {
|
|||||||
double z = this.pos.getZ() + 0.5;
|
double z = this.pos.getZ() + 0.5;
|
||||||
|
|
||||||
if(!world.isRemote){
|
if(!world.isRemote){
|
||||||
|
|
||||||
WizardryPacketHandler.net.sendToAllAround(new PacketConquerShrine.Message(this.pos),
|
WizardryPacketHandler.net.sendToAllAround(new PacketConquerShrine.Message(this.pos),
|
||||||
new NetworkRegistry.TargetPoint(this.world.provider.getDimension(), x, y, z, 64));
|
new NetworkRegistry.TargetPoint(this.world.provider.getDimension(), x, y, z, 64));
|
||||||
}
|
|
||||||
|
|
||||||
world.setBlockState(pos, WizardryBlocks.runestone_pedestal.getDefaultState()
|
if(world.getBlockState(pos).getBlock() == WizardryBlocks.runestone_pedestal){
|
||||||
.withProperty(BlockPedestal.ELEMENT, world.getBlockState(pos).getValue(BlockPedestal.ELEMENT)));
|
world.setBlockState(pos, WizardryBlocks.runestone_pedestal.getDefaultState()
|
||||||
|
.withProperty(BlockPedestal.ELEMENT, world.getBlockState(pos).getValue(BlockPedestal.ELEMENT)));
|
||||||
|
}else{
|
||||||
|
Wizardry.logger.warn("What's going on?! A shrine core is being conquered but the block at its position is not a runestone pedestal!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
world.markTileEntityForRemoval(this);
|
world.markTileEntityForRemoval(this);
|
||||||
|
|
||||||
|
|||||||
@@ -111,12 +111,12 @@ public final class AllyDesignationSystem {
|
|||||||
*/
|
*/
|
||||||
public static boolean isValidTarget(Entity attacker, Entity target){
|
public static boolean isValidTarget(Entity attacker, Entity target){
|
||||||
|
|
||||||
// Always return true if the attacker is null
|
|
||||||
if(attacker == null) return true;
|
|
||||||
|
|
||||||
// Always return false if the target is null
|
// Always return false if the target is null
|
||||||
if(target == null) return false;
|
if(target == null) return false;
|
||||||
|
|
||||||
|
// Always return true if the attacker is null - this must be after the target null check!
|
||||||
|
if(attacker == null) return true;
|
||||||
|
|
||||||
// Tests whether the target is the attacker
|
// Tests whether the target is the attacker
|
||||||
if(target == attacker) return false;
|
if(target == attacker) return false;
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public final class CustomSoundCategory {
|
|||||||
/**
|
/**
|
||||||
* Adds a new custom sound category, performing the necessary changes to GameSettings and
|
* Adds a new custom sound category, performing the necessary changes to GameSettings and
|
||||||
*
|
*
|
||||||
* @param name A unique name for the sound category
|
* @param name A unique name for the sound category. <b>Must not contain any colons!</b>
|
||||||
* @return The resulting SoundCategory object
|
* @return The resulting SoundCategory object
|
||||||
* @throws IllegalArgumentException if name is not unique
|
* @throws IllegalArgumentException if name is not unique
|
||||||
*/
|
*/
|
||||||
@@ -59,8 +59,8 @@ public final class CustomSoundCategory {
|
|||||||
constantName = name.toUpperCase().replace(" ", "");
|
constantName = name.toUpperCase().replace(" ", "");
|
||||||
referenceName = constantName.toLowerCase();
|
referenceName = constantName.toLowerCase();
|
||||||
// >> Electroblob: Removed array surrounding varargs argument
|
// >> Electroblob: Removed array surrounding varargs argument
|
||||||
soundCategory = EnumHelper.addEnum(SoundCategory.class , constantName, new Class[]{String.class}, referenceName);
|
soundCategory = EnumHelper.addEnum(SoundCategory.class , constantName, new Class<?>[]{String.class}, referenceName);
|
||||||
SOUND_CATEGORIES = ObfuscationReflectionHelper.getPrivateValue(SoundCategory.class, SoundCategory.VOICE ,"SOUND_CATEGORIES", SRG_SOUND_CATEGORIES);
|
SOUND_CATEGORIES = ObfuscationReflectionHelper.getPrivateValue(SoundCategory.class, SoundCategory.VOICE, SRG_SOUND_CATEGORIES);
|
||||||
if (SOUND_CATEGORIES.containsKey(referenceName))
|
if (SOUND_CATEGORIES.containsKey(referenceName))
|
||||||
// >> Electroblob: changed from Error to IllegalArgumentException
|
// >> Electroblob: changed from Error to IllegalArgumentException
|
||||||
throw new IllegalArgumentException("Clash in Sound Category name pools! Cannot insert " + constantName);
|
throw new IllegalArgumentException("Clash in Sound Category name pools! Cannot insert " + constantName);
|
||||||
@@ -79,8 +79,7 @@ public final class CustomSoundCategory {
|
|||||||
// Replace the map in the GameSettings.class
|
// Replace the map in the GameSettings.class
|
||||||
// >> Electroblob: Fully qualified names, because this class gets loaded on both sides
|
// >> Electroblob: Fully qualified names, because this class gets loaded on both sides
|
||||||
ObfuscationReflectionHelper.setPrivateValue(net.minecraft.client.settings.GameSettings.class,
|
ObfuscationReflectionHelper.setPrivateValue(net.minecraft.client.settings.GameSettings.class,
|
||||||
net.minecraft.client.Minecraft.getMinecraft().gameSettings, soundLevels,
|
net.minecraft.client.Minecraft.getMinecraft().gameSettings, soundLevels, SRG_soundLevels);
|
||||||
"soundLevels", SRG_soundLevels);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ public final class WandHelper {
|
|||||||
public static final String UPGRADES_KEY = "upgrades";
|
public static final String UPGRADES_KEY = "upgrades";
|
||||||
public static final String PROGRESSION_KEY = "progression";
|
public static final String PROGRESSION_KEY = "progression";
|
||||||
|
|
||||||
private static final HashMap<Item, String> upgradeMap = new HashMap<Item, String>();
|
private static final HashMap<Item, String> upgradeMap = new HashMap<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
upgradeMap.put(WizardryItems.condenser_upgrade, "condenser");
|
upgradeMap.put(WizardryItems.condenser_upgrade, "condenser");
|
||||||
@@ -251,11 +251,15 @@ public final class WandHelper {
|
|||||||
/** Returns the given wand's cooldown for the currently selected spell, or 0 if the wand has no cooldown data. */
|
/** Returns the given wand's cooldown for the currently selected spell, or 0 if the wand has no cooldown data. */
|
||||||
public static int getCurrentCooldown(ItemStack wand){
|
public static int getCurrentCooldown(ItemStack wand){
|
||||||
|
|
||||||
|
if(wand.getTagCompound() == null) wand.setTagCompound(new NBTTagCompound());
|
||||||
|
|
||||||
int[] cooldowns = getCooldowns(wand);
|
int[] cooldowns = getCooldowns(wand);
|
||||||
|
|
||||||
if(cooldowns.length == 0) return 0;
|
int selectedSpell = wand.getTagCompound().getInteger(SELECTED_SPELL_KEY);
|
||||||
|
|
||||||
|
if(selectedSpell < 0 || cooldowns.length <= selectedSpell) return 0;
|
||||||
// Don't need to check if the tag compound is null since the above check is equivalent.
|
// Don't need to check if the tag compound is null since the above check is equivalent.
|
||||||
return cooldowns[wand.getTagCompound().getInteger(SELECTED_SPELL_KEY)];
|
return cooldowns[selectedSpell];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the given wand's cooldown for the spell after the currently selected spell, or 0 if the wand has no
|
/** Returns the given wand's cooldown for the spell after the currently selected spell, or 0 if the wand has no
|
||||||
@@ -264,9 +268,11 @@ public final class WandHelper {
|
|||||||
|
|
||||||
int[] cooldowns = getCooldowns(wand);
|
int[] cooldowns = getCooldowns(wand);
|
||||||
|
|
||||||
if(cooldowns.length == 0) return 0;
|
int nextSpell = getNextSpellIndex(wand);
|
||||||
|
|
||||||
|
if(nextSpell < 0 || cooldowns.length <= nextSpell) return 0;
|
||||||
// Don't need to check if the tag compound is null since the above check is equivalent.
|
// Don't need to check if the tag compound is null since the above check is equivalent.
|
||||||
return cooldowns[getNextSpellIndex(wand)];
|
return cooldowns[nextSpell];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the given wand's cooldown for the spell before the currently selected spell, or 0 if the wand has no
|
/** Returns the given wand's cooldown for the spell before the currently selected spell, or 0 if the wand has no
|
||||||
@@ -275,9 +281,11 @@ public final class WandHelper {
|
|||||||
|
|
||||||
int[] cooldowns = getCooldowns(wand);
|
int[] cooldowns = getCooldowns(wand);
|
||||||
|
|
||||||
if(cooldowns.length == 0) return 0;
|
int previousSpell = getPreviousSpellIndex(wand);
|
||||||
|
|
||||||
|
if(previousSpell < 0 || cooldowns.length <= previousSpell) return 0;
|
||||||
// Don't need to check if the tag compound is null since the above check is equivalent.
|
// Don't need to check if the tag compound is null since the above check is equivalent.
|
||||||
return cooldowns[getPreviousSpellIndex(wand)];
|
return cooldowns[previousSpell];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the given wand's cooldown for the currently selected spell. Will also set the maximum cooldown. */
|
/** Sets the given wand's cooldown for the currently selected spell. Will also set the maximum cooldown. */
|
||||||
@@ -287,19 +295,24 @@ public final class WandHelper {
|
|||||||
|
|
||||||
int[] cooldowns = getCooldowns(wand);
|
int[] cooldowns = getCooldowns(wand);
|
||||||
|
|
||||||
|
int selectedSpell = wand.getTagCompound().getInteger(SELECTED_SPELL_KEY);
|
||||||
|
int spellCount = getSpells(wand).length;
|
||||||
|
|
||||||
|
if(spellCount <= selectedSpell) return; // Probably shouldn't happen
|
||||||
|
|
||||||
// The length of the spells array must be greater than 0 since this method can only be called if a spell is
|
// The length of the spells array must be greater than 0 since this method can only be called if a spell is
|
||||||
// cast, which is impossible if there are no spells.
|
// cast, which is impossible if there are no spells.
|
||||||
if(cooldowns.length == 0) cooldowns = new int[getSpells(wand).length];
|
if(cooldowns.length <= selectedSpell) cooldowns = new int[spellCount];
|
||||||
|
|
||||||
cooldowns[wand.getTagCompound().getInteger(SELECTED_SPELL_KEY)] = cooldown;
|
cooldowns[selectedSpell] = cooldown;
|
||||||
|
|
||||||
setCooldowns(wand, cooldowns);
|
setCooldowns(wand, cooldowns);
|
||||||
|
|
||||||
int[] maxCooldowns = getMaxCooldowns(wand);
|
int[] maxCooldowns = getMaxCooldowns(wand);
|
||||||
|
|
||||||
if(maxCooldowns.length == 0) maxCooldowns = new int[getSpells(wand).length];
|
if(maxCooldowns.length <= selectedSpell) maxCooldowns = new int[spellCount];
|
||||||
|
|
||||||
maxCooldowns[wand.getTagCompound().getInteger(SELECTED_SPELL_KEY)] = cooldown;
|
maxCooldowns[selectedSpell] = cooldown;
|
||||||
|
|
||||||
setMaxCooldowns(wand, maxCooldowns);
|
setMaxCooldowns(wand, maxCooldowns);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -870,9 +870,10 @@ public final class WizardryUtilities {
|
|||||||
|
|
||||||
ItemStack stack = caster.getHeldItem(caster.getActiveHand());
|
ItemStack stack = caster.getHeldItem(caster.getActiveHand());
|
||||||
|
|
||||||
if(stack.getItem() instanceof ISpellCastingItem && ((ISpellCastingItem)stack.getItem()).getCurrentSpell(stack) == spell
|
if(stack.getItem() instanceof ISpellCastingItem && ((ISpellCastingItem)stack.getItem()).getCurrentSpell(stack) == spell){
|
||||||
&& ((ISpellCastingItem)stack.getItem()).canCast(stack, spell, (EntityPlayer)caster,
|
// Don't do this, it interferes with stuff! We effectively already tested this with caster.isHandActive() anyway
|
||||||
EnumHand.MAIN_HAND, 0, new SpellModifiers())){
|
// && ((ISpellCastingItem)stack.getItem()).canCast(stack, spell, (EntityPlayer)caster,
|
||||||
|
// EnumHand.MAIN_HAND, 0, new SpellModifiers())){
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ item.ebwizardry\:amulet_auto_shield.desc=Grants a 25%% chance to trigger the shi
|
|||||||
item.ebwizardry\:charm_haggler.name=Haggler's Sign
|
item.ebwizardry\:charm_haggler.name=Haggler's Sign
|
||||||
item.ebwizardry\:charm_haggler.desc=Wizards are guaranteed to offer a new trade every time you trade with them
|
item.ebwizardry\:charm_haggler.desc=Wizards are guaranteed to offer a new trade every time you trade with them
|
||||||
item.ebwizardry\:charm_experience_tome.name=Tome of the Diligent
|
item.ebwizardry\:charm_experience_tome.name=Tome of the Diligent
|
||||||
item.ebwizardry\:charm_experience_tome.desc=Increases the rate at which wands gain progression by 40%%
|
item.ebwizardry\:charm_experience_tome.desc=Increases the rate at which wands gain progression by 50%%
|
||||||
item.ebwizardry\:charm_auto_smelt.name=Metallurgist's Mark
|
item.ebwizardry\:charm_auto_smelt.name=Metallurgist's Mark
|
||||||
item.ebwizardry\:charm_auto_smelt.desc=Pocket furnace triggers automatically when bound to a wand on your hotbar
|
item.ebwizardry\:charm_auto_smelt.desc=Pocket furnace triggers automatically when bound to a wand on your hotbar
|
||||||
item.ebwizardry\:charm_lava_walking.name=Nether Ice Core
|
item.ebwizardry\:charm_lava_walking.name=Nether Ice Core
|
||||||
@@ -719,14 +719,14 @@ spell.ebwizardry\:arc.desc=Fires a spark of lightning at the target.
|
|||||||
spell.ebwizardry\:arcane_jammer.desc=Prevents the target from using magic for 15 seconds.
|
spell.ebwizardry\:arcane_jammer.desc=Prevents the target from using magic for 15 seconds.
|
||||||
spell.ebwizardry\:arcane_lock.desc=Creates an impenetrable barrier of force around a container, protecting it from being opened or destroyed. The caster and their allies may still open it, however.
|
spell.ebwizardry\:arcane_lock.desc=Creates an impenetrable barrier of force around a container, protecting it from being opened or destroyed. The caster and their allies may still open it, however.
|
||||||
spell.ebwizardry\:arrow_rain.desc="Archers, fire!"
|
spell.ebwizardry\:arrow_rain.desc="Archers, fire!"
|
||||||
spell.ebwizardry\:banish.desc=Teleports the target against its will to a random locations within a certain range.
|
spell.ebwizardry\:banish.desc=Teleports the target against its will to a random location within a certain range.
|
||||||
spell.ebwizardry\:black_hole.desc=Tear reality asunder.
|
spell.ebwizardry\:black_hole.desc=Tear reality asunder.
|
||||||
spell.ebwizardry\:blink.desc=Teleports the caster over a short distance to where they are pointing.
|
spell.ebwizardry\:blink.desc=Teleports the caster over a short distance to where they are pointing.
|
||||||
spell.ebwizardry\:blizzard.desc=Creates a zone of swirling icy wind which slows and continually damages anything trapped inside. The caster is immune to the damage but is still slowed.
|
spell.ebwizardry\:blizzard.desc=Creates a zone of swirling icy wind which slows and continually damages anything trapped inside. The caster is immune to the damage but is still slowed.
|
||||||
spell.ebwizardry\:bubble.desc=Fires a jet of bubbles which causes anything it hits to float upwards helplessly. The target will fall after a certain time or if it is damaged.
|
spell.ebwizardry\:bubble.desc=Fires a jet of bubbles which causes anything it hits to float upwards helplessly. The target will fall after a certain time or if it is damaged.
|
||||||
spell.ebwizardry\:chain_lightning.desc=Fires a spark of lightning at the target, which then chains to additional targets up to twice.
|
spell.ebwizardry\:chain_lightning.desc=Fires a spark of lightning at the target, which then chains to additional targets up to twice.
|
||||||
spell.ebwizardry\:charge.desc=Causes the caster to charge rapidly in the direction they are looking, damaging and knocking back anything in their path.
|
spell.ebwizardry\:charge.desc=Causes the caster to charge rapidly in the direction they are looking, damaging and knocking back anything in their path.
|
||||||
spell.ebwizardry\:clairvoyance.desc=Reveals the path to a remembered locations. With this spell selected, sneak-right-click on a block to set the locations. Cast this spell normally to reveal the path. The path will fade after 90 seconds.
|
spell.ebwizardry\:clairvoyance.desc=Reveals the path to a remembered location. With this spell selected, sneak-right-click on a block to set the location. Cast this spell normally to reveal the path. The path will fade after 90 seconds.
|
||||||
spell.ebwizardry\:cobwebs.desc=Creates cobwebs where you are pointing, which greatly hamper the movement of any creatures caught amongst them. The cobwebs will vanish after 20 seconds or if broken.
|
spell.ebwizardry\:cobwebs.desc=Creates cobwebs where you are pointing, which greatly hamper the movement of any creatures caught amongst them. The cobwebs will vanish after 20 seconds or if broken.
|
||||||
spell.ebwizardry\:combustion_rune.desc=Places a magical landmine on the ground where you are pointing, which explodes when stepped upon.
|
spell.ebwizardry\:combustion_rune.desc=Places a magical landmine on the ground where you are pointing, which explodes when stepped upon.
|
||||||
spell.ebwizardry\:conjure_armour.desc=Creates spectral armour around the caster which offers protection equal to that of iron armour. The armour lasts for 60 seconds. The caster must have an empty armour slot.
|
spell.ebwizardry\:conjure_armour.desc=Creates spectral armour around the caster which offers protection equal to that of iron armour. The armour lasts for 60 seconds. The caster must have an empty armour slot.
|
||||||
@@ -895,9 +895,9 @@ spell.ebwizardry\:transportation.undefined=You must remember the location of a s
|
|||||||
spell.ebwizardry\:transportation.wrongdimension=No remembered stone circle in this dimension...
|
spell.ebwizardry\:transportation.wrongdimension=No remembered stone circle in this dimension...
|
||||||
spell.ebwizardry\:clairvoyance.searching=Searching...
|
spell.ebwizardry\:clairvoyance.searching=Searching...
|
||||||
spell.ebwizardry\:clairvoyance.confirm=The path revealed upon casting %1$s will now lead back to this point
|
spell.ebwizardry\:clairvoyance.confirm=The path revealed upon casting %1$s will now lead back to this point
|
||||||
spell.ebwizardry\:clairvoyance.outofrange=Your remembered locations is too far away or inaccessible...
|
spell.ebwizardry\:clairvoyance.outofrange=Your remembered location is too far away or inaccessible...
|
||||||
spell.ebwizardry\:clairvoyance.undefined=You must remember a locations first!
|
spell.ebwizardry\:clairvoyance.undefined=You must remember a location first!
|
||||||
spell.ebwizardry\:clairvoyance.wrongdimension=Your remembered locations is in another dimension...
|
spell.ebwizardry\:clairvoyance.wrongdimension=Your remembered location is in another dimension...
|
||||||
spell.ebwizardry\:possession.insufficienthealth=You don't have enough health to possess %1$s!
|
spell.ebwizardry\:possession.insufficienthealth=You don't have enough health to possess %1$s!
|
||||||
spell.ebwizardry\:possession.success=Press %s to stop possessing
|
spell.ebwizardry\:possession.success=Press %s to stop possessing
|
||||||
spell.ebwizardry\:divination.nothing=Nothing happened.
|
spell.ebwizardry\:divination.nothing=Nothing happened.
|
||||||
@@ -1003,6 +1003,16 @@ enchantment.ebwizardry\:magic_protection=Magic Protection
|
|||||||
enchantment.ebwizardry\:frost_protection=Frost Protection
|
enchantment.ebwizardry\:frost_protection=Frost Protection
|
||||||
enchantment.ebwizardry\:shock_protection=Shock Protection
|
enchantment.ebwizardry\:shock_protection=Shock Protection
|
||||||
|
|
||||||
|
enchantment.ebwizardry.magic_sword.desc=Part of the Imbue Weapon spell; unobtainable in survival mode (the book won't work).
|
||||||
|
enchantment.ebwizardry.magic_bow.desc=Part of the Imbue Weapon spell; unobtainable in survival mode (the book won't work).
|
||||||
|
enchantment.ebwizardry.flaming_weapon.desc=Part of the Flaming Weapon spell; unobtainable in survival mode (the book won't work).
|
||||||
|
enchantment.ebwizardry.freezing_weapon.desc=Part of the Freezing Weapon spell; unobtainable in survival mode (the book won't work).
|
||||||
|
enchantment.ebwizardry.shocking_weapon.desc=Part of the Shocking Weapon spell; unobtainable in survival mode (the book won't work).
|
||||||
|
|
||||||
|
enchantment.ebwizardry.magic_protection.desc=Reduces damage from all magic.
|
||||||
|
enchantment.ebwizardry.frost_protection.desc=Reduces the effects of frost damage.
|
||||||
|
enchantment.ebwizardry.shock_protection.desc=Reduces the effects of shock damage.
|
||||||
|
|
||||||
key.categories.ebwizardry=Wizardry
|
key.categories.ebwizardry=Wizardry
|
||||||
|
|
||||||
key.ebwizardry.next_spell=Next Spell
|
key.ebwizardry.next_spell=Next Spell
|
||||||
@@ -1011,7 +1021,7 @@ key.ebwizardry.previous_spell=Previous Spell
|
|||||||
death.attack.wizardry_magic=%1$s was killed by %2$s using magic
|
death.attack.wizardry_magic=%1$s was killed by %2$s using magic
|
||||||
death.attack.indirect_wizardry_magic=%1$s was killed by %2$s using magic
|
death.attack.indirect_wizardry_magic=%1$s was killed by %2$s using magic
|
||||||
|
|
||||||
soundCategory.ebwizardry\:spells=Spells
|
soundCategory.ebwizardry_spells=Spells
|
||||||
|
|
||||||
commands.ebwizardry\:cast.usage=/%1$s <spell> [player | x y z direction] [duration] [modifiers]
|
commands.ebwizardry\:cast.usage=/%1$s <spell> [player | x y z direction] [duration] [modifiers]
|
||||||
commands.ebwizardry\:cast.success=Successfully cast %s
|
commands.ebwizardry\:cast.success=Successfully cast %s
|
||||||
|
|||||||
@@ -313,7 +313,7 @@ item.ebwizardry\:amulet_auto_shield.desc=Grants a 25%% chance to trigger the shi
|
|||||||
item.ebwizardry\:charm_haggler.name=Haggler's Sign
|
item.ebwizardry\:charm_haggler.name=Haggler's Sign
|
||||||
item.ebwizardry\:charm_haggler.desc=Wizards are guaranteed to offer a new trade every time you trade with them
|
item.ebwizardry\:charm_haggler.desc=Wizards are guaranteed to offer a new trade every time you trade with them
|
||||||
item.ebwizardry\:charm_experience_tome.name=Tome of the Diligent
|
item.ebwizardry\:charm_experience_tome.name=Tome of the Diligent
|
||||||
item.ebwizardry\:charm_experience_tome.desc=Increases the rate at which wands gain progression by 40%%
|
item.ebwizardry\:charm_experience_tome.desc=Increases the rate at which wands gain progression by 50%%
|
||||||
item.ebwizardry\:charm_auto_smelt.name=Metallurgist's Mark
|
item.ebwizardry\:charm_auto_smelt.name=Metallurgist's Mark
|
||||||
item.ebwizardry\:charm_auto_smelt.desc=Pocket furnace triggers automatically when bound to a wand on your hotbar
|
item.ebwizardry\:charm_auto_smelt.desc=Pocket furnace triggers automatically when bound to a wand on your hotbar
|
||||||
item.ebwizardry\:charm_lava_walking.name=Nether Ice Core
|
item.ebwizardry\:charm_lava_walking.name=Nether Ice Core
|
||||||
@@ -719,14 +719,14 @@ spell.ebwizardry\:arc.desc=Fires a spark of lightning at the target.
|
|||||||
spell.ebwizardry\:arcane_jammer.desc=Prevents the target from using magic for 15 seconds.
|
spell.ebwizardry\:arcane_jammer.desc=Prevents the target from using magic for 15 seconds.
|
||||||
spell.ebwizardry\:arcane_lock.desc=Creates an impenetrable barrier of force around a container, protecting it from being opened or destroyed. The caster and their allies may still open it, however.
|
spell.ebwizardry\:arcane_lock.desc=Creates an impenetrable barrier of force around a container, protecting it from being opened or destroyed. The caster and their allies may still open it, however.
|
||||||
spell.ebwizardry\:arrow_rain.desc="Archers, fire!"
|
spell.ebwizardry\:arrow_rain.desc="Archers, fire!"
|
||||||
spell.ebwizardry\:banish.desc=Teleports the target against its will to a random locations within a certain range.
|
spell.ebwizardry\:banish.desc=Teleports the target against its will to a random location within a certain range.
|
||||||
spell.ebwizardry\:black_hole.desc=Tear reality asunder.
|
spell.ebwizardry\:black_hole.desc=Tear reality asunder.
|
||||||
spell.ebwizardry\:blink.desc=Teleports the caster over a short distance to where they are pointing.
|
spell.ebwizardry\:blink.desc=Teleports the caster over a short distance to where they are pointing.
|
||||||
spell.ebwizardry\:blizzard.desc=Creates a zone of swirling icy wind which slows and continually damages anything trapped inside. The caster is immune to the damage but is still slowed.
|
spell.ebwizardry\:blizzard.desc=Creates a zone of swirling icy wind which slows and continually damages anything trapped inside. The caster is immune to the damage but is still slowed.
|
||||||
spell.ebwizardry\:bubble.desc=Fires a jet of bubbles which causes anything it hits to float upwards helplessly. The target will fall after a certain time or if it is damaged.
|
spell.ebwizardry\:bubble.desc=Fires a jet of bubbles which causes anything it hits to float upwards helplessly. The target will fall after a certain time or if it is damaged.
|
||||||
spell.ebwizardry\:chain_lightning.desc=Fires a spark of lightning at the target, which then chains to additional targets up to twice.
|
spell.ebwizardry\:chain_lightning.desc=Fires a spark of lightning at the target, which then chains to additional targets up to twice.
|
||||||
spell.ebwizardry\:charge.desc=Causes the caster to charge rapidly in the direction they are looking, damaging and knocking back anything in their path.
|
spell.ebwizardry\:charge.desc=Causes the caster to charge rapidly in the direction they are looking, damaging and knocking back anything in their path.
|
||||||
spell.ebwizardry\:clairvoyance.desc=Reveals the path to a remembered locations. With this spell selected, sneak-right-click on a block to set the locations. Cast this spell normally to reveal the path. The path will fade after 90 seconds.
|
spell.ebwizardry\:clairvoyance.desc=Reveals the path to a remembered location. With this spell selected, sneak-right-click on a block to set the location. Cast this spell normally to reveal the path. The path will fade after 90 seconds.
|
||||||
spell.ebwizardry\:cobwebs.desc=Creates cobwebs where you are pointing, which greatly hamper the movement of any creatures caught amongst them. The cobwebs will vanish after 20 seconds or if broken.
|
spell.ebwizardry\:cobwebs.desc=Creates cobwebs where you are pointing, which greatly hamper the movement of any creatures caught amongst them. The cobwebs will vanish after 20 seconds or if broken.
|
||||||
spell.ebwizardry\:combustion_rune.desc=Places a magical landmine on the ground where you are pointing, which explodes when stepped upon.
|
spell.ebwizardry\:combustion_rune.desc=Places a magical landmine on the ground where you are pointing, which explodes when stepped upon.
|
||||||
spell.ebwizardry\:conjure_armour.desc=Creates spectral armor around the caster which offers protection equal to that of iron armor. The armor lasts for 60 seconds. The caster must have an empty armor slot.
|
spell.ebwizardry\:conjure_armour.desc=Creates spectral armor around the caster which offers protection equal to that of iron armor. The armor lasts for 60 seconds. The caster must have an empty armor slot.
|
||||||
@@ -895,9 +895,9 @@ spell.ebwizardry\:transportation.undefined=You must remember the location of a s
|
|||||||
spell.ebwizardry\:transportation.wrongdimension=No remembered stone circle in this dimension...
|
spell.ebwizardry\:transportation.wrongdimension=No remembered stone circle in this dimension...
|
||||||
spell.ebwizardry\:clairvoyance.searching=Searching...
|
spell.ebwizardry\:clairvoyance.searching=Searching...
|
||||||
spell.ebwizardry\:clairvoyance.confirm=The path revealed upon casting %1$s will now lead back to this point
|
spell.ebwizardry\:clairvoyance.confirm=The path revealed upon casting %1$s will now lead back to this point
|
||||||
spell.ebwizardry\:clairvoyance.outofrange=Your remembered locations is too far away or inaccessible...
|
spell.ebwizardry\:clairvoyance.outofrange=Your remembered location is too far away or inaccessible...
|
||||||
spell.ebwizardry\:clairvoyance.undefined=You must remember a locations first!
|
spell.ebwizardry\:clairvoyance.undefined=You must remember a location first!
|
||||||
spell.ebwizardry\:clairvoyance.wrongdimension=Your remembered locations is in another dimension...
|
spell.ebwizardry\:clairvoyance.wrongdimension=Your remembered location is in another dimension...
|
||||||
spell.ebwizardry\:possession.insufficienthealth=You don't have enough health to possess %1$s!
|
spell.ebwizardry\:possession.insufficienthealth=You don't have enough health to possess %1$s!
|
||||||
spell.ebwizardry\:possession.success=Press %s to stop possessing
|
spell.ebwizardry\:possession.success=Press %s to stop possessing
|
||||||
spell.ebwizardry\:divination.nothing=Nothing happened.
|
spell.ebwizardry\:divination.nothing=Nothing happened.
|
||||||
@@ -1003,6 +1003,16 @@ enchantment.ebwizardry\:magic_protection=Magic Protection
|
|||||||
enchantment.ebwizardry\:frost_protection=Frost Protection
|
enchantment.ebwizardry\:frost_protection=Frost Protection
|
||||||
enchantment.ebwizardry\:shock_protection=Shock Protection
|
enchantment.ebwizardry\:shock_protection=Shock Protection
|
||||||
|
|
||||||
|
enchantment.ebwizardry.magic_sword.desc=Part of the Imbue Weapon spell; unobtainable in survival mode (the book won't work).
|
||||||
|
enchantment.ebwizardry.magic_bow.desc=Part of the Imbue Weapon spell; unobtainable in survival mode (the book won't work).
|
||||||
|
enchantment.ebwizardry.flaming_weapon.desc=Part of the Flaming Weapon spell; unobtainable in survival mode (the book won't work).
|
||||||
|
enchantment.ebwizardry.freezing_weapon.desc=Part of the Freezing Weapon spell; unobtainable in survival mode (the book won't work).
|
||||||
|
enchantment.ebwizardry.shocking_weapon.desc=Part of the Shocking Weapon spell; unobtainable in survival mode (the book won't work).
|
||||||
|
|
||||||
|
enchantment.ebwizardry.magic_protection.desc=Reduces damage from all magic.
|
||||||
|
enchantment.ebwizardry.frost_protection.desc=Reduces the effects of frost damage.
|
||||||
|
enchantment.ebwizardry.shock_protection.desc=Reduces the effects of shock damage.
|
||||||
|
|
||||||
key.categories.ebwizardry=Wizardry
|
key.categories.ebwizardry=Wizardry
|
||||||
|
|
||||||
key.ebwizardry.next_spell=Next Spell
|
key.ebwizardry.next_spell=Next Spell
|
||||||
@@ -1011,7 +1021,7 @@ key.ebwizardry.previous_spell=Previous Spell
|
|||||||
death.attack.wizardry_magic=%1$s was killed by %2$s using magic
|
death.attack.wizardry_magic=%1$s was killed by %2$s using magic
|
||||||
death.attack.indirect_wizardry_magic=%1$s was killed by %2$s using magic
|
death.attack.indirect_wizardry_magic=%1$s was killed by %2$s using magic
|
||||||
|
|
||||||
soundCategory.ebwizardry\:spells=Spells
|
soundCategory.ebwizardry_spells=Spells
|
||||||
|
|
||||||
commands.ebwizardry\:cast.usage=/%1$s <spell> [player | x y z direction] [duration] [modifiers]
|
commands.ebwizardry\:cast.usage=/%1$s <spell> [player | x y z direction] [duration] [modifiers]
|
||||||
commands.ebwizardry\:cast.success=Successfully cast %s
|
commands.ebwizardry\:cast.success=Successfully cast %s
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,6 @@
|
|||||||
"cooldown": 300,
|
"cooldown": 300,
|
||||||
"base_properties": {
|
"base_properties": {
|
||||||
"resistance_duration": 600,
|
"resistance_duration": 600,
|
||||||
"resistance_strength": 3
|
"resistance_strength": 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,6 @@
|
|||||||
"cooldown": 100,
|
"cooldown": 100,
|
||||||
"base_properties": {
|
"base_properties": {
|
||||||
"resistance_duration": 600,
|
"resistance_duration": 600,
|
||||||
"resistance_strength": 2
|
"resistance_strength": 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,6 @@
|
|||||||
"cooldown": 50,
|
"cooldown": 50,
|
||||||
"base_properties": {
|
"base_properties": {
|
||||||
"resistance_duration": 600,
|
"resistance_duration": 600,
|
||||||
"resistance_strength": 1
|
"resistance_strength": 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -732,11 +732,11 @@
|
|||||||
|
|
||||||
"Code:",
|
"Code:",
|
||||||
|
|
||||||
"- Corail31 \n- 12foo \n- Shadows-of-Fire \n- Tora-B \n- Avatair \n- Aeronica",
|
"- Corail31 \n- 12foo \n- Shadows-of-Fire \n- HellFirePvP \n- Tora-B \n- Avatair \n- Aeronica",
|
||||||
|
|
||||||
"Translations:",
|
"Translations:",
|
||||||
|
|
||||||
"- Spanish and Mexican Spanish: MadWrist \n- Russian: VilagVil, kellixon \n- French: Hahdrim \n- Brazilian Portuguese: lorrampi \n- Chinese: ZHENGLOC, dragon-evol \n-Korean: shejery, rewi_wire",
|
"- Spanish and Mexican Spanish: MadWrist \n- Russian: VilagVil, kellixon \n- French: Hahdrim \n- Brazilian Portuguese: lorrampi \n- Chinese: ZHENGLOC, dragon-evol \n- Korean: shejery, rewi_wire \n- Polish: Trozuu",
|
||||||
|
|
||||||
"Lightning ray sound effect from OhhWowProductions",
|
"Lightning ray sound effect from OhhWowProductions",
|
||||||
|
|
||||||
|
|||||||
@@ -732,11 +732,11 @@
|
|||||||
|
|
||||||
"Code:",
|
"Code:",
|
||||||
|
|
||||||
"- Corail31 \n- 12foo \n- Shadows-of-Fire \n- Tora-B \n- Avatair \n- Aeronica",
|
"- Corail31 \n- 12foo \n- Shadows-of-Fire \n- HellFirePvP \n- Tora-B \n- Avatair \n- Aeronica",
|
||||||
|
|
||||||
"Translations:",
|
"Translations:",
|
||||||
|
|
||||||
"- Spanish and Mexican Spanish: MadWrist \n- Russian: VilagVil, kellixon \n- French: Hahdrim \n- Brazilian Portuguese: lorrampi \n- Chinese: ZHENGLOC, dragon-evol \n-Korean: shejery, rewi_wire",
|
"- Spanish and Mexican Spanish: MadWrist \n- Russian: VilagVil, kellixon \n- French: Hahdrim \n- Brazilian Portuguese: lorrampi \n- Chinese: ZHENGLOC, dragon-evol \n- Korean: shejery, rewi_wire \n- Polish: Trozuu",
|
||||||
|
|
||||||
"Lightning ray sound effect from OhhWowProductions",
|
"Lightning ray sound effect from OhhWowProductions",
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 31 KiB |
@@ -2,10 +2,10 @@
|
|||||||
{
|
{
|
||||||
"modid" : "ebwizardry",
|
"modid" : "ebwizardry",
|
||||||
"name" : "Electroblob's Wizardry",
|
"name" : "Electroblob's Wizardry",
|
||||||
"version" : "4.2.1",
|
"version" : "4.2.2",
|
||||||
"mcversion" : "1.12.2",
|
"mcversion" : "1.12.2",
|
||||||
"url" : "https://minecraft.curseforge.com/projects/electroblobs-wizardry",
|
"url" : "https://minecraft.curseforge.com/projects/electroblobs-wizardry",
|
||||||
"credits" : "\nDesigned, coded and textured by Electroblob.\nCode contributed by: Corail31, 12foo, Shadows-of-Fire, Tora-B, Avatair, Aeronica.\nTranslators: MadWrist (Spanish, Mexican Spanish), VilagVil & kellixon (Russian), Hahdrim (French), lorrampi (Brazilian Portuguese), ZHENGLOC & dragon-evol (Chinese), shejery & rewi_wire (Korean).",
|
"credits" : "\nDesigned, coded and textured by Electroblob.\nCode contributed by: Corail31, 12foo, Shadows-of-Fire, Tora-B, Avatair, Aeronica.\nTranslators: MadWrist (Spanish, Mexican Spanish), VilagVil & kellixon (Russian), Hahdrim (French), lorrampi (Brazilian Portuguese), ZHENGLOC & dragon-evol (Chinese), shejery & rewi_wire (Korean), Trozuu (Polish).",
|
||||||
"authorList" : [
|
"authorList" : [
|
||||||
"Electroblob"
|
"Electroblob"
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user