Compare commits

...

27 Commits

Author SHA1 Message Date
Electroblob77 a490168fa2 Derp 2020-03-19 15:46:42 +00:00
Electroblob77 306137a026 Update version number 2020-03-19 15:38:19 +00:00
Electroblob77 0a5527f3d4 Add backwards compatibility to convert old-format atlas markers to new ones 2020-03-19 15:35:09 +00:00
Electroblob77 4dbe24c8ea This is the problem with everything being a string... 2020-03-19 15:13:25 +00:00
Electroblob77 81bba5e7e0 Add null check to ice spikes, fixes #371 2020-03-19 13:35:36 +00:00
Electroblob77 9c29142e6a Maven-ify all the things and update Antique Atlas 2020-03-19 13:33:34 +00:00
Electroblob77 3151d7d626 Require Antique Atlas 4.6 or newer 2020-03-18 17:18:41 +00:00
Electroblob77 d68f968632 Make sure fall damage stuff is processed on the server only, and reactivate the config option by default 2020-03-18 16:00:23 +00:00
Electroblob77 74d9198522 Convert replaceVanillaFireballs to a synchronised option, fixes #351 2020-03-18 15:50:01 +00:00
Electroblob77 0b56d47022 Replace wildcard with metadata 0 for display purposes, fixes #370
N.B. The output is still not visible for non-zero inputs when using wildcard trades, but for now this is good enough
2020-03-18 15:32:59 +00:00
Electroblob77 587ab1338e Make Magic Protection protect against vanilla magic damage, closes #337 2020-03-18 14:57:04 +00:00
Electroblob77 4816c48aa6 Disable replaceVanillaFallDamage by default 2020-03-18 14:49:12 +00:00
Electroblob77 79b745e005 Randomise y coordinate to search from when spawning structures in 'cavern' dimensions, fixes #372 2020-03-17 23:54:52 +00:00
Electroblob77 6fff0e31d1 *Facepalm* 2020-03-17 23:45:40 +00:00
Electroblob77 11efe56437 Replace old hardcoded spell book text with translation keys, fixes #368 2020-03-17 23:38:25 +00:00
Electroblob77 7f5786c28c Override override override! 2020-03-17 23:22:54 +00:00
Electroblob77 85b49b330a Make tomes of arcana more common in obelisks, shrines and wizard towers, and make tomes generated as loot more likely to be apprentice tier 2020-03-17 23:16:04 +00:00
Electroblob77 d797e72445 Reduce rarity of all structures a bit 2020-03-17 23:13:17 +00:00
Electroblob77 5f21b565cd Make fireballs, large fireballs and iceballs respect the playerBlockDamage config option 2020-03-17 22:44:30 +00:00
Electroblob77 9ed06c9a34 Stop wizards casting heal ally 2020-03-17 22:34:34 +00:00
Electroblob77 50f315666f Fix spanish handbook translations, fixes #365 2020-03-15 19:23:50 +00:00
Electroblob77 62bdbc81e4 Prevent players from picking up items when possessing and prevent players from possessing whilst sneaking, fixes #376 2020-03-15 19:15:28 +00:00
Electroblob77 3a571fd239 Update credits 2020-02-29 11:25:35 +00:00
Electroblob 4fb5452dc4 Merge pull request #363 from chesterccj305/patch-1
Create handbook_zh_tw.json
2020-02-24 16:51:28 +00:00
Electroblob 652f1d2620 Merge pull request #364 from chesterccj305/patch-2
Create zh_tw.lang
2020-02-24 16:51:15 +00:00
chesterccj305 046ecb1e41 Create zh_tw.lang 2020-02-21 22:56:45 +08:00
chesterccj305 f3dd7bccd8 Create handbook_zh_tw.json 2020-02-21 22:55:22 +08:00
33 changed files with 2218 additions and 118 deletions
+1 -1
View File
@@ -10,7 +10,7 @@ assignees: ''
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting. Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting.
Minecraft version: 1.12.2 [change as necessary] Minecraft version: 1.12.2 [change as necessary]
Wizardry version: 4.2.9 [change as necessary] Wizardry version: 4.2.10 [change as necessary]
Environment: Singleplayer/LAN game/Server [delete as necessary] Environment: Singleplayer/LAN game/Server [delete as necessary]
Issue details: [describe what you were doing when the issue occurred, what went wrong, what you expected to happen, etc.] Issue details: [describe what you were doing when the issue occurred, what went wrong, what you expected to happen, etc.]
+1 -1
View File
@@ -10,7 +10,7 @@ assignees: ''
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting. Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting.
Minecraft version: 1.12.2 [change as necessary] Minecraft version: 1.12.2 [change as necessary]
Wizardry version: 4.2.9 [change as necessary] Wizardry version: 4.2.10 [change as necessary]
Question details: [explain your question here] Question details: [explain your question here]
+2 -1
View File
@@ -1,7 +1,7 @@
# Credits # Credits
Electroblob's Wizardry Electroblob's Wizardry
Version 4.2.9 Version 4.2.10
For Minecraft 1.12.2 For Minecraft 1.12.2
Designed, coded and textured by Electroblob Designed, coded and textured by Electroblob
@@ -36,5 +36,6 @@ In addition, I'd like to thank the following individuals for their contributions
- Korean: shejery, rewi_wire - Korean: shejery, rewi_wire
- Polish: Trozuu - Polish: Trozuu
- German: BirdyDragon - German: BirdyDragon
- Taiwanese: chesterccj305
Lightning ray sound effect from OhhWowProductions Lightning ray sound effect from OhhWowProductions
+1 -1
View File
@@ -1,7 +1,7 @@
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting. Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting.
Minecraft version: 1.12.2 [change as necessary] Minecraft version: 1.12.2 [change as necessary]
Wizardry version: 4.2.9 [change as necessary] Wizardry version: 4.2.10 [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.]
+8 -36
View File
@@ -11,7 +11,7 @@ apply plugin: 'net.minecraftforge.gradle.forge'
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. //Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
version = "4.2.9" // There, it matches semver, happy now? version = "4.2.10" // 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"
@@ -31,15 +31,10 @@ repositories {
name = "ModMaven" name = "ModMaven"
url = "modmaven.k-4u.nl" url = "modmaven.k-4u.nl"
} }
flatDir { maven {
// evErYthINg hAS tO Be a mAVeN rEPoSiTOrY... (to use deobfProvided, for some reason) name = "Curseforge Maven"
// The lack of documentation is actually quite impressive, see the following threads: url = "https://minecraft.curseforge.com/api/maven/"
// http://www.minecraftforge.net/forum/topic/44262-solved-how-to-build-mod-with-dependencies/
// https://www.minecraftforum.net/forums/mapping-and-modding-java-edition/mapping-and-modding-tutorials/2866817-setting-up-dependencies-in-minecraft-forge-with
// http://www.minecraftforge.net/forum/topic/44534-adding-dependencies-to-a-forge-project/
dirs "libsfordeobf" // Don't put src jars in libs or forge will think you have duplicate mods
} }
} }
minecraft { minecraft {
@@ -56,37 +51,14 @@ minecraft {
} }
dependencies { dependencies {
// you may put jars on which you depend on in ./libs
// or you may define them like so..
//compile "some.group:artifact:version:classifier"
//compile "some.group:artifact:version"
// compile against the JEI API but do not include it at runtime // Compile against the JEI API but do not include it at runtime
deobfProvided "mezz.jei:jei_${mc_version}:${jei_version}:api" deobfProvided "mezz.jei:jei_${mc_version}:${jei_version}:api"
// at runtime, use the full JEI jar // At runtime, use the full JEI jar
runtime "mezz.jei:jei_${mc_version}:${jei_version}" runtime "mezz.jei:jei_${mc_version}:${jei_version}"
//deobfProvided "baubles:baubles-1.12:1.5.2:api" // #ihavenoideawhatimdoing #itjustworks deobfCompile "baubles:Baubles:${mc_version_short}:${baubles_version}"
//runtime "baubles:baubles-1.12:1.5.2" // If in doubt, copy what already works deobfCompile "antique-atlas:antiqueatlas:${mc_version}:${antique_atlas_version}"
//deobfProvided "antiqueatlas:antiqueatlas-1.12.2:4.5.1:src"
//runtime "antiqueatlas:antiqueatlas-1.12.2:4.5.1"
// real examples
//compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
//compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env
// the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
//provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// the deobf configurations: 'deobfCompile' and 'deobfProvided' are the same as the normal compile and provided,
// except that these dependencies get remapped to your current MCP mappings
//deobfCompile 'com.mod-buildcraft:buildcraft:6.0.8:dev'
//deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// for more info...
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
// http://www.gradle.org/docs/current/userguide/dependency_management.html
} }
+3
View File
@@ -2,4 +2,7 @@
# This is required to provide enough memory for the Minecraft decompilation process. # This is required to provide enough memory for the Minecraft decompilation process.
org.gradle.jvmargs=-Xmx3G org.gradle.jvmargs=-Xmx3G
mc_version=1.12.2 mc_version=1.12.2
mc_version_short=1.12
jei_version=4.13.1.225 jei_version=4.13.1.225
baubles_version=1.5.2
antique_atlas_version=4.6.3
@@ -94,7 +94,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 = 900; public int towerRarity = 700;
/** <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"),
@@ -108,7 +108,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 = 800; public int obeliskRarity = 600;
/** <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"),
@@ -118,7 +118,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 = 1500; public int shrineRarity = 1100;
/** <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"),
@@ -168,8 +168,6 @@ public final class Settings {
public boolean playerBlockDamage = true; public boolean playerBlockDamage = true;
/** <b>[Server-only]</b> Whether to revert to the old wand upgrade system, which only requires tomes of arcana. */ /** <b>[Server-only]</b> Whether to revert to the old wand upgrade system, which only requires tomes of arcana. */
public boolean legacyWandLevelling = false; public boolean legacyWandLevelling = false;
/** <b>[Server-only]</b> Whether to replace Minecraft's own fireballs with wizardry fireballs. */
public boolean replaceVanillaFireballs = true;
/** <b>[Server-only]</b> Whether to replace Minecraft's distance-based fall damage calculation with an equivalent, /** <b>[Server-only]</b> Whether to replace Minecraft's distance-based fall damage calculation with an equivalent,
* velocity-based one. */ * velocity-based one. */
public boolean replaceVanillaFallDamage = true; public boolean replaceVanillaFallDamage = true;
@@ -272,7 +270,9 @@ public final class Settings {
* effect. * effect.
*/ */
public boolean slowTimeAffectsPlayers = true; public boolean slowTimeAffectsPlayers = true;
/** <b>[Synchronised]</b> Chance of 'misreading' an undiscovered spell and triggering a forfeit instead. */ /** <b>[Synchronised]</b> Whether to replace Minecraft's own fireballs with wizardry fireballs. */
public boolean replaceVanillaFireballs = true;
/** <b>[Synchronised]</b> Chance of 'misreading' an undiscovered spell and triggering a forfeit instead. */
public double forfeitChance = 0.2; public double forfeitChance = 0.2;
// Client-only settings. These settings only affect client-side code and hence are not synced. Each client obeys // Client-only settings. These settings only affect client-side code and hence are not synced. Each client obeys
@@ -46,7 +46,7 @@ import java.util.Calendar;
*/ */
@Mod(modid = Wizardry.MODID, name = Wizardry.NAME, version = Wizardry.VERSION, acceptedMinecraftVersions = "[1.12.2]", @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,)") guiFactory = "electroblob.wizardry.WizardryGuiFactory", dependencies = "required-after:forge@[14.23.5.2814,);after:antiqueatlas@[4.6,)")
public class Wizardry { public class Wizardry {
@@ -64,7 +64,7 @@ public class Wizardry {
* 1.x.x represents Minecraft 1.7.x versions, 2.x.x represents Minecraft 1.10.x versions, 3.x.x represents Minecraft * 1.x.x represents Minecraft 1.7.x versions, 2.x.x represents Minecraft 1.10.x versions, 3.x.x represents Minecraft
* 1.11.x versions, and so on. * 1.11.x versions, and so on.
*/ */
public static final String VERSION = "4.2.9"; public static final String VERSION = "4.2.10";
// 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
@@ -420,7 +420,7 @@ public final class WizardryEventHandler {
@SubscribeEvent // Priority doesn't matter here, we're only setting event fields so if it's cancelled it won't matter @SubscribeEvent // Priority doesn't matter here, we're only setting event fields so if it's cancelled it won't matter
public static void onLivingFallEvent(LivingFallEvent event){ public static void onLivingFallEvent(LivingFallEvent event){
// Why is fall damage based on distance fallen? Why? Who on earth came up with that? It makes no sense whatsoever! // Why is fall damage based on distance fallen? Why? Who on earth came up with that? It makes no sense whatsoever!
if(Wizardry.settings.replaceVanillaFallDamage && !Loader.isModLoaded("speedbasedfalldamage")){ if(!event.getEntity().world.isRemote && Wizardry.settings.replaceVanillaFallDamage && !Loader.isModLoaded("speedbasedfalldamage")){
// We want to keep the fall damage EXACTLY THE SAME for free, uninterrupted falls, but fix the weirdness // We want to keep the fall damage EXACTLY THE SAME for free, uninterrupted falls, but fix the weirdness
// caused when something else changes the entity's velocity // caused when something else changes the entity's velocity
// All living entities have a gravity of 0.08b/t^2 // All living entities have a gravity of 0.08b/t^2
@@ -13,6 +13,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord; import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
@@ -32,9 +33,7 @@ public class GuiSpellBook extends GuiScreen {
this.spell = Spell.byMetadata(stack.getItemDamage()); this.spell = Spell.byMetadata(stack.getItemDamage());
} }
/** @Override
* Draws the screen and all the components in it.
*/
public void drawScreen(int par1, int par2, float par3){ public void drawScreen(int par1, int par2, float par3){
int xPos = this.width / 2 - xSize / 2; int xPos = this.width / 2 - xSize / 2;
@@ -69,22 +68,18 @@ public class GuiSpellBook extends GuiScreen {
0x777777); 0x777777);
} }
//this.fontRenderer.drawString("-------------------", xPos + 17, yPos + 35, 0); // Novice is usually white but this doesn't show up
String tier = I18n.format("gui.ebwizardry:spell_book.tier", spell.getTier() == Tier.NOVICE ?
"\u00A77" + spell.getTier().getDisplayName() : spell.getTier().getDisplayNameWithFormatting());
this.fontRenderer.drawString(tier, xPos + 17, yPos + 45, 0);
if(spell.getTier() == Tier.NOVICE){ String element = I18n.format("gui.ebwizardry:spell_book.element", spell.getElement().getFormattingCode() + spell.getElement().getDisplayName());
// Novice is usually white but this doesn't show up. if(!discovered) element = I18n.format("gui.ebwizardry:spell_book.element_undiscovered");
this.fontRenderer.drawString("Tier: \u00A77" + Tier.NOVICE.getDisplayName(), xPos + 17, yPos + 45, 0);
}else{
this.fontRenderer.drawString("Tier: " + spell.getTier().getDisplayNameWithFormatting(), xPos + 17, yPos + 45, 0);
}
String element = "Element: " + spell.getElement().getFormattingCode() + spell.getElement().getDisplayName();
if(!discovered) element = "Element: ?";
this.fontRenderer.drawString(element, xPos + 17, yPos + 57, 0); this.fontRenderer.drawString(element, xPos + 17, yPos + 57, 0);
String manaCost = "Mana Cost: " + spell.getCost(); String manaCost = I18n.format("gui.ebwizardry:spell_book.mana_cost", spell.getCost());
if(spell.isContinuous) manaCost = "Mana Cost: " + spell.getCost() + "/second"; if(spell.isContinuous) manaCost = I18n.format("gui.ebwizardry:spell_book.mana_cost_continuous", spell.getCost());
if(!discovered) manaCost = "Mana Cost: ?"; if(!discovered) manaCost = I18n.format("gui.ebwizardry:spell_book.mana_cost_undiscovered");
this.fontRenderer.drawString(manaCost, xPos + 17, yPos + 69, 0); this.fontRenderer.drawString(manaCost, xPos + 17, yPos + 69, 0);
if(discovered){ if(discovered){
@@ -95,6 +90,7 @@ public class GuiSpellBook extends GuiScreen {
} }
} }
@Override
public void initGui(){ public void initGui(){
super.initGui(); super.initGui();
Keyboard.enableRepeatEvents(true); Keyboard.enableRepeatEvents(true);
@@ -103,6 +99,7 @@ public class GuiSpellBook extends GuiScreen {
this.mc.getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(WizardrySounds.MISC_BOOK_OPEN, 1)); this.mc.getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(WizardrySounds.MISC_BOOK_OPEN, 1));
} }
@Override
public void onGuiClosed(){ public void onGuiClosed(){
super.onGuiClosed(); super.onGuiClosed();
Keyboard.enableRepeatEvents(false); Keyboard.enableRepeatEvents(false);
@@ -68,7 +68,7 @@ public class EnchantmentMagicProtection extends Enchantment {
public enum Type { public enum Type {
MAGIC("magic", 1, 5, 8, s -> s instanceof IElementalDamage), MAGIC("magic", 1, 5, 8, s -> s instanceof IElementalDamage || s.isMagicDamage()),
FROST("frost", 2, 10, 8, s -> s instanceof IElementalDamage && ((IElementalDamage)s).getType() == MagicDamage.DamageType.FROST), FROST("frost", 2, 10, 8, s -> s instanceof IElementalDamage && ((IElementalDamage)s).getType() == MagicDamage.DamageType.FROST),
SHOCK("shock", 2, 10, 8, s -> s instanceof IElementalDamage && ((IElementalDamage)s).getType() == MagicDamage.DamageType.SHOCK); SHOCK("shock", 2, 10, 8, s -> s instanceof IElementalDamage && ((IElementalDamage)s).getType() == MagicDamage.DamageType.SHOCK);
// Fire already exists, and the other types aren't used enough to be worth having // Fire already exists, and the other types aren't used enough to be worth having
@@ -10,6 +10,7 @@ import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.MoverType; import net.minecraft.entity.MoverType;
import net.minecraft.potion.PotionEffect; import net.minecraft.potion.PotionEffect;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@@ -61,10 +62,9 @@ public class EntityIceSpike extends EntityMagicConstruct {
if(!this.world.isRemote){ if(!this.world.isRemote){
for(Object entity : this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox())){ for(Object entity : this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox())){
if(entity instanceof EntityLivingBase && this.isValidTarget((EntityLivingBase)entity)){ if(entity instanceof EntityLivingBase && this.isValidTarget((EntityLivingBase)entity)){
DamageSource source = this.getCaster() == null ? DamageSource.MAGIC : MagicDamage.causeDirectMagicDamage(this.getCaster(), DamageType.FROST);
// Potion effect only gets added if the damage succeeded. // Potion effect only gets added if the damage succeeded.
if(((EntityLivingBase)entity).attackEntityFrom( if(((EntityLivingBase)entity).attackEntityFrom(source, Spells.ice_spikes.getProperty(Spell.DAMAGE).floatValue() * this.damageMultiplier))
MagicDamage.causeDirectMagicDamage(this.getCaster(), DamageType.FROST),
Spells.ice_spikes.getProperty(Spell.DAMAGE).floatValue() * this.damageMultiplier))
((EntityLivingBase)entity).addPotionEffect(new PotionEffect(WizardryPotions.frost, ((EntityLivingBase)entity).addPotionEffect(new PotionEffect(WizardryPotions.frost,
Spells.ice_spikes.getProperty(Spell.EFFECT_DURATION).intValue(), Spells.ice_spikes.getProperty(Spell.EFFECT_DURATION).intValue(),
Spells.ice_spikes.getProperty(Spell.EFFECT_STRENGTH).intValue())); Spells.ice_spikes.getProperty(Spell.EFFECT_STRENGTH).intValue()));
@@ -503,7 +503,6 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
ItemStack anySpellBook = new ItemStack(WizardryItems.spell_book, 1, OreDictionary.WILDCARD_VALUE); ItemStack anySpellBook = new ItemStack(WizardryItems.spell_book, 1, OreDictionary.WILDCARD_VALUE);
ItemStack crystalStack = new ItemStack(WizardryItems.magic_crystal, 5); ItemStack crystalStack = new ItemStack(WizardryItems.magic_crystal, 5);
// NOTE: For wizardry 1.2, increase the number of uses of this trade. The default is 7, for reference.
this.trades.add(new MerchantRecipe(anySpellBook, crystalStack)); this.trades.add(new MerchantRecipe(anySpellBook, crystalStack));
this.addRandomRecipes(3); this.addRandomRecipes(3);
@@ -9,7 +9,6 @@ import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.ParticleBuilder; import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.WizardryUtilities; import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.potion.PotionEffect; import net.minecraft.potion.PotionEffect;
@@ -48,13 +47,7 @@ public class EntityIceball extends EntityMagicProjectile {
}else{ }else{
boolean flag = true; if(this.getThrower() == null || WizardryUtilities.canDamageBlocks(this.getThrower(), world)){
if(this.getThrower() != null && this.getThrower() instanceof EntityLiving){
flag = net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this.getThrower());
}
if(flag){
BlockPos pos = rayTrace.getBlockPos(); BlockPos pos = rayTrace.getBlockPos();
@@ -3,6 +3,7 @@ package electroblob.wizardry.entity.projectile;
import electroblob.wizardry.Wizardry; 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 io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import net.minecraft.entity.projectile.EntityLargeFireball; import net.minecraft.entity.projectile.EntityLargeFireball;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
@@ -50,7 +51,7 @@ public class EntityLargeMagicFireball extends EntityMagicFireball {
protected void onImpact(RayTraceResult rayTrace){ protected void onImpact(RayTraceResult rayTrace){
if(!world.isRemote){ if(!world.isRemote){
boolean flag = net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this.thrower); boolean flag = this.getThrower() == null || WizardryUtilities.canDamageBlocks(this.getThrower(), world);
this.world.newExplosion(null, this.posX, this.posY, this.posZ, getExplosionPower() * blastMultiplier, flag, flag); this.world.newExplosion(null, this.posX, this.posY, this.posZ, getExplosionPower() * blastMultiplier, flag, flag);
} }
@@ -6,9 +6,9 @@ import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.MagicDamage; import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType; import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.ParticleBuilder; import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.WizardryUtilities;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.projectile.EntitySmallFireball; import net.minecraft.entity.projectile.EntitySmallFireball;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
@@ -84,13 +84,7 @@ public class EntityMagicFireball extends EntityMagicProjectile {
}else{ }else{
boolean flag = true; if(this.getThrower() == null || WizardryUtilities.canDamageBlocks(this.getThrower(), world)){
if(this.getThrower() != null && this.getThrower() instanceof EntityLiving){
flag = net.minecraftforge.event.ForgeEventFactory.getMobGriefingEvent(this.world, this.getThrower());
}
if(flag){
BlockPos blockpos = rayTrace.getBlockPos().offset(rayTrace.sideHit); BlockPos blockpos = rayTrace.getBlockPos().offset(rayTrace.sideHit);
@@ -1,11 +1,17 @@
package electroblob.wizardry.integration.antiqueatlas; package electroblob.wizardry.integration.antiqueatlas;
import electroblob.wizardry.Wizardry; import electroblob.wizardry.Wizardry;
import hunternif.mc.atlas.AntiqueAtlasMod;
import hunternif.mc.atlas.api.AtlasAPI; import hunternif.mc.atlas.api.AtlasAPI;
import hunternif.mc.atlas.marker.GlobalMarkersData;
import hunternif.mc.atlas.marker.Marker;
import hunternif.mc.atlas.registry.MarkerType; import hunternif.mc.atlas.registry.MarkerType;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
/** /**
* This class handles all of wizardry's integration with the <i>Antique Atlas</i> mod. This class contains only the code * This class handles all of wizardry's integration with the <i>Antique Atlas</i> mod. This class contains only the code
@@ -15,6 +21,7 @@ import net.minecraftforge.fml.common.Loader;
* @since Wizardry 4.2 * @since Wizardry 4.2
* @author Electroblob * @author Electroblob
*/ */
@Mod.EventBusSubscriber
public class WizardryAntiqueAtlasIntegration { public class WizardryAntiqueAtlasIntegration {
public static final String ANTIQUE_ATLAS_MOD_ID = "antiqueatlas"; public static final String ANTIQUE_ATLAS_MOD_ID = "antiqueatlas";
@@ -38,7 +45,7 @@ public class WizardryAntiqueAtlasIntegration {
* {@link electroblob.wizardry.Settings#autoTowerMarkers} is enabled. Server side only! */ * {@link electroblob.wizardry.Settings#autoTowerMarkers} is enabled. Server side only! */
public static void markTower(World world, int x, int z){ public static void markTower(World world, int x, int z){
if(enabled() && Wizardry.settings.autoTowerMarkers){ if(enabled() && Wizardry.settings.autoTowerMarkers){
AtlasAPI.getMarkerAPI().putGlobalMarker(world, false, TOWER_MARKER.toString().replace(':', '.'), "integration.antiqueatlas.marker." + TOWER_MARKER.toString(), x, z); AtlasAPI.getMarkerAPI().putGlobalMarker(world, false, TOWER_MARKER.toString(), "integration.antiqueatlas.marker." + TOWER_MARKER.toString().replace(':', '.'), x, z);
} }
} }
@@ -46,7 +53,7 @@ public class WizardryAntiqueAtlasIntegration {
* {@link electroblob.wizardry.Settings#autoObeliskMarkers} is enabled. Server side only! */ * {@link electroblob.wizardry.Settings#autoObeliskMarkers} is enabled. Server side only! */
public static void markObelisk(World world, int x, int z){ public static void markObelisk(World world, int x, int z){
if(enabled() && Wizardry.settings.autoObeliskMarkers){ if(enabled() && Wizardry.settings.autoObeliskMarkers){
AtlasAPI.getMarkerAPI().putGlobalMarker(world, false, OBELISK_MARKER.toString().replace(':', '.'), "integration.antiqueatlas.marker." + OBELISK_MARKER.toString(), x, z); AtlasAPI.getMarkerAPI().putGlobalMarker(world, false, OBELISK_MARKER.toString(), "integration.antiqueatlas.marker." + OBELISK_MARKER.toString().replace(':', '.'), x, z);
} }
} }
@@ -54,7 +61,7 @@ public class WizardryAntiqueAtlasIntegration {
* {@link electroblob.wizardry.Settings#autoShrineMarkers} is enabled. Server side only! */ * {@link electroblob.wizardry.Settings#autoShrineMarkers} is enabled. Server side only! */
public static void markShrine(World world, int x, int z){ public static void markShrine(World world, int x, int z){
if(enabled() && Wizardry.settings.autoShrineMarkers){ if(enabled() && Wizardry.settings.autoShrineMarkers){
AtlasAPI.getMarkerAPI().putGlobalMarker(world, false, SHRINE_MARKER.toString().replace(':', '.'), "integration.antiqueatlas.marker." + SHRINE_MARKER.toString(), x, z); AtlasAPI.getMarkerAPI().putGlobalMarker(world, false, SHRINE_MARKER.toString(), "integration.antiqueatlas.marker." + SHRINE_MARKER.toString().replace(':', '.'), x, z);
} }
} }
@@ -68,4 +75,21 @@ public class WizardryAntiqueAtlasIntegration {
AtlasAPI.getMarkerAPI().registerMarker(new MarkerType(OBELISK_MARKER, new ResourceLocation(Wizardry.MODID, "textures/integration/antiqueatlas/obelisk.png"))); AtlasAPI.getMarkerAPI().registerMarker(new MarkerType(OBELISK_MARKER, new ResourceLocation(Wizardry.MODID, "textures/integration/antiqueatlas/obelisk.png")));
} }
@SubscribeEvent
public static void onWorldLoadEvent(WorldEvent.Load event){
if(!enabled()) return;
// Backwards compatibility for existing markers using the old translation key format (with colons)
GlobalMarkersData data = AntiqueAtlasMod.globalMarkersData.getData();
for(Marker marker : data.getMarkersInDimension(event.getWorld().provider.getDimension())){
if(marker.getLabel().contains(":")){
// Remove old-format markers and replace them with new ones
data.removeMarker(marker.getId());
AtlasAPI.getMarkerAPI().putGlobalMarker(event.getWorld(), marker.isVisibleAhead(), marker.getType(),
marker.getLabel().replace(':', '.'), marker.getX(), marker.getZ());
}
}
}
} }
@@ -1,8 +1,10 @@
package electroblob.wizardry.misc; package electroblob.wizardry.misc;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
import net.minecraft.network.PacketBuffer;
import net.minecraft.village.MerchantRecipe; import net.minecraft.village.MerchantRecipe;
import net.minecraft.village.MerchantRecipeList; import net.minecraft.village.MerchantRecipeList;
import net.minecraftforge.oredict.OreDictionary; import net.minecraftforge.oredict.OreDictionary;
@@ -46,7 +48,7 @@ public class WildcardTradeList extends MerchantRecipeList {
} }
private boolean areItemStacksExactlyEqual(ItemStack stack1, ItemStack stack2){ private boolean areItemStacksExactlyEqual(ItemStack stack1, ItemStack stack2){
// Added to allow wildcards; this line is the only actual change. // Added to allow wildcards
if((stack1.getItemDamage() == OreDictionary.WILDCARD_VALUE || stack2.getItemDamage() == OreDictionary.WILDCARD_VALUE) if((stack1.getItemDamage() == OreDictionary.WILDCARD_VALUE || stack2.getItemDamage() == OreDictionary.WILDCARD_VALUE)
// Can't use ItemStack.areItemsEqualIgnoreDurability because that only works for items with durability, not subtypes. // Can't use ItemStack.areItemsEqualIgnoreDurability because that only works for items with durability, not subtypes.
&& stack1.getItem() == stack2.getItem()) return true; && stack1.getItem() == stack2.getItem()) return true;
@@ -54,4 +56,34 @@ public class WildcardTradeList extends MerchantRecipeList {
return ItemStack.areItemsEqual(stack1, stack2) && (!stack2.hasTagCompound() || stack1.hasTagCompound() && NBTUtil.areNBTEquals(stack2.getTagCompound(), stack1.getTagCompound(), false)); return ItemStack.areItemsEqual(stack1, stack2) && (!stack2.hasTagCompound() || stack1.hasTagCompound() && NBTUtil.areNBTEquals(stack2.getTagCompound(), stack1.getTagCompound(), false));
} }
@Override
public void writeToBuf(PacketBuffer buffer){
buffer.writeByte((byte)(this.size() & 255));
// Trick the client into thinking this is a normal item
for(MerchantRecipe merchantrecipe : this){
ItemStack itemToBuy = merchantrecipe.getItemToBuy();
if(itemToBuy.getMetadata() == OreDictionary.WILDCARD_VALUE) itemToBuy = WizardryUtilities.copyWithMeta(itemToBuy, 0);
buffer.writeItemStack(itemToBuy);
ItemStack itemToSell = merchantrecipe.getItemToSell();
if(itemToSell.getMetadata() == OreDictionary.WILDCARD_VALUE) itemToSell = WizardryUtilities.copyWithMeta(itemToSell, 0);
buffer.writeItemStack(itemToSell);
ItemStack secondItemToBuy = merchantrecipe.getSecondItemToBuy();
buffer.writeBoolean(!secondItemToBuy.isEmpty());
if(!secondItemToBuy.isEmpty()){
if(secondItemToBuy.getMetadata() == OreDictionary.WILDCARD_VALUE) secondItemToBuy = WizardryUtilities.copyWithMeta(secondItemToBuy, 0);
buffer.writeItemStack(secondItemToBuy);
}
buffer.writeBoolean(merchantrecipe.isRecipeDisabled());
buffer.writeInt(merchantrecipe.getToolUses());
buffer.writeInt(merchantrecipe.getMaxTradeUses());
}
}
} }
@@ -56,6 +56,7 @@ public class PacketSyncSettings implements IMessageHandler<Message, IMessage> {
settings.discoveryMode = buf.readBoolean(); settings.discoveryMode = buf.readBoolean();
settings.creativeBypassesArcaneLock = buf.readBoolean(); settings.creativeBypassesArcaneLock = buf.readBoolean();
settings.slowTimeAffectsPlayers = buf.readBoolean(); settings.slowTimeAffectsPlayers = buf.readBoolean();
settings.replaceVanillaFireballs = buf.readBoolean();
settings.forfeitChance = buf.readFloat(); settings.forfeitChance = buf.readFloat();
} }
@@ -64,6 +65,7 @@ public class PacketSyncSettings implements IMessageHandler<Message, IMessage> {
buf.writeBoolean(settings.discoveryMode); buf.writeBoolean(settings.discoveryMode);
buf.writeBoolean(settings.creativeBypassesArcaneLock); buf.writeBoolean(settings.creativeBypassesArcaneLock);
buf.writeBoolean(settings.slowTimeAffectsPlayers); buf.writeBoolean(settings.slowTimeAffectsPlayers);
buf.writeBoolean(settings.replaceVanillaFireballs);
buf.writeFloat((float)settings.forfeitChance); // Configs don't have floats but this can only be 0-1 anyway buf.writeFloat((float)settings.forfeitChance); // Configs don't have floats but this can only be 0-1 anyway
} }
} }
@@ -4,6 +4,7 @@ import electroblob.wizardry.util.ParticleBuilder;
import electroblob.wizardry.util.SpellModifiers; import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities; import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.EnumAction; import net.minecraft.item.EnumAction;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
@@ -19,6 +20,11 @@ public class HealAlly extends SpellRay {
addProperties(HEALTH); addProperties(HEALTH);
} }
@Override
public boolean canBeCastBy(EntityLiving npc, boolean override){
return false;
}
@Override @Override
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){ protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
@@ -201,6 +201,8 @@ public class Possession extends SpellRay {
*/ */
public boolean possess(EntityPlayer possessor, EntityLiving target, int duration){ public boolean possess(EntityPlayer possessor, EntityLiving target, int duration){
if(possessor.isSneaking()) return false;
if(WizardData.get(possessor) != null){ if(WizardData.get(possessor) != null){
WizardData.get(possessor).setVariable(POSSESSEE_KEY, target); WizardData.get(possessor).setVariable(POSSESSEE_KEY, target);
@@ -683,11 +685,13 @@ public class Possession extends SpellRay {
if(possessee != null){ if(possessee != null){
if(possessee.canPickUpLoot() && possessee.getHeldItemMainhand().isEmpty()){ event.setCanceled(true);
possessee.setHeldItem(EnumHand.MAIN_HAND, event.getItem().getItem());
}else{ // if(possessee.canPickUpLoot() && possessee.getHeldItemMainhand().isEmpty()){
event.setCanceled(true); // possessee.setHeldItem(EnumHand.MAIN_HAND, event.getItem().getItem());
} // }else{
// event.setCanceled(true);
// }
} }
} }
@@ -24,6 +24,7 @@ import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.inventory.EntityEquipmentSlot.Type; import net.minecraft.inventory.EntityEquipmentSlot.Type;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.datasync.DataParameter; import net.minecraft.network.datasync.DataParameter;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.util.*; import net.minecraft.util.*;
@@ -795,6 +796,20 @@ public final class WizardryUtilities {
return false; return false;
} }
/**
* Returns a new {@link ItemStack} that is identical to the supplied one, except with the metadata changed to the
* new value given.
* @param toCopy The stack to copy
* @param newMetadata The new metadata value
* @return The resulting {@link ItemStack}
*/
public static ItemStack copyWithMeta(ItemStack toCopy, int newMetadata){
ItemStack copy = new ItemStack(toCopy.getItem(), toCopy.getCount(), newMetadata);
NBTTagCompound compound = toCopy.getTagCompound();
if(compound != null) copy.setTagCompound(compound.copy());
return copy;
}
/** /**
* Checks if the given player is opped on the given server. If the server is a singleplayer or LAN server, this * Checks if the given player is opped on the given server. If the server is a singleplayer or LAN server, this
* means they have cheats enabled. * means they have cheats enabled.
@@ -144,6 +144,9 @@ public abstract class WorldGenSurfaceStructure implements IWorldGenerator {
// Estimate a starting height for searching for the floor // Estimate a starting height for searching for the floor
BlockPos centre = world.getTopSolidOrLiquidBlock(new BlockPos(origin.add(size.getX()/2, 0, size.getZ()/2))); BlockPos centre = world.getTopSolidOrLiquidBlock(new BlockPos(origin.add(size.getX()/2, 0, size.getZ()/2)));
// Check if we're at the top of the world, and if so just randomise the y pos (accounts for 'cavern' dimensions)
if(centre.getY() >= world.getActualHeight()) centre = new BlockPos(centre.getX(), random.nextInt(world.getActualHeight()), centre.getZ());
Integer startingHeight = WizardryUtilities.getNearestSurface(world, centre, EnumFacing.UP, 32, true, Integer startingHeight = WizardryUtilities.getNearestSurface(world, centre, EnumFacing.UP, 32, true,
WizardryUtilities.SurfaceCriteria.COLLIDABLE_IGNORING_TREES); WizardryUtilities.SurfaceCriteria.COLLIDABLE_IGNORING_TREES);
@@ -1,4 +1,4 @@
#PARSE_ESCAPES # PARSE_ESCAPES
tile.ebwizardry\:arcane_workbench.name=Arcane Workbench tile.ebwizardry\:arcane_workbench.name=Arcane Workbench
tile.ebwizardry\:crystal_ore.name=Crystal Ore tile.ebwizardry\:crystal_ore.name=Crystal Ore
tile.ebwizardry\:petrified_stone.name=Petrified Stone tile.ebwizardry\:petrified_stone.name=Petrified Stone
@@ -498,6 +498,13 @@ advancement.ebwizardry\:enchant_scroll.desc=Craft a blank scroll and enchant it
handbook.toast.title=New Handbook Section Unlocked! handbook.toast.title=New Handbook Section Unlocked!
gui.ebwizardry\:spell_book.tier=Tier: %s
gui.ebwizardry\:spell_book.element=Element: %s
gui.ebwizardry\:spell_book.element_undiscovered=Element: ?
gui.ebwizardry\:spell_book.mana_cost=Mana Cost: %s
gui.ebwizardry\:spell_book.mana_cost_continuous=Mana Cost: %s/second
gui.ebwizardry\:spell_book.mana_cost_undiscovered=Mana Cost: ?
container.ebwizardry\:arcane_workbench=Arcane Workbench container.ebwizardry\:arcane_workbench=Arcane Workbench
container.ebwizardry\:arcane_workbench.apply=Apply container.ebwizardry\:arcane_workbench.apply=Apply
container.ebwizardry\:arcane_workbench.mana=Mana\: container.ebwizardry\:arcane_workbench.mana=Mana\:
@@ -498,6 +498,13 @@ advancement.ebwizardry\:enchant_scroll.desc=Craft a blank scroll and enchant it
handbook.toast.title=New Handbook Section Unlocked! handbook.toast.title=New Handbook Section Unlocked!
gui.ebwizardry\:spell_book.tier=Tier: %s
gui.ebwizardry\:spell_book.element=Element: %s
gui.ebwizardry\:spell_book.element_undiscovered=Element: ?
gui.ebwizardry\:spell_book.mana_cost=Mana Cost: %s
gui.ebwizardry\:spell_book.mana_cost_continuous=Mana Cost: %s/second
gui.ebwizardry\:spell_book.mana_cost_undiscovered=Mana Cost: ?
container.ebwizardry\:arcane_workbench=Arcane Workbench container.ebwizardry\:arcane_workbench=Arcane Workbench
container.ebwizardry\:arcane_workbench.apply=Apply container.ebwizardry\:arcane_workbench.apply=Apply
container.ebwizardry\:arcane_workbench.mana=Mana\: container.ebwizardry\:arcane_workbench.mana=Mana\:
File diff suppressed because it is too large Load Diff
@@ -10,7 +10,7 @@
{ {
"type": "loot_table", "type": "loot_table",
"name": "ebwizardry:subsets/arcane_tomes", "name": "ebwizardry:subsets/arcane_tomes",
"weight": 3 "weight": 4
}, },
{ {
"type": "loot_table", "type": "loot_table",
@@ -31,7 +31,7 @@
{ {
"type": "loot_table", "type": "loot_table",
"name": "ebwizardry:subsets/arcane_tomes", "name": "ebwizardry:subsets/arcane_tomes",
"weight": 6 "weight": 8
}, },
{ {
"type": "loot_table", "type": "loot_table",
@@ -20,7 +20,7 @@
{ {
"type": "loot_table", "type": "loot_table",
"name": "ebwizardry:subsets/arcane_tomes", "name": "ebwizardry:subsets/arcane_tomes",
"weight": 4 "weight": 5
}, },
{ {
"type": "loot_table", "type": "loot_table",
@@ -8,7 +8,7 @@
"type": "item", "type": "item",
"entryName": "apprentice_tome", "entryName": "apprentice_tome",
"name": "ebwizardry:arcane_tome", "name": "ebwizardry:arcane_tome",
"weight": 3, "weight": 4,
"functions": [ "functions": [
{ {
"function": "set_data", "function": "set_data",
@@ -1,5 +1,5 @@
{ {
"bookmark_start_section": "introduccion", "bookmark_start_section": "introduction",
"colours": { "colours": {
"text": "#000000", "text": "#000000",
@@ -0,0 +1,750 @@
{
"bookmark_start_section": "introduction",
"colours": {
"text": "#000000",
"caption": "#666666",
"hyperlink": "#601ba0",
"highlight": "#dd4c1d",
"new_section": "#ee88f7"
},
"images": {
"workbench": {
"location": "ebwizardry:textures/gui/arcane_workbench_picture.png",
"caption": "法術工作台",
"u": 0,
"v": 0,
"width": 110,
"height": 110
},
"crystal_ore": {
"location": "ebwizardry:textures/gui/ore_picture.png",
"caption": "水晶礦",
"u": 0,
"v": 0,
"width": 64,
"height": 64
},
"magic_crystal": {
"location": "ebwizardry:textures/items/crystal_magic.png",
"caption": "魔法水晶",
"u": 6,
"v": 6,
"width": 36,
"height": 33,
"texture_width": 48,
"texture_height": 48,
"border": false
},
"magic_wand": {
"location": "ebwizardry:textures/items/wand_novice.png",
"caption": "法杖",
"u": 0,
"v": 0,
"width": 64,
"height": 64,
"border": false
},
"crystal_flower": {
"location": "ebwizardry:textures/gui/flower_picture.png",
"caption": "水晶花",
"u": 0,
"v": 0,
"width": 48,
"height": 48
},
"wizard_tower": {
"location": "ebwizardry:textures/gui/tower_picture.png",
"caption": "法師塔",
"u": 0,
"v": 0,
"width": 110,
"height": 110
},
"wizard_armour": {
"location": "ebwizardry:textures/gui/armour_picture.png",
"caption": "法師服",
"u": 0,
"v": 0,
"width": 90,
"height": 90
},
"obelisk": {
"location": "ebwizardry:textures/gui/obelisk_picture.png",
"caption": "方尖碑",
"u": 0,
"v": 0,
"width": 110,
"height": 67
},
"shrine": {
"location": "ebwizardry:textures/gui/shrine_picture.png",
"caption": "神殿",
"u": 0,
"v": 0,
"width": 110,
"height": 67
},
"tiers": {
"location": "ebwizardry:textures/gui/tiers_picture.png",
"caption": "四種等級的法杖",
"u": 0,
"v": 0,
"width": 96,
"height": 24,
"border": false
},
"elements": {
"location": "ebwizardry:textures/gui/elements_picture.png",
"caption": "七種法術元素",
"u": 0,
"v": 0,
"width": 106,
"height": 20,
"border": false
}
},
"recipes": {
"arcane_workbench": {
"locations": [ "ebwizardry:arcane_workbench" ]
},
"magic_wand": {
"locations": [ "ebwizardry:magic_wand" ]
},
"novice_wands": {
"locations": [
"ebwizardry:magic_wand",
"ebwizardry:wand_fire",
"ebwizardry:wand_ice",
"ebwizardry:wand_lightning",
"ebwizardry:wand_necromancy",
"ebwizardry:wand_earth",
"ebwizardry:wand_sorcery",
"ebwizardry:wand_healing"
]
},
"magic_missile_spell_book": {
"locations": [ "ebwizardry:magic_missile_spell_book" ]
},
"wizard_handbook": {
"locations": [ "ebwizardry:wizard_handbook" ]
},
"crystal_flower_to_crystals": {
"locations": [ "ebwizardry:crystal_flower_to_crystals" ]
},
"crystal_blocks": {
"locations": [
"ebwizardry:crystal_block",
"ebwizardry:crystal_block_fire",
"ebwizardry:crystal_block_ice",
"ebwizardry:crystal_block_lightning",
"ebwizardry:crystal_block_necromancy",
"ebwizardry:crystal_block_earth",
"ebwizardry:crystal_block_sorcery",
"ebwizardry:crystal_block_healing"
]
},
"crystal_blocks_to_crystals": {
"locations": [
"ebwizardry:crystal_block_to_crystals",
"ebwizardry:crystal_block_to_crystals_fire",
"ebwizardry:crystal_block_to_crystals_ice",
"ebwizardry:crystal_block_to_crystals_lightning",
"ebwizardry:crystal_block_to_crystals_necromancy",
"ebwizardry:crystal_block_to_crystals_earth",
"ebwizardry:crystal_block_to_crystals_sorcery",
"ebwizardry:crystal_block_to_crystals_healing"
]
},
"crystal_shard": {
"locations": [ "ebwizardry:crystal_shard" ]
},
"small_mana_flask": {
"locations": [ "ebwizardry:small_mana_flask" ]
},
"medium_mana_flask": {
"locations": [ "ebwizardry:medium_mana_flask" ]
},
"large_mana_flask": {
"locations": [ "ebwizardry:large_mana_flask" ]
},
"runestone": {
"locations": [
"ebwizardry:runestone_fire",
"ebwizardry:runestone_ice",
"ebwizardry:runestone_lightning",
"ebwizardry:runestone_necromancy",
"ebwizardry:runestone_earth",
"ebwizardry:runestone_sorcery",
"ebwizardry:runestone_healing"
]
},
"runestone_pedestal": {
"locations": [
"ebwizardry:runestone_pedestal_fire",
"ebwizardry:runestone_pedestal_ice",
"ebwizardry:runestone_pedestal_lightning",
"ebwizardry:runestone_pedestal_necromancy",
"ebwizardry:runestone_pedestal_earth",
"ebwizardry:runestone_pedestal_sorcery",
"ebwizardry:runestone_pedestal_healing"
]
},
"transportation_stone": {
"locations": [ "ebwizardry:transportation_stone" ]
},
"magic_silk": {
"locations": [ "ebwizardry:magic_silk" ]
},
"wizard_hat": {
"locations": [ "ebwizardry:wizard_hat" ]
},
"wizard_robe": {
"locations": [ "ebwizardry:wizard_robe" ]
},
"wizard_leggings": {
"locations": [ "ebwizardry:wizard_leggings" ]
},
"wizard_boots": {
"locations": [ "ebwizardry:wizard_boots" ]
},
"blank_scroll": {
"locations": [ "ebwizardry:blank_scroll" ]
},
"firebomb": {
"locations": [ "ebwizardry:firebomb" ]
},
"poison_bomb": {
"locations": [ "ebwizardry:poison_bomb" ]
},
"smoke_bomb": {
"locations": [ "ebwizardry:smoke_bomb" ]
},
"spark_bomb": {
"locations": [ "ebwizardry:spark_bomb" ]
}
},
"sections": {
"inside_cover": {
"centre": {
"x": true,
"y": true
},
"text": [
"法師手冊",
"作者: Electroblob\n\n翻譯: Grant"
]
},
"introduction": {
"title": "前言",
"text": [
"你好啊,法師!\n\n本書介紹許多法術相關事物及使用方式。 這不是一本普通的書,其內容會隨著你在魔法世界的探索而逐漸呈現。",
"使用箭頭按鈕來翻頁,按下雙箭頭按鈕則可快速的切換章節,而中間的選單按鈕則是翻回主目錄頁面。",
"點擊任何紫色連結文字直接跳至相關頁面。對書籤點擊滑鼠右鍵可將書籤移到目前這頁,對書籤點擊滑鼠左鍵則可翻回書籤那頁。"
]
},
"main_contents": {
"title": "目錄",
"contents": {
"id": "main_contents",
"hyperlinks": true,
"page_numbers": true,
"separator": "."
}
},
"setting_up": {
"title": "準備",
"include_in_contents": "main_contents",
"text": [
"要開始使用法術,你需要準備:",
"》法杖, 請依圖示合成:",
"#recipe magic_wand",
"\n\n》@arcane_workbench 法術工作台@ 合成方式如圖:",
"#recipe arcane_workbench",
"》@spells 法術書@\n這個可以在箱子裡找到,或從怪物身上掉落,或向法師購買。\n\n\n\n不然你也可以自己合成一個\n初學者法術【魔法彈】,\n如圖所示:",
"#recipe magic_missile_spell_book",
"你還需要準備一大堆魔法水晶\n來為法杖供應@mana 法力@。"
]
},
"mana": {
"title": "法力",
"include_in_contents": "main_contents",
"triggers": [
"ebwizardry:crystal"
],
"text": [
"法力是賦予法師力量的魔法能量,其本身並非實體的物質,反而是可滲入於萬物之中的永恆能量。特別的是,法力蘊藏在於地下岩石中所找到的天然水晶內。\n@wands 法杖@可儲存法力,並在施法時\n將法力引導到@spells 法術@上。\n不同的法術會依其力量強度及持續時間消耗不同的法力值。",
"#image crystal_ore",
"#image magic_crystal",
"人們普遍認為法力無法被創造或消滅,每當施展法術時,其引導的法力就會散失到周圍環境中。事實上這就是大量的法力散布於世界各處的原因。總之無論要如何使用法力,必須從地底下的天然千年水晶中,或本書未涵蓋的高級人工方式將其收集。還有各種方法使法術更有效的使用法力,以及回收在施法過程中逸散的部分法力。"
]
},
"wands": {
"title": "法杖",
"include_in_contents": "main_contents",
"triggers": [
"ebwizardry:arcane_initiate"
],
"text": [
"法杖是法師首選的器具。\n你能用它來施展任何法杖能力\n所及的@spells 法術@(請參閱@tiers 等級@章節)\n。\n法杖的種類很多,不過當然都得從基礎法杖開始。",
"#image magic_wand",
"大多數的法杖都誕生於一個簡單的製作方式。\n準備一顆某種類型的魔法水晶,\n將水晶裝在木棒的一端,\n再於另一端黏上一顆金粒。\n水晶自然是法杖力量的源頭,\n因為它提供了引導@spells 法術@所需的\n焦點。而其餘的部分也很重要,不只是因為提供了握住法杖的地方,更是指引@mana 法力@前進的路徑\n。",
"隨著法杖施展了愈多法術,\n其變得愈能駕馭@spells 法術@,\n因此也能施展更強大的法術。\n這樣的成長可以從法杖外觀上的細微變化中發現,隨著法杖愈來愈強,水晶會變得更加明亮,\n顏色也可能會根據其@elements 元素@而\n產生變化。過了一段時間之後,法杖本身的木材也會開始扭曲生長成各種複雜的形狀。",
"當你拿著法杖時,畫面的角落會顯示出目前法杖所選的法術及其圖示,而在施放法術之後,還會顯示冷卻條來表示直到下次施展所需等待的時間,它還會顯示法杖中的前一個和下一個法術名稱。按下《#next_spell_key 鍵》及《#previous_spell_key 鍵》可切換法術(這些都可在【選項】->【按鍵設定】中變更),你也可以在潛行時使用滑鼠滾輪來切換法術。",
"當你將游標停留在物品欄的法杖上時,會顯示法杖中儲存的\n@mana 法力@,伴隨目前所選的@spells 法術@及其\n特殊能力。\n將法杖放入@arcane_workbench 法術工作台@則可\n看見更詳細的資訊。"
]
},
"spells": {
"title": "法術",
"include_in_contents": "main_contents",
"triggers": [
"ebwizardry:handbook/spells"
],
"text": [
"沒有法術的@wands 法杖@沒有作用。\n法術的記錄形式有兩種:\n一種是永久性的書本,\n一種是暫時性的卷軸。",
"法術書本身無法使用,而是用於將書中記載的法術存入@wands 法杖@。\n在世界各地都能發現法術書,應該用不了多少時間你就能找到一本。當你找到後,可將游標停留在書上,看一下這本法術書的基本資訊,也可以拿著書點擊滑鼠右鍵以閱讀更詳細的資料。",
"相對而言卷軸則有不同的用途: 拿著卷軸點擊滑鼠右鍵便會施展上面的法術並用掉卷軸。跟法術書一樣,卷軸在世界各地都能找到,但你也可以自己@enchanting_scrolls 製作@。",
"在你準備進行某個任務時,有些法術可能只會用到一兩次,\n所以你不想讓那些法術占用\n你的@wands 法杖@空間,此時卷軸就非常\n有用。不過得注意,比起法杖,卷軸還是效率較差的施法方式。",
"未經訓練的眼睛無法閱讀法術中的魔法符文。然而若要鑑定一個法術,你當然可以冒著發生意外的風險來施展看看結果,但即便如此許多法術是要在特定的條件下才會發生作用。不過即便如此,還是有可能在施法時誤用了未鑑定的法術,其潛在的危險性取決於這個法術有多強大。因此更安全可靠的選擇是使用鑑定卷軸,可以在箱子裡找到或是向法師購買。拿著鑑定卷軸點擊滑鼠右鍵便會用掉卷軸並鑑定你快捷欄中第一個未知的法術書或卷軸。"
]
},
"arcane_workbench": {
"title": "法術工作台",
"include_in_contents": "main_contents",
"contents": {
"id": "arcane_workbench_subsections",
"hyperlinks": true,
"page_numbers": true,
"separator": "."
},
"triggers": [
"ebwizardry:handbook/arcane_workbench"
],
"text": [
"法術工作台看起來有點像附魔台, 用來升級你的@wands 法杖@、\n為其補充法力和存入@spells 法術@。\n\n其合成方式如下:",
"#recipe arcane_workbench",
"接下來的頁面將說明法術工作台的各種功用。",
"#image workbench"
],
"sections": {
"binding_spells": {
"title": "抄寫法術",
"include_in_contents": "arcane_workbench_subsections",
"triggers": [
"ebwizardry:handbook/arcane_workbench"
],
"text": [
"要將@spells 法術@存入你的@wands 法杖@,只要將\n法杖放入工作台中央的槽中,然後將法術書放入周圍其中一個槽並按下按鈕。此時你會注意到,在這個過程中,法術書並沒有受到任何影響,這是因為存入法術的動作,並不是將法術從法術書中取走,只是將法術抄寫至法杖中而已。因此你可以重複這個動作,盡量將想要的法術存入你的法杖。你一次最多只能存入五種法術到法杖中,不過可用協調升級來增加法術存量。"
]
},
"charging_wands": {
"title": "法杖補充法力",
"include_in_contents": "arcane_workbench_subsections",
"triggers": [
"ebwizardry:handbook/arcane_workbench"
],
"text": [
"要幫@wands 法杖@補充法力,先將法杖\n放入法術工作台中央的槽,並在左下方那個槽放入魔法水晶,然後按下按鈕。\n每個水晶相當於#mana_per_crystal點的@mana 法力@,\n而法杖只會在需要時用掉水晶,因此你可以將水晶留在工作台內,以便需要時供應。但是請記得,法杖只能取用整數單位的水晶,舉例來說,如果法杖只需要30點法力,那補充法力時會有#example_charging_loss點法力浪費掉。"
]
},
"upgrading_wands": {
"title": "升級法杖",
"include_in_contents": "arcane_workbench_subsections",
"triggers": [
"ebwizardry:handbook/tome_of_arcana"
],
"text": [
"你需要對應@tiers 等級@的法術寶典來\n升級你的@wands 法杖@或進行特殊的法\n杖升級。這兩種東西都可從怪物的掉落物或向法師購買獲得。要升級法杖,先將法杖放入法術工作台中央的槽,並在右上方的槽放入升級物後按下按鈕。",
"特殊的法杖升級可加強法杖某方面的能力,每種升級最高只能疊加三次,而法杖的總升級數取決於法杖的等級。升級後就無法移除。"
]
},
"enchanting_scrolls": {
"title": "製作卷軸",
"include_in_contents": "arcane_workbench_subsections",
"triggers": [
"ebwizardry:handbook/scrolls"
],
"text": [
"法術工作台也能用來將@spells 法術@\n存入卷軸。要製作卷軸,你需要先用一張紙及一些線來合成空白卷軸,然後選一本想要作成卷軸的法術書,最後準備足夠的魔法水晶以提供施展這個法術的@mana 法力@。",
"#recipe blank_scroll",
"先將水晶放入左下方的槽,再將空白卷軸放入中央的槽,然後將法術書放入上方單獨的槽,最後按下按鈕以製成法術卷軸。"
]
}
}
},
"wizard_armour": {
"title": "法師服",
"include_in_contents": "main_contents",
"triggers": [
"ebwizardry:arcane_initiate"
],
"text": [
"身為一位法師,在與生物搏鬥時需要一些東西來保護自己。雖然也能使用一般的護甲,但是為了充分發揮你的法術,你還是需要一套法師服,包括帽子、長袍、褲子和鞋子。\n與一般護甲不同的是,法師服不會破損,其使用魔法能量來保護穿著的人。因此跟法杖一樣,需要魔法水晶來補充能量。不過幸好這些服裝不會消耗太多\n@mana 法力@。\n法師服補充能量的方式也跟法杖一樣,可以用@arcane_workbench 法術工作台@或\n@mana_flasks 法力瓶@來補充,但是必須當心,\n如果法師服的法力耗盡了,你會發現自己毫無防禦力。",
"#image wizard_armour",
"你可以用魔法絲綢來製成法師服:",
"#recipe magic_silk",
"#recipe wizard_hat",
"#recipe wizard_robe",
"#recipe wizard_leggings",
"#recipe wizard_boots",
"使用一般的附魔台就能為法師服附魔,而且由於魔法絲綢本身的特性,附魔後的效果特別好。對一個法師而言,最有用的是魔法、冰凍及衝擊三種防護附魔,有助於對抗敵人的魔法攻擊。",
"有些專注於特定元素的法師會穿著能加強該元素力量的特殊服裝,這種整套的服裝法師們都相當喜歡,但也不容易找到。",
"傳說中最強的法師曾經用一種法術印記來大大強化他們的服裝。"
]
},
"magical_world": {
"title": "魔法世界",
"include_in_contents": "main_contents",
"contents": {
"id": "magical_world_subsections",
"hyperlinks": true,
"page_numbers": true,
"separator": "."
},
"triggers": [
"ebwizardry:handbook/on_subsection_unlock"
],
"text": [
"只是待在家裡是無法成為法術大師的,到外頭探索充滿魔法的世界吧!\n若你勇於挑戰,古代遺址、遺物以及不管好的或壞的神秘生物,都等著你發現。\n最偉大的法師同時也最具好奇心,他們會不斷的探索周遭環境,並嘗試所發現的東西,來獲得豐富的知識及強大的力量。",
"雖然法師不免大多的時間都是孤身一人,但知識的分享也是學習魔法藝術重要的一環。找尋其他法師,盡可能從他們身上學習更多知識,溝通才是一切最大的力量。"
],
"sections": {
"crystal_flowers": {
"title": "水晶花",
"include_in_contents": "magical_world_subsections",
"triggers": [
"ebwizardry:handbook/crystal_flowers"
],
"text": [
"在你的旅途當中,可能在野外會不時遇到奇怪的發光花朵,這些獨特的花稱為水晶花,它們具有聚集@mana 法力@的神奇能力,至今還不\n知道原因。不過我們卻知道這些水晶花,可經由採集製作以提取法力成為水晶,這使它們成為地面上相當有用的法力來源。然而由於這種花並不大,而且生長的土地都很小塊,因此這種方式所能獲得的法力其實很有限。",
"#image crystal_flower",
"#recipe crystal_flower_to_crystals"
]
},
"wizard_towers": {
"title": "法師塔",
"include_in_contents": "magical_world_subsections",
"triggers": [
"ebwizardry:wizard_tower"
],
"text": [
"害怕嗎?你並不是這個世界上唯一會使用魔法的人。\n在你的旅途中,你可能會遇到具有獨特尖頂或雙尖頂的高塔,這些是法師同伴居住的地方。\n隱居的生活使法師們有時候會有點古怪,但是他們通常還是友善的,而且只要你願意付出代價,還是會樂意與你分享他們的知識。\n在支付了貴重金屬及寶石後,你會收到許多驚奇的法術作為回報。",
"如果你想尋找的是@tiers 大師級@法術,\n那你得跟專門的人交談。",
"#image wizard_tower",
"不幸的是,有少數法師並不歡迎訪客。這些法師通常已被驅逐,所以對於任何闖入地盤的人都充滿敵意。\n接近這些傢伙要特別小心,並做好抵擋強大魔法的準備。只要擊敗他們,他們的知識就會成為你的了。",
"有一點必須知道,沒有法師會接受對他們攻擊或盜取他們東西的人,他們肯定不會善罷甘休。"
]
},
"obelisks": {
"title": "方尖碑",
"include_in_contents": "magical_world_subsections",
"triggers": [
"ebwizardry:handbook/obelisks"
],
"text": [
"古老魔法的遺跡散落在世界各處,其中最著名的是刻有許多符號及符文的石頭結構。這些廢墟看起來像是某種古代文明的遺跡,無論建造它們的是誰或是什麼,顯然具有相當豐富的魔法知識,且用來在這些地方設置持續至今的防衛魔法。",
"這些結構大致上分成兩種類型,第一種是較常見的方尖碑:\n以雕刻符文石堆成高高尖頂的結構,底部開著一塊空間,存放著過去所遺留的次等魔法物品。",
"#image obelisk",
"這些結構通常受到魔法保護,一旦有人靠近就會召喚出充滿敵意的@creatures 魔法生物@來攻擊人類。\n對抗這些生物並摧毀其魔法源頭,那些遺物就是你的了。"
]
},
"shrines": {
"title": "神殿",
"include_in_contents": "magical_world_subsections",
"triggers": [
"ebwizardry:visit_shrine"
],
"text": [
"第二種較為罕見的結構稱之為神殿,由一個中央基座及圍繞在四周的符文石柱所組成。基座上方擺著一個裝有古代@artefacts 神器@的\n寶箱,並通常施加了防護魔法鎖,以防他人竊取。整個結構還受到封鎖力場保護,使擅闖者無法逃離。",
"#image shrine",
"由於這些神殿的重要意義及巨大的神秘力量,更別說裡面的寶物,對於志氣高昂的法師特別有吸引力。\n\n但是務必謹慎,有許多關於法師被關在封鎖區內,可能因為幽閉恐懼症導致慢慢發瘋的報導。且愈來愈多人認為,這就是神殿防護魔法的一個部分,而被關在其中的法師,其實是被控制用來守護神殿。這對於膽敢前往冒險的人來說,無疑是令人不寒而慄的結局..."
]
},
"creatures": {
"title": "魔法生物",
"include_in_contents": "magical_world_subsections",
"triggers": [
"ebwizardry:handbook/magical_creatures"
],
"text": [
"除了法師,還有許多其它生物也會使用魔法。其中有許多是源自於魔法,且大部分都能用特定的@spells 法術@召喚。會看到這些生物,\n大多是在守護@obelisks 方尖碑@,但也可能\n遇到了強大的召喚法師。只有非常少數的神秘生物才會偶爾在野外發現。"
]
},
"artefacts": {
"title": "神器",
"include_in_contents": "magical_world_subsections",
"triggers": [
"ebwizardry:artefact"
],
"text": [
"在探索@shrines 神殿@時,你可能會好運的\n發現某種古代魔法神器,一種能夠賦予配戴者獨特而強大能力的物品。\n目前所知的類型有三種:\n為法術附加額外能力及效果的戒指,增強防禦力的項鍊,以及各種應用魔法的寶器。\n這些神器只是放入背包是沒有用的,要擺在身上的正確位置才會發生作用。"
]
}
}
},
"tiers": {
"title": "等級",
"include_in_contents": "main_contents",
"triggers": [
"ebwizardry:handbook/tome_of_arcana"
],
"text":[
"@wands 法杖@和@spells 法術@都分成四個等級: #colour_novice基礎#colour_reset、#colour_apprentice學徒#colour_reset、#colour_advanced進階#colour_reset以及#colour_master大師#colour_reset。每個等級都比前一級還強。",
"#image tiers",
"只有#colour_novice基礎#colour_reset法杖能以合成的方式製作,其最多可儲存#novice_max_charge點法力,且只能施展基礎法術。基礎法術通常不會消耗太多法力,任何人都足以施展。但這並不表示它們相較於高等法術就毫無用處。即便你已經能施展大師級法術,某些基礎法術由於消耗法力低而仍然實用。",
"#colour_apprentice學徒#colour_reset法杖是基礎法杖的下個等級,其最多可儲存#apprentice_max_charge點法力,並可施展基礎及學徒法術。學徒法術比基礎法術更強一些,但通常也消耗更多法力。",
"#colour_advanced進階#colour_reset法杖非常稀有也更加強大,可施展大師級以外的所有法術,並可儲存#advanced_max_charge點法力。進階法術能夠重創敵人,並擁有超人般的能力,例如隱身術。",
"#colour_master大師#colour_reset法杖是現存最強大的法杖,其最多可儲存#master_max_charge點法力,並可施展所有法術。大師級法術書相當罕見,且法術的威力能徹底毀滅的不僅是敵人,甚至包括整個世界。務必謹慎使用!",
"要提升至更高等級,首先法杖必須變得夠強大到足以引導該等級的法術。法杖會隨著施展法術而獲得成長,法術類型、法術力量、元素效果以及其它外部因素都可能會影響法杖的成長速度。",
"當法杖足夠強大,法術寶典為最終將法杖提升至下個等級的關鍵物品(請參閱@upgrading_wands 升級法杖@),\n一旦完成升級,法杖將再次朝下個等級開始成長。"
]
},
"elements": {
"title": "元素",
"include_in_contents": "main_contents",
"triggers": [
"ebwizardry:handbook/elements"
],
"text": [
"@spells 法術@各屬於不同的元素,代表\n法術的本質,且搭配使用對應的@wands 法杖@還會加強效果。",
"#image elements",
"#colour_fire火#colour_reset \n火元素涉及燃燒、岩漿以及爆炸,大概是最具破壞性的元素。一個強大的烈焰法師可使敵人面臨煉獄般的火海,並可能在過程中毀掉這個世界。\n大部分的火系法術會讓目標著火,使他們持續受到傷害,但是對地獄的生物則沒什麼效果。",
"#colour_ice冰#colour_reset \n冰元素來自於所有冰冷的物質。冰系法術通常會讓敵人減速,甚至使他們完全凍結,對於火系生物特別有效。\n冰凍魔法在戰鬥之外也很有用,例如使水面結冰以過河。",
"\n#colour_lightning電#colour_reset \n這個元素涉及雷電、風暴以及天氣。決不可小看一個強大雷電法師的力量,有些甚至能隨意召喚閃電。\n雷電法術經常能一次傷害多個敵人,還會自動搜尋目標,對任何生物都能造成有效的攻擊...但是得當心苦力怕。",
"#colour_necromancy死靈#colour_reset \n死靈是黑暗、渾沌以及不死生物的元素。神秘的死靈法師往往被視為邪惡,儘管通常不是這樣的。\n死靈法術常召喚@creatures 生物@來為他\n戰鬥,或進而扭曲敵人的意志。",
"#colour_earth大地#colour_reset \n大地元素來自於動植物、風等自然界的的力量。大地魔法千變萬化,從毒害敵人到控制天氣,有各式各樣的形式。\n大地法術是綜合攻擊、防禦以及實用的法術。",
"#colour_sorcery秘術#colour_reset \n秘術是力量與變化的元素。\n秘術法師能操縱光線、重力,甚至現實世界本身來符合他們的需求。\n且不提其它用途,秘術法術可用來提供施法者魔法力量,或是任意移動物體。",
"#colour_healing治療#colour_reset \n治療元素包括防禦和再生。\n治療法師會盡可能的保護自己及他們的同伴,因此可能會是非常難以對付的對手。\n治療法術在戰鬥中是不可或缺的,即便其通常不會用來進行攻擊,但是一些治療法術的淨化光芒會對不死生物造成相當大的傷害。",
"不同元素之間的分界並不總是那麼明確,有些法術除了所屬元素的性質外,也會具有其它元素的特性。",
"幸運的話,或許你能發現一種元素水晶,這是種在生長過程中吸收了元素的魔法水晶,不過實際上發生的方式及所需的條件仍然是個謎。但我們知道這種水晶能用來製作元素法杖,用來施展對應的法術,可比平常發揮更大的效果。"
]
},
"miscellaneous": {
"title": "其它",
"include_in_contents": "main_contents",
"contents": {
"id": "miscellaneous_subsections",
"hyperlinks": true,
"page_numbers": true,
"separator": "."
},
"triggers": [
"ebwizardry:on_subsection_unlock"
],
"sections": {
"mana_flasks": {
"title": "法力瓶",
"include_in_contents": "miscellaneous_subsections",
"triggers": [
"ebwizardry:handbook/mana_flasks"
],
"text": [
"亞肯多魔法用品公司 - 為您所需的魔法物品!",
"需要在旅行中為你的@wands 法杖@補充\n法力嗎?\n沒問題! 現在@mana 法力@可以裝瓶。\n只要用一個玻璃瓶及八個魔法水晶合成出法力瓶,就可以隨身攜帶。要用的時候,只要將你的法杖與法力瓶合成,就能將法力存入法杖。(註)",
"#recipe medium_mana_flask",
"好消息! 即日起推出全新的小瓶裝及大瓶裝法力,可依您的需求選擇!",
"#recipe small_mana_flask",
"#recipe large_mana_flask",
"(註)過程中瓶子會用掉,且裝瓶時也會耗損一些法力。"
]
},
"throwable_items": {
"title": "投擲物",
"include_in_contents": "miscellaneous_subsections",
"triggers": [
"ebwizardry:handbook/throwables"
],
"text": [
"各種@spells 法術@的實體物,像是\n火焰彈、毒液彈、煙霧彈,還有電擊彈都能直接合成:",
"#recipe firebomb",
"#recipe poison_bomb",
"#recipe smoke_bomb",
"#recipe spark_bomb"
]
},
"automated_casting": {
"title": "自動施法",
"include_in_contents": "miscellaneous_subsections",
"triggers": [
"ebwizardry:enchant_scroll"
],
"text": [
"近期的實驗顯示,在某種程度上只需要簡單的發射器就能自動施展@spells 法術@。沒有人知道原因,\n但看起來似乎是紅石的神奇特性竟然能觸發法術卷軸。只要將一些卷軸放入發射器,然後提供能量,就完成了這個機關..."
]
}
}
},
"crafting_recipes": {
"title": "合成表",
"include_in_contents": "main_contents",
"text": [
"#recipe arcane_workbench",
"#recipe novice_wands",
"#recipe magic_missile_spell_book",
"#recipe wizard_handbook",
"#recipe crystal_flower_to_crystals",
"#recipe crystal_blocks",
"#recipe crystal_blocks_to_crystals",
"#recipe crystal_shard",
"#recipe small_mana_flask",
"#recipe medium_mana_flask",
"#recipe large_mana_flask",
"#recipe runestone",
"#recipe runestone_pedestal",
"#recipe transportation_stone",
"#recipe magic_silk",
"#recipe wizard_hat",
"#recipe wizard_robe",
"#recipe wizard_leggings",
"#recipe wizard_boots",
"#recipe blank_scroll",
"#recipe firebomb",
"#recipe poison_bomb",
"#recipe smoke_bomb",
"#recipe spark_bomb"
]
},
"credits": {
"title": "製作群",
"include_in_contents": "main_contents",
"text": [
"法術模組\n版本 #version\n支援 Minecraft #mcversion",
"設計、程式及材質: Electroblob",
"感謝 Minecraft Forge 及 MCP\n沒有它們就沒有這個模組。",
"也感謝Minecraft的模組討論區,\n總能回答我的模組問題!",
"\n另外,我要感謝以下各位對本模組的貢獻:",
"程式碼:",
"》Corail31 \n》12foo \n》Shadows-of-Fire \n》HellFirePvP \n》Tora-B \n》Avatair \n》Aeronica",
"\n\n翻譯:",
"》繁體中文: Grant\n》(墨西哥)西班牙文: MadWrist \n》俄文: VilagVil, kellixon\n》法文: Hahdrim\n》巴西葡萄牙文: lorrampi\n》簡體中文: ZHENGLOC, dragon-evol\n》韓文: shejery, rewi_wire\n》波蘭文: Trozuu",
"雷電音效: OhhWowProductions",
"更多資訊請前往 @https://github.com/Electroblob77/Wizardry/wiki wiki@",
"覺得法術模組還有不足之處? 請加入 @https://discord.gg/MTmMzMv Discord 伺服器@以獲得\n最新消息、討論及額外事務!"
]
}
}
}
+2 -2
View File
@@ -2,10 +2,10 @@
{ {
"modid" : "ebwizardry", "modid" : "ebwizardry",
"name" : "Electroblob's Wizardry", "name" : "Electroblob's Wizardry",
"version" : "4.2.9", "version" : "4.2.10",
"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, UltraHex, Azim-Palmer, raoulvdberge.\nTranslators: MadWrist (Spanish, Mexican Spanish), VilagVil, kellixon & bigenergy (Russian), Hahdrim (French), lorrampi (Brazilian Portuguese), ZHENGLOC & dragon-evol (Chinese), shejery & rewi_wire (Korean), Trozuu (Polish).", "credits" : "\nDesigned, coded and textured by Electroblob.\nCode contributed by: Corail31, 12foo, Shadows-of-Fire, Tora-B, Avatair, Aeronica, UltraHex, Azim-Palmer, raoulvdberge.\nTranslators: MadWrist (Spanish, Mexican Spanish), VilagVil, kellixon & bigenergy (Russian), Hahdrim (French), lorrampi (Brazilian Portuguese), ZHENGLOC & dragon-evol (Chinese), shejery & rewi_wire (Korean), Trozuu (Polish), chesterccj305 (Taiwanese).",
"authorList" : [ "authorList" : [
"Electroblob" "Electroblob"
], ],