Compare commits
102 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f9f6b34549 | |||
| bee7e51d06 | |||
| 51a2ff0976 | |||
| 1b298ff18b | |||
| 86d13d3a6e | |||
| 5421372754 | |||
| 53b29939f1 | |||
| 7bda8db86f | |||
| a7a48cd32b | |||
| b8e0836a6d | |||
| a7e6b2892c | |||
| f886ebfd75 | |||
| 98b334e6d7 | |||
| 83edb8007e | |||
| 67dda448f3 | |||
| 09953c0299 | |||
| 38b0fa65bc | |||
| 7200182c82 | |||
| e73e998de2 | |||
| a69da2eb2a | |||
| a00c594d83 | |||
| 3df99552e1 | |||
| e2bc2824f6 | |||
| 36f4728f3a | |||
| 6ca72e7965 | |||
| 151dcc06da | |||
| 5737109dec | |||
| 4bd3a46f32 | |||
| 73e2d64fcd | |||
| 1f008b405d | |||
| 00e1e2602f | |||
| 98445da971 | |||
| dbc1490e10 | |||
| f33a0aceb2 | |||
| 7141ae9544 | |||
| af638ab2f7 | |||
| a75a6c6114 | |||
| 9c1042f686 | |||
| cad3fee1b9 | |||
| 5947b2ee62 | |||
| 177a39bad1 | |||
| cdf8f6e32d | |||
| f88aac11e9 | |||
| 05b905b988 | |||
| 669cd2892d | |||
| dd07d08ff0 | |||
| 54bb327fdf | |||
| 2cd8b46c1f | |||
| b61413f7f1 | |||
| 4e7765a7e7 | |||
| 49a6dc43c1 | |||
| b82bc6698f | |||
| 1e43c67660 | |||
| c129571167 | |||
| b23a643c0e | |||
| 194bff3e6a | |||
| 426ca78288 | |||
| f15919fdce | |||
| 2124842136 | |||
| 70e697876b | |||
| 9b5e5a871c | |||
| 5ba92e5de5 | |||
| 4e6780a3cf | |||
| 00584ad635 | |||
| f72ed33515 | |||
| c2366ed1ba | |||
| 46df8d7311 | |||
| d4579b9184 | |||
| ee6f0cfe70 | |||
| 6155fd9c68 | |||
| 32c0608b51 | |||
| 404df6af23 | |||
| 764e10538b | |||
| 6b1b590e30 | |||
| 8360e520cd | |||
| 005a17d750 | |||
| 28abe036a0 | |||
| ca96112b67 | |||
| b8e847c6a6 | |||
| 35cb2c31fc | |||
| 30dd587d34 | |||
| 4644814582 | |||
| 7db3151d8a | |||
| c8ca73cca9 | |||
| d5a0479ebe | |||
| 339ec69a72 | |||
| b2cb717aa3 | |||
| cf4a02f37f | |||
| 84304dd7ce | |||
| e3b44eb194 | |||
| 2cbb0a590f | |||
| 6b9c864890 | |||
| c15a0763d5 | |||
| 4a23d88f30 | |||
| 286705c79b | |||
| 3895f5c531 | |||
| c51e0bd218 | |||
| 766570aeb2 | |||
| 4e91b0d19d | |||
| 65f7630546 | |||
| 8cf7572041 | |||
| db057a5ca9 |
@@ -21,4 +21,5 @@ build
|
||||
eclipse
|
||||
run
|
||||
misc
|
||||
libs
|
||||
Thumbs.db
|
||||
+6
-2
@@ -1,8 +1,8 @@
|
||||
# Credits
|
||||
|
||||
Electroblob's Wizardry
|
||||
Version 3.1.0
|
||||
For Minecraft 1.11.2
|
||||
Version 4.1.4
|
||||
For Minecraft 1.12.2
|
||||
|
||||
Designed, coded and textured by Electroblob
|
||||
|
||||
@@ -15,10 +15,14 @@ In addition, I'd like to thank the following individuals for their contributions
|
||||
#### Code
|
||||
|
||||
- Corail31
|
||||
- 12foo
|
||||
- Shadows-of-Fire
|
||||
- HellFirePvP
|
||||
|
||||
#### Translations
|
||||
|
||||
- Russian: VilagVil
|
||||
- Spanish and Mexican Spanish: MadWrist
|
||||
- Chinese: ZHENGLOC and dragon-evol
|
||||
|
||||
Lightning ray sound effect from OhhWowProductions
|
||||
|
||||
+4
-2
@@ -1,5 +1,7 @@
|
||||
Minecraft version: 1.10.2 [change as necessary]
|
||||
Wizardry version: 2.1.0 [change as necessary]
|
||||
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.1.4 [change as necessary]
|
||||
Environment: Singleplayer/LAN game/Server [delete as necessary]
|
||||
|
||||
Issue details: [describe what you were doing when the issue occurred, what went wrong, what you expected to happen, etc.]
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
# License
|
||||
This repository is copyright © Electroblob 2018. The following license is provided to allow you to creatively contribute to and improve the repository.
|
||||
|
||||
This license applies only to the source code and assets present in this repository. The compiled mod (available at https://minecraft.curseforge.com/projects/electroblobs-wizardry) comes under its own separate license, see the aforementioned webpage for details.
|
||||
This license applies only to the source code, assets and wiki pages present in this repository. The compiled mod (available at https://minecraft.curseforge.com/projects/electroblobs-wizardry) comes under its own separate license, see the aforementioned webpage for details.
|
||||
|
||||
TL;DR: Do what you want with this repo on Github, but ask me first if you want to put it anywhere else or publish your version. Don't try and make money off the repo or anything in it. I'm not responsible if the code breaks things, and if you help me out by submitting a PR, I can use and modify the contents of that PR as long as I give you credit. (This brief summary is non-binding and does not override or replace the full license below.)
|
||||
|
||||
@@ -17,7 +17,7 @@ TL;DR: Do what you want with this repo on Github, but ask me first if you want t
|
||||
|
||||
'Electroblob's Wizardry', 'Wizardry', 'the mod' - The Minecraft modification Electroblob's Wizardry
|
||||
|
||||
'Repository' - This repository on Github, containing this license, other informational files, configurations, code and assets which are part of Electroblob's Wizardry
|
||||
'Repository' - This repository on Github, containing this license, the wiki, other informational files, configurations, code and assets which are part of Electroblob's Wizardry
|
||||
|
||||
'Curseforge' - The webpage https://minecraft.curseforge.com/projects/electroblobs-wizardry
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||

|
||||
|
||||
Source code for Electroblob's Wizardry, a Minecraft mod currently for versions 1.7.10, 1.10.2 and 1.11.2. Wizardry adds an RPG-style system of magic spells to Minecraft with the aim of being as playable as possible. No crazy constructs, no perk trees, no complex recipes - simply find spell books, cast spells, and master the arcane!
|
||||
Source code for Electroblob's Wizardry, a Minecraft mod currently for versions 1.7.10, 1.10.2, 1.11.2, and 1.12.2. Wizardry adds an RPG-style system of magic spells to Minecraft with the aim of being as playable as possible. No crazy constructs, no perk trees, no complex recipes - simply find spell books, cast spells, and master the arcane!
|
||||
|
||||
Please read the [guide for contributing](guide_for_contributing.md) before submitting an issue or a PR.
|
||||
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ apply plugin: 'net.minecraftforge.gradle.forge'
|
||||
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
|
||||
|
||||
|
||||
version = " 4.1.0 - MC 1.12.2"
|
||||
version = " 4.1.4 - MC 1.12.2"
|
||||
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
archivesBaseName = "Electroblob's Wizardry "
|
||||
|
||||
@@ -29,7 +29,7 @@ minecraft {
|
||||
// stable_# stables are built at the discretion of the MCP team.
|
||||
// Use non-default mappings at your own risk. they may not always work.
|
||||
// simply re-run your setup task after changing the mappings to update your workspace.
|
||||
mappings = "snapshot_20180316"
|
||||
mappings = "stable_39"
|
||||
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,20 @@
|
||||
|
||||
## Submitting an issue
|
||||
|
||||
When submitting an issue, please stick to the issue template. 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! Most importantly, use gist or pastebin to post crash reports.
|
||||
When submitting an issue, I would be grateful if you could follow these few guidelines:
|
||||
|
||||
- First and foremost, please check your issue hasn't already been posted. The issue tracker is searchable, so try typing in a few keywords and see if anything comes up.
|
||||
|
||||
- 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 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!
|
||||
|
||||
- There's no need to put 'tags' in square brackets in the issue title, I'll put proper github issue tags on it which will also help organise it. You can use them to search for issues too!
|
||||
|
||||
- Don't close an issue unless it has actually been fixed or is no longer relevant - otherwise I might not end up fixing it at all! Usually I'll take care of closing issues anyway, so you don't have to worry about it.
|
||||
|
||||
- Most importantly, use gist or pastebin to post crash reports. Do not paste the entire crash report inline, not even in a code block!
|
||||
> If you've got a git account (which you do, if you're posting an issue) you can access gist, and pastebin doesn't require an account at all, so there's no excuse!
|
||||
|
||||
## Submitting a PR
|
||||
|
||||
|
||||
@@ -143,8 +143,9 @@ public class CommonProxy {
|
||||
|
||||
// I have now learnt that the server side I18n always translates to the default en_US, so I could just return
|
||||
// a hardcoded name in English instead.
|
||||
Wizardry.logger.info("A mod has called ItemScroll#getItemStackDisplayName from the server side. Using the"
|
||||
+ "deprecated server-side translation methods as a fallback.");
|
||||
// Commented because it's just really annoying.
|
||||
//Wizardry.logger.info("A mod has called ItemScroll#getItemStackDisplayName from the server side. Using the"
|
||||
// + "deprecated server-side translation methods as a fallback.");
|
||||
|
||||
// Displays [Empty slot] if spell is continuous.
|
||||
Spell spell = Spell.get(scroll.getItemDamage());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package electroblob.wizardry;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
@@ -45,9 +46,8 @@ import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
* @since Wizardry 1.2
|
||||
* @author Electroblob
|
||||
*/
|
||||
// NOTE: We could convert over to the @Config system IF it is sufficiently complete in this Forge version for my
|
||||
// purposes.
|
||||
// (For one, I know that the LangKey annotation is not applicable to type declarations in 1.10.2, unlike in 1.11.2)
|
||||
// TODO: New plan: convert to the @Config system BUT separate the spells config out so it doesn't break stuff. (Maybe even
|
||||
// make it a JSON instead? Either way, there's scope for then adding more options for adjusting the base attributes etc.)
|
||||
// @Config(modid = Wizardry.MODID)
|
||||
@SuppressWarnings("deprecation") // Used server I18n deliberately; we want to write the comments in english.
|
||||
public final class Settings {
|
||||
@@ -63,8 +63,8 @@ public final class Settings {
|
||||
public static final String COMMANDS_CATEGORY = "commands";
|
||||
/** The unlocalised name of the worldgen config category. */
|
||||
public static final String WORLDGEN_CATEGORY = "worldgen";
|
||||
/** The unlocalised name of the global config category. */
|
||||
public static final String GLOBAL_CATEGORY = "global";
|
||||
/** The unlocalised name of the gameplay config category. */
|
||||
public static final String GAMEPLAY_CATEGORY = "gameplay";
|
||||
|
||||
/** The wizardry config file. */
|
||||
private Configuration config;
|
||||
@@ -102,19 +102,26 @@ public final class Settings {
|
||||
/** <b>[Server-only]</b> Whether summoned creatures can revenge attack their caster if their caster attacks them. */
|
||||
public boolean minionRevengeTargeting = true;
|
||||
/**
|
||||
* <b>[Server-only]</b> List of names of entities which summoned creatures are allowed to attack, in addition to the
|
||||
* defaults.
|
||||
* <b>[Server-only]</b> List of registry names of entities which summoned creatures are allowed to attack, in addition
|
||||
* to the defaults.
|
||||
*/
|
||||
public String[] summonedCreatureTargetsWhitelist = {};
|
||||
public ResourceLocation[] summonedCreatureTargetsWhitelist = {};
|
||||
/**
|
||||
* <b>[Server-only]</b> List of names of entities which summoned creatures are specifically not allowed to attack,
|
||||
* overriding the defaults and the whitelist.
|
||||
* <b>[Server-only]</b> List of registry names of entities which summoned creatures are specifically not allowed to
|
||||
* attack, overriding the defaults and the whitelist.
|
||||
*/
|
||||
public String[] summonedCreatureTargetsBlacklist = {"creeper"};
|
||||
public ResourceLocation[] summonedCreatureTargetsBlacklist = {new ResourceLocation("creeper")};
|
||||
/**
|
||||
* <b>[Server-only]</b> List of registry names of entities which are immune to the mind control spell, in addition to
|
||||
* the defaults.
|
||||
*/
|
||||
public ResourceLocation[] mindControlTargetsBlacklist = {};
|
||||
/** <b>[Server-only]</b> Global damage scaling factor for all player magic damage. */
|
||||
public double playerDamageScale = 1.0f;
|
||||
/** <b>[Server-only]</b> Global damage scaling factor for all npc magic damage. */
|
||||
public double npcDamageScale = 1.0f;
|
||||
/** <b>[Server-only]</b> List of dimension ids in which evil wizards can spawn. */
|
||||
public int[] evilWizardDimensions = {0};
|
||||
|
||||
// Commands (these don't need synchronising since typing a command always queries the server).
|
||||
/**
|
||||
@@ -134,19 +141,6 @@ public final class Settings {
|
||||
// Synchronised settings. These settings affect both client-side AND server-side code. Changing these locally
|
||||
// only has an effect if the local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world.
|
||||
|
||||
// Recipes (only need syncing for display in the wizard's handbook)
|
||||
/** <b>[Synchronised]</b> Whether or not firebombs should be craftable. */
|
||||
public boolean firebombIsCraftable = true;
|
||||
/** <b>[Synchronised]</b> Whether or not poison bombs should be craftable. */
|
||||
public boolean poisonBombIsCraftable = true;
|
||||
/** <b>[Synchronised]</b> Whether or not poison bombs should be craftable. */
|
||||
public boolean smokeBombIsCraftable = true;
|
||||
/**
|
||||
* <b>[Synchronised]</b> Whether to require a magic crystal in the blank scroll crafting recipe (in case it
|
||||
* conflicts with another mod).
|
||||
*/
|
||||
public boolean useAlternateScrollRecipe = false;
|
||||
|
||||
// Gamemodes
|
||||
/**
|
||||
* <b>[Synchronised]</b> When set to true, spells a player hasn't cast yet will be unreadable until they are cast
|
||||
@@ -218,7 +212,7 @@ public final class Settings {
|
||||
/**
|
||||
* Called from preInit to initialise the config file. The first part of the config file has to be done here (as is
|
||||
* conventional) so that the various registries can change what they do accordingly. The spell part of the config
|
||||
* has to be done in the init method.
|
||||
* and the resistance part of the config have to be done in the init method since they depend on the registry events.
|
||||
*/
|
||||
void initConfig(FMLPreInitializationEvent event){
|
||||
|
||||
@@ -228,20 +222,27 @@ public final class Settings {
|
||||
Wizardry.logger.info("Setting up main config");
|
||||
|
||||
setupGeneralConfig();
|
||||
setupWorldgenConfig();
|
||||
setupClientConfig();
|
||||
setupCommandsConfig();
|
||||
|
||||
config.save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from init to initialise the parts of the config file that depend on other mods. For example, the spell
|
||||
* config is done here and not in preInit because all spells must be registered before it is added, including those
|
||||
* in other mods.
|
||||
* Called from init to initialise the parts of the config file that have to be done after registry events are fired.
|
||||
* For example, the spell config is done here and not in preInit because all spells must be registered before it is
|
||||
* added, including those in other mods.
|
||||
*/
|
||||
void initConfigExtras(){
|
||||
|
||||
Wizardry.logger.info("Setting up spells config for " + Spell.getTotalSpellCount() + " spells");
|
||||
|
||||
setupSpellsConfig();
|
||||
|
||||
Wizardry.logger.info("Setting up resistances config");
|
||||
|
||||
setupResistancesConfig();
|
||||
|
||||
config.save();
|
||||
}
|
||||
@@ -252,7 +253,11 @@ public final class Settings {
|
||||
Wizardry.logger.info("Saving in-game config changes");
|
||||
|
||||
setupGeneralConfig();
|
||||
setupWorldgenConfig();
|
||||
setupClientConfig();
|
||||
setupCommandsConfig();
|
||||
setupSpellsConfig();
|
||||
setupResistancesConfig();
|
||||
|
||||
config.save();
|
||||
}
|
||||
@@ -292,19 +297,22 @@ public final class Settings {
|
||||
|
||||
Property property;
|
||||
|
||||
config.addCustomCategoryComment(Configuration.CATEGORY_GENERAL,
|
||||
"Please note that changing some of these settings may make the mod very difficult to play.");
|
||||
config.addCustomCategoryComment(GAMEPLAY_CATEGORY, "Global settings that affect game mechanics. In multiplayer, the server/LAN host settings will apply. Please note that changing some of these settings may make the mod very difficult to play.");
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "towerRarity", 8,
|
||||
"Rarity of wizard towers. Higher numbers are rarer. Set to 0 to disable wizard towers completely.", 0,
|
||||
50);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".tower_rarity");
|
||||
property = config.get(GAMEPLAY_CATEGORY, "discoveryMode", true,
|
||||
"For those who like a sense of mystery! When set to true, spells you haven't cast yet will be unreadable until you cast them (on a per-world basis). Has no effect when in creative mode. Spells of identification will be unobtainable in survival mode if this is false.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".discovery_mode");
|
||||
property.setRequiresWorldRestart(true);
|
||||
Wizardry.proxy.setToNumberSliderEntry(property);
|
||||
towerRarity = property.getInt();
|
||||
discoveryMode = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "spellBookDropChance", 3,
|
||||
property = config.get(GAMEPLAY_CATEGORY, "friendlyFire", true,
|
||||
"Whether to allow players to damage their designated allies using magic.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".friendly_fire");
|
||||
friendlyFire = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "spellBookDropChance", 3,
|
||||
"The chance for mobs to drop a spell book when killed. The greater this number, the more often they will drop. Set to 0 to disable spell book drops. Set to 200 for guaranteed drops.",
|
||||
0, 200);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".spell_book_drop_chance");
|
||||
@@ -312,202 +320,208 @@ public final class Settings {
|
||||
spellBookDropChance = property.getInt();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "oreDimensions", new int[]{0},
|
||||
"List of dimension ids in which crystal ore will generate. Note that removing the overworld (id 0) from this list will make the mod VERY difficult to play!");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".ore_dimensions");
|
||||
property.setRequiresWorldRestart(true);
|
||||
oreDimensions = property.getIntList();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "flowerDimensions", new int[]{0},
|
||||
"List of dimension ids in which crystal flowers will generate.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".flower_dimensions");
|
||||
property.setRequiresWorldRestart(true);
|
||||
flowerDimensions = property.getIntList();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "towerDimensions", new int[]{0},
|
||||
"List of dimension ids in which wizard towers will generate.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".tower_dimensions");
|
||||
property.setRequiresWorldRestart(true);
|
||||
towerDimensions = property.getIntList();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "generateLoot", true,
|
||||
"Whether to generate wizardry loot in dungeon chests.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".generate_loot");
|
||||
property.setRequiresWorldRestart(true);
|
||||
generateLoot = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "firebombIsCraftable", true,
|
||||
"Whether firebombs can be crafted or not.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".firebomb_is_craftable");
|
||||
property = config.get(GAMEPLAY_CATEGORY, "evilWizardDimensions", new int[]{0},
|
||||
"List of dimension ids in which evil wizards can spawn.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".evil_wizard_dimensions");
|
||||
property.setRequiresMcRestart(true);
|
||||
firebombIsCraftable = property.getBoolean();
|
||||
evilWizardDimensions = property.getIntList();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "poisonBombIsCraftable", true,
|
||||
"Whether poison bombs can be crafted or not.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".poison_bomb_is_craftable");
|
||||
property.setRequiresMcRestart(true);
|
||||
poisonBombIsCraftable = property.getBoolean();
|
||||
// These two aren't sliders because using a slider makes it difficult to fine-tune the numbers; the nature of a
|
||||
// scaling factor means that 0.5 is as big a change as 2.0, so whilst a slider is fine for increasing the
|
||||
// damage, it doesn't give fine enough control for values less than 1.
|
||||
property = config.get(GAMEPLAY_CATEGORY, "playerDamageScaling", 1.0,
|
||||
"Global damage scaling factor for the damage dealt by players casting spells, relative to 1.", 0, 20);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".player_damage_scaling");
|
||||
playerDamageScale = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "smokeBombIsCraftable", true,
|
||||
"Whether smoke bombs can be crafted or not.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".smoke_bomb_is_craftable");
|
||||
property.setRequiresMcRestart(true);
|
||||
smokeBombIsCraftable = property.getBoolean();
|
||||
property = config.get(GAMEPLAY_CATEGORY, "npcDamageScaling", 1.0,
|
||||
"Global damage scaling factor for the damage dealt by NPCs casting spells, relative to 1.", 0, 20);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".npc_damage_scaling");
|
||||
npcDamageScale = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "useAlternateScrollRecipe", false,
|
||||
"Whether to require a magic crystal in the shapeless crafting recipe for blank scrolls. Set to true if another mod adds a conflicting recipe.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".use_alternate_scroll_recipe");
|
||||
property.setRequiresMcRestart(true);
|
||||
useAlternateScrollRecipe = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "teleportThroughUnbreakableBlocks", false,
|
||||
"Whether players are allowed to teleport through unbreakable blocks (e.g. bedrock) using the phase step spell.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".teleport_through_unbreakable_blocks");
|
||||
teleportThroughUnbreakableBlocks = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "showSummonedCreatureNames", true,
|
||||
"Whether to show summoned creatures' names and owners above their heads.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".show_summoned_creature_names");
|
||||
showSummonedCreatureNames = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "friendlyFire", true,
|
||||
"Whether to allow players to damage their designated allies using magic.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".friendly_fire");
|
||||
friendlyFire = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "telekineticDisarmament", true,
|
||||
"Whether to allow players to disarm other players using the telekinesis spell. Set to false to prevent stealing of items.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".telekinetic_disarmament");
|
||||
telekineticDisarmament = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "discoveryMode", true,
|
||||
"For those who like a sense of mystery! When set to true, spells you haven't cast yet will be unreadable until you cast them (on a per-world basis). Has no effect when in creative mode. Spells of identification will be unobtainable in survival mode if this is false.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".discovery_mode");
|
||||
property.setRequiresWorldRestart(true);
|
||||
discoveryMode = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "enableShiftScrolling", true,
|
||||
"Whether you can switch between spells on a wand by scrolling with the mouse wheel while sneaking. Note that this will only affect you; other players connected to the same server obey their own settings.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".enable_shift_scrolling");
|
||||
property.setRequiresWorldRestart(false);
|
||||
enableShiftScrolling = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "minionRevengeTargeting", true,
|
||||
property = config.get(GAMEPLAY_CATEGORY, "minionRevengeTargeting", true,
|
||||
"Whether summoned creatures can revenge attack their owner if their owner attacks them.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".minion_revenge_targeting");
|
||||
property.setRequiresWorldRestart(false);
|
||||
minionRevengeTargeting = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
// These two aren't sliders because using a slider makes it difficult to fine-tune the numbers; the nature of a
|
||||
// scaling factor means that 0.5 is as big a change as 2.0, so whilst a slider is fine for increasing the
|
||||
// damage,
|
||||
// it doesn't give fine enough control for values less than 1.
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "playerDamageScaling", 1.0,
|
||||
"Global damage scaling factor for the damage dealt by players casting spells, relative to 1.", 0, 20);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".player_damage_scaling");
|
||||
playerDamageScale = property.getDouble();
|
||||
property = config.get(GAMEPLAY_CATEGORY, "summonedCreatureTargetsWhitelist", new String[0],
|
||||
"List of names of entities which summoned creatures and wizards are allowed to attack, in addition to the defaults. Add mod creatures to this list if you want summoned creatures to attack them and they aren't already doing so. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".summoned_creature_targets_whitelist");
|
||||
property.setRequiresWorldRestart(true);
|
||||
// Converts all strings in the list to a ResourceLocation.
|
||||
summonedCreatureTargetsWhitelist = Arrays.stream(property.getStringList()).map(s -> new ResourceLocation(s.toLowerCase(Locale.ROOT).trim())).toArray(ResourceLocation[]::new);
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "npcDamageScaling", 1.0,
|
||||
"Global damage scaling factor for the damage dealt by NPCs casting spells, relative to 1.", 0, 20);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".npc_damage_scaling");
|
||||
npcDamageScale = property.getDouble();
|
||||
property = config.get(GAMEPLAY_CATEGORY, "summonedCreatureTargetsBlacklist",
|
||||
new String[]{"creeper"},
|
||||
"List of names of entities which summoned creatures and wizards are specifically not allowed to attack, overriding the defaults and the whitelist. Add creatures to this list if allowing them to be attacked causes problems or is too destructive (removing creepers from this list is done at your own risk!). Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".summoned_creature_targets_blacklist");
|
||||
property.setRequiresWorldRestart(true);
|
||||
// Converts all strings in the list to a ResourceLocation.
|
||||
summonedCreatureTargetsBlacklist = Arrays.stream(property.getStringList()).map(s -> new ResourceLocation(s.toLowerCase(Locale.ROOT).trim())).toArray(ResourceLocation[]::new);
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "telekineticDisarmament", true,
|
||||
"Whether to allow players to disarm other players using the telekinesis spell. Set to false to prevent stealing of items.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".telekinetic_disarmament");
|
||||
telekineticDisarmament = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "teleportThroughUnbreakableBlocks", false,
|
||||
"Whether players are allowed to teleport through unbreakable blocks (e.g. bedrock) using the phase step spell.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".teleport_through_unbreakable_blocks");
|
||||
teleportThroughUnbreakableBlocks = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "mindControlTargetsBlacklist", new String[]{},
|
||||
"List of names of entities which cannot be mind controlled, in addition to the defaults. Add creatures to this list if allowing them to be mind-controlled causes problems or could be exploited. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".mind_control_targets_blacklist");
|
||||
property.setRequiresWorldRestart(true);
|
||||
// Converts all strings in the list to a ResourceLocation.
|
||||
mindControlTargetsBlacklist = Arrays.stream(property.getStringList()).map(s -> new ResourceLocation(s.toLowerCase(Locale.ROOT).trim())).toArray(ResourceLocation[]::new);
|
||||
propOrder.add(property.getName());
|
||||
|
||||
config.setCategoryPropertyOrder(GAMEPLAY_CATEGORY, propOrder);
|
||||
|
||||
}
|
||||
|
||||
private void setupWorldgenConfig(){
|
||||
|
||||
// This trick is borrowed from forge; it sorts the config options into the order you want them.
|
||||
List<String> propOrder = new ArrayList<String>();
|
||||
|
||||
Property property;
|
||||
|
||||
config.addCustomCategoryComment(WORLDGEN_CATEGORY, "Settings that affect world generation. In multiplayer, the server/LAN host settings will apply.");
|
||||
|
||||
property = config.get(WORLDGEN_CATEGORY, "towerRarity", 8, "Rarity of wizard towers. Higher numbers are rarer. Set to 0 to disable wizard towers completely.", 0, 50);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".tower_rarity");
|
||||
property.setRequiresWorldRestart(true);
|
||||
Wizardry.proxy.setToNumberSliderEntry(property);
|
||||
towerRarity = property.getInt();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(WORLDGEN_CATEGORY, "towerDimensions", new int[]{0}, "List of dimension ids in which wizard towers will generate.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".tower_dimensions");
|
||||
property.setRequiresWorldRestart(true);
|
||||
towerDimensions = property.getIntList();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(WORLDGEN_CATEGORY, "oreDimensions", new int[]{0}, "List of dimension ids in which crystal ore will generate. Note that removing the overworld (id 0) from this list will make the mod VERY difficult to play!");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".ore_dimensions");
|
||||
property.setRequiresWorldRestart(true);
|
||||
oreDimensions = property.getIntList();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(WORLDGEN_CATEGORY, "flowerDimensions", new int[]{0}, "List of dimension ids in which crystal flowers will generate.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".flower_dimensions");
|
||||
property.setRequiresWorldRestart(true);
|
||||
flowerDimensions = property.getIntList();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(WORLDGEN_CATEGORY, "generateLoot", true, "Whether to inject wizardry loot (as specified in loot_tables/chests/dungeon_additions.json) into the loot tables for vanilla dungeon chests.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".generate_loot");
|
||||
property.setRequiresWorldRestart(true);
|
||||
generateLoot = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
config.setCategoryPropertyOrder(WORLDGEN_CATEGORY, propOrder);
|
||||
}
|
||||
|
||||
private void setupClientConfig(){
|
||||
|
||||
// This trick is borrowed from forge; it sorts the config options into the order you want them.
|
||||
List<String> propOrder = new ArrayList<String>();
|
||||
|
||||
Property property;
|
||||
|
||||
config.addCustomCategoryComment(CLIENT_CATEGORY, "Client-side settings that only affect the local minecraft game. If this file is on a dedicated server, these settings will have no effect; in multiplayer, each player obeys their own settings.");
|
||||
|
||||
property = config.get(CLIENT_CATEGORY, "enableShiftScrolling", true,
|
||||
"Whether you can switch between spells on a wand by scrolling with the mouse wheel while sneaking. Note that this will only affect you; other players connected to the same server obey their own settings.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".enable_shift_scrolling");
|
||||
property.setRequiresWorldRestart(false);
|
||||
enableShiftScrolling = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(CLIENT_CATEGORY, "spellHUDPosition", GuiPosition.BOTTOM_LEFT.name, "The position of the spell HUD.", GuiPosition.names);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".spell_hud_position");
|
||||
spellHUDPosition = GuiPosition.fromName(property.getString());
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(CLIENT_CATEGORY, "showSummonedCreatureNames", true, "Whether to show summoned creatures' names and owners above their heads.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".show_summoned_creature_names");
|
||||
showSummonedCreatureNames = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
config.setCategoryPropertyOrder(CLIENT_CATEGORY, propOrder);
|
||||
}
|
||||
|
||||
private void setupCommandsConfig(){
|
||||
|
||||
// This trick is borrowed from forge; it sorts the config options into the order you want them.
|
||||
List<String> propOrder = new ArrayList<String>();
|
||||
|
||||
Property property;
|
||||
|
||||
config.addCustomCategoryComment(COMMANDS_CATEGORY, "Settings for the commands added by Wizardry. In multiplayer, the server/LAN host settings will apply.");
|
||||
|
||||
// This one isn't a slider either because people are likely to want exact values ("it must be at most 50.3" is a
|
||||
// bit strange!).
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "castCommandMultiplierLimit", 20.0,
|
||||
property = config.get(COMMANDS_CATEGORY, "castCommandMultiplierLimit", 20.0,
|
||||
"Upper limit for the multipliers passed into the /cast command. This is here to stop players from accidentally breaking a world/server. Large blast mutipliers can cause extreme lag - you have been warned!",
|
||||
1, 255);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".cast_command_multiplier_limit");
|
||||
maxSpellCommandMultiplier = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "summonedCreatureTargetsWhitelist", new String[0],
|
||||
"List of names of entities which summoned creatures and wizards are allowed to attack, in addition to the defaults. Add mod creatures to this list if you want summoned creatures to attack them and they aren't already doing so. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":Wizard).");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".summoned_creature_targets_whitelist");
|
||||
property.setRequiresWorldRestart(true);
|
||||
// Wizardry.proxy.setToEntityNameEntry(property);
|
||||
summonedCreatureTargetsWhitelist = property.getStringList();
|
||||
// Converts all strings in the list to lower case, to ignore case sensitivity, and trims them.
|
||||
for(int i = 0; i < summonedCreatureTargetsWhitelist.length; i++){
|
||||
summonedCreatureTargetsWhitelist[i] = summonedCreatureTargetsWhitelist[i].toLowerCase(Locale.ROOT).trim();
|
||||
}
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "summonedCreatureTargetsBlacklist",
|
||||
new String[]{"creeper"},
|
||||
"List of names of entities which summoned creatures and wizards are specifically not allowed to attack, overriding the defaults and the whitelist. Add creatures to this list if allowing them to be attacked causes problems or is too destructive (removing creepers from this list is done at your own risk!). Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":Wizard).");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".summoned_creature_targets_blacklist");
|
||||
property.setRequiresWorldRestart(true);
|
||||
// Wizardry.proxy.setToEntityNameEntry(property);
|
||||
summonedCreatureTargetsBlacklist = property.getStringList();
|
||||
// Converts all strings in the list to lower case, to ignore case sensitivity, and trims them.
|
||||
for(int i = 0; i < summonedCreatureTargetsBlacklist.length; i++){
|
||||
summonedCreatureTargetsBlacklist[i] = summonedCreatureTargetsBlacklist[i].toLowerCase(Locale.ROOT).trim();
|
||||
}
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "spellHUDPosition", GuiPosition.BOTTOM_LEFT.name,
|
||||
"The position of the spell HUD.", GuiPosition.names);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".spell_hud_position");
|
||||
spellHUDPosition = GuiPosition.fromName(property.getString());
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "castCommandName", "cast",
|
||||
property = config.get(COMMANDS_CATEGORY, "castCommandName", "cast",
|
||||
"The name of the /cast command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /cast you would type /magic instead.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".cast_command_name");
|
||||
property.setRequiresWorldRestart(true);
|
||||
castCommandName = property.getString();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "discoverspellCommandName", "discoverspell",
|
||||
property = config.get(COMMANDS_CATEGORY, "discoverspellCommandName", "discoverspell",
|
||||
"The name of the /discoverspell command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /discoverspell you would type /magic instead.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".discoverspell_command_name");
|
||||
property.setRequiresWorldRestart(true);
|
||||
discoverspellCommandName = property.getString();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "allyCommandName", "ally",
|
||||
property = config.get(COMMANDS_CATEGORY, "allyCommandName", "ally",
|
||||
"The name of the /ally command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /ally you would type /magic instead.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".ally_command_name");
|
||||
property.setRequiresWorldRestart(true);
|
||||
allyCommandName = property.getString();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(Configuration.CATEGORY_GENERAL, "alliesCommandName", "allies",
|
||||
property = config.get(COMMANDS_CATEGORY, "alliesCommandName", "allies",
|
||||
"The name of the /allies command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /allies you would type /magic instead.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".allies_command_name");
|
||||
property.setRequiresWorldRestart(true);
|
||||
alliesCommandName = property.getString();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
config.setCategoryPropertyOrder(COMMANDS_CATEGORY, propOrder);
|
||||
}
|
||||
|
||||
config.setCategoryPropertyOrder(Configuration.CATEGORY_GENERAL, propOrder);
|
||||
private void setupResistancesConfig(){
|
||||
|
||||
// Resistances
|
||||
Property property;
|
||||
|
||||
List<String> propOrder1 = new ArrayList<String>();
|
||||
List<String> propOrder = new ArrayList<String>();
|
||||
|
||||
config.addCustomCategoryComment(RESISTANCES_CATEGORY,
|
||||
"Settings which allow entities to be made immune to certain types of magic. In multiplayer, the server/LAN host settings will apply.");
|
||||
|
||||
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToFire", new String[]{},
|
||||
"List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":Wizard).");
|
||||
"List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_fire");
|
||||
property.setRequiresMcRestart(true);
|
||||
// Wizardry.proxy.setToEntityNameEntry(property);
|
||||
@@ -517,10 +531,10 @@ public final class Settings {
|
||||
MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
|
||||
DamageType.FIRE);
|
||||
}
|
||||
propOrder1.add(property.getName());
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToIce", new String[]{},
|
||||
"List of names of entities that are immune to ice, in addition to the defaults. Add mod creatures to this list if you want them to be immune to ice magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":Wizard).");
|
||||
"List of names of entities that are immune to ice, in addition to the defaults. Add mod creatures to this list if you want them to be immune to ice magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_ice");
|
||||
property.setRequiresMcRestart(true);
|
||||
// Wizardry.proxy.setToEntityNameEntry(property);
|
||||
@@ -530,10 +544,10 @@ public final class Settings {
|
||||
MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
|
||||
DamageType.FROST);
|
||||
}
|
||||
propOrder1.add(property.getName());
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToLightning", new String[]{},
|
||||
"List of names of entities that are immune to lightning, in addition to the defaults. Add mod creatures to this list if you want them to be immune to lightning magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":Wizard).");
|
||||
"List of names of entities that are immune to lightning, in addition to the defaults. Add mod creatures to this list if you want them to be immune to lightning magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_lightning");
|
||||
property.setRequiresMcRestart(true);
|
||||
// Wizardry.proxy.setToEntityNameEntry(property);
|
||||
@@ -543,10 +557,10 @@ public final class Settings {
|
||||
MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
|
||||
DamageType.SHOCK);
|
||||
}
|
||||
propOrder1.add(property.getName());
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToWither", new String[]{},
|
||||
"List of names of entities that are immune to wither effects, in addition to the defaults. Add mod creatures to this list if you want them to be immune to withering magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":Wizard).");
|
||||
"List of names of entities that are immune to wither effects, in addition to the defaults. Add mod creatures to this list if you want them to be immune to withering magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_wither");
|
||||
property.setRequiresMcRestart(true);
|
||||
// Wizardry.proxy.setToEntityNameEntry(property);
|
||||
@@ -556,10 +570,10 @@ public final class Settings {
|
||||
MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
|
||||
DamageType.WITHER);
|
||||
}
|
||||
propOrder1.add(property.getName());
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToPoison", new String[]{},
|
||||
"List of names of entities that are immune to poison, in addition to the defaults. Add mod creatures to this list if you want them to be immune to poison magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":Wizard).");
|
||||
"List of names of entities that are immune to poison, in addition to the defaults. Add mod creatures to this list if you want them to be immune to poison magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_poison");
|
||||
property.setRequiresMcRestart(true);
|
||||
// Wizardry.proxy.setToEntityNameEntry(property);
|
||||
@@ -569,19 +583,9 @@ public final class Settings {
|
||||
MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
|
||||
DamageType.POISON);
|
||||
}
|
||||
propOrder1.add(property.getName());
|
||||
|
||||
config.setCategoryPropertyOrder(RESISTANCES_CATEGORY, propOrder1);
|
||||
|
||||
// config.addCustomCategoryComment(CLIENT_CATEGORY, "Client-side settings that only affect the local minecraft
|
||||
// game. They have no effect on a server; each player obeys their own settings.");
|
||||
// config.addCustomCategoryComment(COMMANDS_CATEGORY, "Settings for the commands added by Wizardry. In
|
||||
// multiplayer, the server/LAN host settings will apply.");
|
||||
// config.addCustomCategoryComment(WORLDGEN_CATEGORY, "Settings that affect world generation. In multiplayer,
|
||||
// the server/LAN host settings will apply.");
|
||||
// config.addCustomCategoryComment(GLOBAL_CATEGORY, "Global settings that affect game mechanics. In multiplayer,
|
||||
// the server/LAN host settings will apply.");
|
||||
propOrder.add(property.getName());
|
||||
|
||||
config.setCategoryPropertyOrder(RESISTANCES_CATEGORY, propOrder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,12 +33,12 @@ import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.init.MobEffects;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.item.ItemEnchantedBook;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagInt;
|
||||
import net.minecraft.nbt.NBTTagString;
|
||||
import net.minecraft.nbt.*;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
@@ -278,12 +278,14 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
|
||||
for(ItemStack stack : player.inventory.mainInventory){
|
||||
if(stack.isItemEnchanted()){
|
||||
|
||||
Map<Enchantment, Integer> enchantments = EnchantmentHelper.getEnchantments(stack);
|
||||
NBTTagList enchantmentList = stack.getItem() == Items.ENCHANTED_BOOK ?
|
||||
ItemEnchantedBook.getEnchantments(stack) : stack.getEnchantmentTagList();
|
||||
|
||||
Iterator<Entry<Enchantment, Integer>> iterator = enchantments.entrySet().iterator();
|
||||
Iterator<NBTBase> iterator =enchantmentList.iterator();
|
||||
// For each of the item's enchantments
|
||||
while(iterator.hasNext()){
|
||||
Enchantment enchantment = iterator.next().getKey();
|
||||
NBTTagCompound enchantmentTag = (NBTTagCompound) iterator.next();
|
||||
Enchantment enchantment = Enchantment.getEnchantmentByID(enchantmentTag.getShort("id"));
|
||||
// Ignores the enchantment unless it is an imbuement
|
||||
if(enchantment instanceof Imbuement){
|
||||
int duration = this.getImbuementDuration(enchantment);
|
||||
@@ -295,10 +297,8 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
|
||||
activeImbuements.add((Imbuement)enchantment);
|
||||
// Otherwise:
|
||||
}else{
|
||||
// Removes the enchantment from the enchantment map
|
||||
// Removes the enchantment from the item
|
||||
iterator.remove();
|
||||
// Applies the new enchantment map to the item
|
||||
EnchantmentHelper.setEnchantments(enchantments, stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package electroblob.wizardry;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import electroblob.wizardry.command.CommandCastSpell;
|
||||
import electroblob.wizardry.command.CommandDiscoverSpell;
|
||||
import electroblob.wizardry.command.CommandSetAlly;
|
||||
@@ -30,13 +28,12 @@ import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@Mod(modid = Wizardry.MODID, name = Wizardry.NAME, version = Wizardry.VERSION, guiFactory = "electroblob.wizardry.WizardryGuiFactory")
|
||||
public class Wizardry {
|
||||
|
||||
/** Wizardry's mod ID. */
|
||||
// This is going to have to change for 1.12 or it'll conflict with the other wizardry mod.
|
||||
// They were there first, it's only fair... although I wonder if that will have unintended side-effects?
|
||||
public static final String MODID = "ebwizardry";
|
||||
/** Wizardry's mod name, in readable form. */
|
||||
public static final String NAME = "Electroblob's Wizardry";
|
||||
@@ -50,7 +47,7 @@ public class Wizardry {
|
||||
* 1.x.x represents Minecraft 1.7.x versions, 2.x.x represents Minecraft 1.10.x versions, 3.x.x represents Minecraft
|
||||
* 1.11.x versions, and so on.
|
||||
*/
|
||||
public static final String VERSION = "4.1.0";
|
||||
public static final String VERSION = "4.1.4";
|
||||
|
||||
// IDEA: Improve the algorithm that finds a place to summon creatures to take walls into account.
|
||||
// IDEA: Replace all uses of Math.cos and Math.sin with MathHelper versions
|
||||
@@ -68,19 +65,6 @@ public class Wizardry {
|
||||
// I can make the healing spells use damage multipliers - hurrah!
|
||||
|
||||
// TODO: Switch from IInventory to IItemHandler (Or don't. It's only useful for automation really.)
|
||||
// TODO: Rearrange the config gui and file
|
||||
|
||||
// Updating:
|
||||
// TODO: Make sure all obf reflection names are still correct
|
||||
// TODO: Go through each of the summoned creatures and check there are no extra vanilla methods to override
|
||||
// TODO: Check whether Minecraft has added some methods that do the same job as my utilities, particularly in
|
||||
// relation to itemstacks, hotbar, armour slots and inventory slots.
|
||||
// TODO: Add wizard towers to the /locate command
|
||||
// TODO: Fix cascading worldgen lag and backport (offset area into loaded chunks, possibly use WorldGenMinable)
|
||||
// TODO: Change evil wizard sounds again to use illager sounds?
|
||||
// TODO: Chnage all instanceof checks on split entity variant classes (zombie, skeleton, etc.) to their abstract
|
||||
// base classes where appropriate
|
||||
|
||||
// TODO: Have particles obey Minecraft's particle setting where appropriate
|
||||
// (see https://github.com/RootsTeam/Embers/blob/master/src/main/java/teamroots/embers/particle/ParticleUtil.java)
|
||||
|
||||
@@ -151,7 +135,6 @@ public class Wizardry {
|
||||
|
||||
// Event Handlers
|
||||
GameRegistry.registerWorldGenerator(generator, 0);
|
||||
MinecraftForge.EVENT_BUS.register(new WizardryKeyHandler());
|
||||
MinecraftForge.EVENT_BUS.register(instance);
|
||||
proxy.registerSpellHUD(); // This can't easily be converted to use the new @Mod.EventBusSubscriber system
|
||||
NetworkRegistry.INSTANCE.registerGuiHandler(this, new WizardryGuiHandler());
|
||||
@@ -190,15 +173,15 @@ public class Wizardry {
|
||||
|
||||
// 2.1 changed some item ids, so this fixes them for existing worlds
|
||||
// Nobody updates minecraft versions when using mods, but I may as well leave this here just in case.
|
||||
@EventHandler
|
||||
@SubscribeEvent
|
||||
public static void onMissingMappingEvent(RegistryEvent.MissingMappings<Item> event){
|
||||
// Just get, not getAll, since the mod id didn't change!
|
||||
for(RegistryEvent.MissingMappings.Mapping<Item> mapping : event.getAllMappings()){
|
||||
if(mapping.key.getResourceDomain().equals(Wizardry.MODID)){
|
||||
if(mapping.key.getNamespace().equals(Wizardry.MODID)){
|
||||
|
||||
Item replacement = null;
|
||||
|
||||
switch(mapping.key.getResourcePath()){
|
||||
switch(mapping.key.getPath()){
|
||||
|
||||
case "wand_basic": replacement = WizardryItems.magic_wand; break;
|
||||
case "wand_basic_fire": replacement = WizardryItems.basic_fire_wand; break;
|
||||
|
||||
@@ -50,6 +50,7 @@ import net.minecraft.world.storage.loot.LootPool;
|
||||
import net.minecraft.world.storage.loot.RandomValueRange;
|
||||
import net.minecraft.world.storage.loot.conditions.LootCondition;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.event.LootTableLoadEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingAttackEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingDeathEvent;
|
||||
@@ -199,7 +200,8 @@ public final class WizardryEventHandler {
|
||||
|
||||
// Ice Shroud
|
||||
if(event.getEntityLiving().isPotionActive(WizardryPotions.ice_shroud)
|
||||
&& !MagicDamage.isEntityImmune(DamageType.FROST, event.getEntityLiving()))
|
||||
&& !MagicDamage.isEntityImmune(DamageType.FROST, event.getEntityLiving())
|
||||
&& !(event.getEntityLiving() instanceof FakePlayer))
|
||||
attacker.addPotionEffect(new PotionEffect(WizardryPotions.frost, 100, 0));
|
||||
|
||||
// Static Aura
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
package electroblob.wizardry;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import electroblob.wizardry.client.ClientProxy;
|
||||
import electroblob.wizardry.packet.PacketControlInput;
|
||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.InputEvent;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
|
||||
public class WizardryKeyHandler {
|
||||
|
||||
boolean NkeyPressed = false;
|
||||
boolean BkeyPressed = false;
|
||||
boolean NkeyAlreadyPressed = false;
|
||||
boolean BkeyAlreadyPressed = false;
|
||||
|
||||
@SubscribeEvent
|
||||
public void onKeyInput(InputEvent.KeyInputEvent event){
|
||||
|
||||
// Key pressed
|
||||
if(Keyboard.getEventKeyState()){
|
||||
|
||||
if(Wizardry.proxy instanceof ClientProxy){
|
||||
|
||||
if(ClientProxy.NEXT_SPELL.isPressed() && Minecraft.getMinecraft().inGameHasFocus){
|
||||
if(!NkeyPressed){
|
||||
NkeyPressed = true;
|
||||
}else{
|
||||
NkeyAlreadyPressed = true;
|
||||
}
|
||||
if(!NkeyAlreadyPressed){
|
||||
// Packet building
|
||||
IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.NEXT_SPELL_KEY);
|
||||
WizardryPacketHandler.net.sendToServer(msg);
|
||||
}
|
||||
}
|
||||
|
||||
if(ClientProxy.PREVIOUS_SPELL.isPressed() && Minecraft.getMinecraft().inGameHasFocus){
|
||||
if(!BkeyPressed){
|
||||
BkeyPressed = true;
|
||||
}else{
|
||||
BkeyAlreadyPressed = true;
|
||||
}
|
||||
if(!BkeyAlreadyPressed){
|
||||
// Packet building
|
||||
IMessage msg = new PacketControlInput.Message(
|
||||
PacketControlInput.ControlType.PREVIOUS_SPELL_KEY);
|
||||
WizardryPacketHandler.net.sendToServer(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Key released
|
||||
else{
|
||||
if(NkeyPressed){
|
||||
NkeyPressed = false;
|
||||
NkeyAlreadyPressed = false;
|
||||
}else if(BkeyPressed){
|
||||
BkeyPressed = false;
|
||||
BkeyAlreadyPressed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,7 +175,7 @@ public class WizardryWorldGenerator implements IWorldGenerator {
|
||||
}
|
||||
|
||||
// 0 = West, 1 = North, 2 = East, 3 = South (The way you would face when walking out of the door)
|
||||
EnumFacing orientation = EnumFacing.getHorizontal(random.nextInt(4));
|
||||
EnumFacing orientation = EnumFacing.byHorizontalIndex(random.nextInt(4));
|
||||
boolean flip = random.nextBoolean();
|
||||
|
||||
if(checkSpaceForTower(world, origin, towerBlueprint, orientation, flip)){
|
||||
@@ -237,7 +237,8 @@ public class WizardryWorldGenerator implements IWorldGenerator {
|
||||
// BlockPos is immutable, so I'm not sure if simply saying pos1 = pos will be sufficient.
|
||||
BlockPos layerCentre = new BlockPos(origin);
|
||||
|
||||
while(flag){
|
||||
// Stop when the bottom of the world is reached
|
||||
while(flag && layerCentre.getY() > 0){
|
||||
|
||||
flag = false;
|
||||
|
||||
@@ -299,7 +300,7 @@ public class WizardryWorldGenerator implements IWorldGenerator {
|
||||
// Rotates the door depending on whether flip is true.
|
||||
ItemDoor.placeDoor(
|
||||
world, pos, flip
|
||||
? EnumFacing.getHorizontal(3 - orientation.getHorizontalIndex())
|
||||
? EnumFacing.byHorizontalIndex(3 - orientation.getHorizontalIndex())
|
||||
.getOpposite()
|
||||
: orientation.rotateYCCW(),
|
||||
Blocks.OAK_DOOR, false);
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
package electroblob.wizardry.block;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.WizardryGuiHandler;
|
||||
import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench;
|
||||
import net.minecraft.block.BlockContainer;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.inventory.InventoryHelper;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.EnumBlockRenderType;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
@@ -65,59 +61,20 @@ public class BlockArcaneWorkbench extends BlockContainer {
|
||||
return false;
|
||||
}
|
||||
|
||||
player.openGui(Wizardry.instance, WizardryGuiHandler.ARCANE_WORKBENCH, world, pos.getX(), pos.getY(),
|
||||
pos.getZ());
|
||||
player.openGui(Wizardry.instance, WizardryGuiHandler.ARCANE_WORKBENCH, world, pos.getX(), pos.getY(), pos.getZ());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void breakBlock(World world, BlockPos pos, IBlockState block){
|
||||
|
||||
TileEntity tileentity = world.getTileEntity(pos);
|
||||
|
||||
Random random = new Random();
|
||||
TileEntityArcaneWorkbench tileentityarcaneworkbench = (TileEntityArcaneWorkbench)world.getTileEntity(pos);
|
||||
if(tileentity instanceof TileEntityArcaneWorkbench){
|
||||
InventoryHelper.dropInventoryItems(world, pos, (TileEntityArcaneWorkbench)tileentity);
|
||||
}
|
||||
|
||||
if(tileentityarcaneworkbench != null){
|
||||
|
||||
for(int j1 = 0; j1 < tileentityarcaneworkbench.getSizeInventory(); ++j1){
|
||||
|
||||
ItemStack itemstack = tileentityarcaneworkbench.getStackInSlot(j1);
|
||||
|
||||
if(!itemstack.isEmpty()){
|
||||
|
||||
float f = random.nextFloat() * 0.8F + 0.1F;
|
||||
float f1 = random.nextFloat() * 0.8F + 0.1F;
|
||||
EntityItem entityitem;
|
||||
|
||||
for(float f2 = random.nextFloat() * 0.8F + 0.1F; itemstack.getCount() > 0; world
|
||||
.spawnEntity(entityitem)){
|
||||
|
||||
int k1 = random.nextInt(21) + 10;
|
||||
|
||||
if(k1 > itemstack.getCount()){
|
||||
k1 = itemstack.getCount();
|
||||
}
|
||||
|
||||
itemstack.shrink(k1);
|
||||
|
||||
entityitem = new EntityItem(world, (double)((float)pos.getX() + f),
|
||||
(double)((float)pos.getY() + f1), (double)((float)pos.getZ() + f2),
|
||||
new ItemStack(itemstack.getItem(), k1, itemstack.getItemDamage()));
|
||||
float f3 = 0.05F;
|
||||
entityitem.motionX = (double)((float)random.nextGaussian() * f3);
|
||||
entityitem.motionY = (double)((float)random.nextGaussian() * f3 + 0.2F);
|
||||
entityitem.motionZ = (double)((float)random.nextGaussian() * f3);
|
||||
|
||||
if(itemstack.hasTagCompound()){
|
||||
entityitem.getItem().setTagCompound(((NBTTagCompound)itemstack.getTagCompound().copy()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// par1World.func_96440_m(par2, par3, par4, block);
|
||||
}
|
||||
|
||||
super.breakBlock(world, pos, block);
|
||||
super.breakBlock(world, pos, block);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,6 +8,10 @@ import net.minecraft.block.SoundType;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BlockCrystalOre extends Block {
|
||||
|
||||
@@ -20,10 +24,17 @@ public class BlockCrystalOre extends Block {
|
||||
|
||||
@Override
|
||||
public int quantityDropped(IBlockState state, int fortune, Random random){
|
||||
// This now works the same way as vanilla ores
|
||||
if(fortune > 0){
|
||||
return random.nextInt(2) + 1 + random.nextInt(fortune);
|
||||
|
||||
int i = random.nextInt(fortune + 2) - 1;
|
||||
|
||||
if(i < 0) i = 0;
|
||||
|
||||
return (random.nextInt(3) + 1) * (i + 1);
|
||||
|
||||
}else{
|
||||
return random.nextInt(2) + 1;
|
||||
return random.nextInt(3) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,4 +42,16 @@ public class BlockCrystalOre extends Block {
|
||||
public Item getItemDropped(IBlockState state, Random random, int fortune){
|
||||
return WizardryItems.magic_crystal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getExpDrop(IBlockState state, IBlockAccess world, BlockPos pos, int fortune){
|
||||
|
||||
Random rand = world instanceof World ? ((World)world).rand : RANDOM;
|
||||
|
||||
if(this.getItemDropped(state, rand, fortune) != Item.getItemFromBlock(this)){
|
||||
return MathHelper.getInt(rand, 1, 4);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ public class BlockSnare extends BlockContainer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity){
|
||||
public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entity){
|
||||
|
||||
if(!world.isRemote && entity instanceof EntityLivingBase){
|
||||
if(world.getTileEntity(pos) instanceof TileEntityPlayerSave){
|
||||
@@ -80,7 +80,7 @@ public class BlockSnare extends BlockContainer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRenderLayer getBlockLayer(){
|
||||
public BlockRenderLayer getRenderLayer() {
|
||||
return BlockRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ public class BlockSpectral extends BlockContainer {
|
||||
|
||||
// Replaces getRenderBlockPass
|
||||
@Override
|
||||
public BlockRenderLayer getBlockLayer(){
|
||||
public BlockRenderLayer getRenderLayer(){
|
||||
return BlockRenderLayer.TRANSLUCENT;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ public class BlockStatue extends BlockContainer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockRenderLayer getBlockLayer(){
|
||||
public BlockRenderLayer getRenderLayer(){
|
||||
return this.isIce ? BlockRenderLayer.TRANSLUCENT : BlockRenderLayer.SOLID;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,14 +66,15 @@ public class BlockTransportationStone extends Block {
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void onNeighborChange(IBlockAccess world, BlockPos pos, BlockPos neighbor){
|
||||
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos fromPos){
|
||||
|
||||
super.onNeighborChange(world, pos, neighbor);
|
||||
super.neighborChanged(state, world, pos, block, fromPos);
|
||||
|
||||
if(!world.isSideSolid(pos.down(), EnumFacing.UP, false) && world instanceof World){
|
||||
this.dropBlockAsItem((World)world, pos, world.getBlockState(pos), 0);
|
||||
((World)world).setBlockToAir(pos);
|
||||
if(!world.isSideSolid(pos.down(), EnumFacing.UP, false)){
|
||||
this.dropBlockAsItem(world, pos, world.getBlockState(pos), 0);
|
||||
world.setBlockToAir(pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ public class BlockVanishingCobweb extends BlockContainer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity){
|
||||
public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entity){
|
||||
entity.setInWeb();
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,8 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
@Override
|
||||
public void drawScreen(int p_73863_1_, int p_73863_2_, float p_73863_3_){
|
||||
|
||||
this.drawDefaultBackground();
|
||||
|
||||
// Tests if there is a wand in the workbench and edits the positioning accordingly
|
||||
if(this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getHasStack() && this.inventorySlots
|
||||
.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack().getItem() instanceof ItemWand){
|
||||
@@ -80,8 +82,6 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
@Override
|
||||
public void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY){
|
||||
|
||||
GlStateManager.pushAttrib();
|
||||
|
||||
GlStateManager.color(1F, 1F, 1F, 1F);
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture(texture);
|
||||
|
||||
@@ -152,8 +152,6 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
// Fixes the bug that caused the slot hightlight to render opaque. I don't know why it works, it just works!
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.enableAlpha();
|
||||
|
||||
GlStateManager.popAttrib();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,57 +24,107 @@ public class GuiConfigWizardry extends GuiConfig {
|
||||
}
|
||||
|
||||
private static List<IConfigElement> getConfigEntries(){
|
||||
|
||||
List<IConfigElement> configList = new ArrayList<IConfigElement>(1);
|
||||
configList.add(new DummyCategoryElement("spellsConfig", "config." + Wizardry.MODID + ".category." + Settings.SPELLS_CATEGORY,
|
||||
SpellsCategory.class));
|
||||
configList.add(new DummyCategoryElement("resistancesConfig",
|
||||
"config.wizardry.category." + Settings.RESISTANCES_CATEGORY, ResistancesCategory.class));
|
||||
configList.addAll(new ConfigElement(Wizardry.settings.getConfigCategory(Configuration.CATEGORY_GENERAL))
|
||||
.getChildElements());
|
||||
|
||||
configList.add(new DummyCategoryElement("gameplayConfig", "config." + Wizardry.MODID + ".category." + Settings.GAMEPLAY_CATEGORY, GameplayCategory.class));
|
||||
configList.add(new DummyCategoryElement("worldgenConfig", "config." + Wizardry.MODID + ".category." + Settings.WORLDGEN_CATEGORY, WorldgenCategory.class));
|
||||
configList.add(new DummyCategoryElement("commandsConfig", "config." + Wizardry.MODID + ".category." + Settings.COMMANDS_CATEGORY, CommandsCategory.class));
|
||||
configList.add(new DummyCategoryElement("clientConfig", "config." + Wizardry.MODID + ".category." + Settings.CLIENT_CATEGORY, ClientCategory.class));
|
||||
configList.add(new DummyCategoryElement("spellsConfig", "config." + Wizardry.MODID + ".category." + Settings.SPELLS_CATEGORY, SpellsCategory.class));
|
||||
configList.add(new DummyCategoryElement("resistancesConfig", "config." + Wizardry.MODID + ".category." + Settings.RESISTANCES_CATEGORY, ResistancesCategory.class));
|
||||
|
||||
configList.addAll(new ConfigElement(Wizardry.settings.getConfigCategory(Configuration.CATEGORY_GENERAL)).getChildElements());
|
||||
|
||||
return configList;
|
||||
}
|
||||
|
||||
// The reason this system is so convoluted is that it's designed for use with the @Config annotation. The problem is,
|
||||
// I'm not sure whether that will play well with the load phases. Hmmm...
|
||||
|
||||
public static abstract class CategoryBase extends CategoryEntry {
|
||||
|
||||
public CategoryBase(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
|
||||
super(owningScreen, owningEntryList, prop);
|
||||
}
|
||||
|
||||
/** Spells category of the config gui. This adds a button which opens up the spells category config. */
|
||||
public static class SpellsCategory extends CategoryEntry {
|
||||
@Override
|
||||
protected GuiScreen buildChildScreen(){
|
||||
|
||||
String category = this.getCategory();
|
||||
|
||||
// This GuiConfig object specifies the configID of the object and as such will force-save when it is closed.
|
||||
// The parent GuiConfig object's entryList will also be refreshed to reflect the changes.
|
||||
GuiConfig childScreen = new GuiConfig(this.owningScreen,
|
||||
(new ConfigElement(Wizardry.settings.getConfigCategory(category))).getChildElements(),
|
||||
this.owningScreen.modID, category, false, false,
|
||||
Wizardry.NAME + " - " + I18n.format("config." + Wizardry.MODID + ".title." + category));
|
||||
|
||||
childScreen.titleLine2 = I18n.format("config." + Wizardry.MODID + ".subtitle." + category);
|
||||
|
||||
return childScreen;
|
||||
}
|
||||
|
||||
protected abstract String getCategory();
|
||||
}
|
||||
|
||||
/** Gameplay category of the config gui. */
|
||||
public static class GameplayCategory extends CategoryBase {
|
||||
|
||||
public GameplayCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
|
||||
super(owningScreen, owningEntryList, prop);
|
||||
}
|
||||
|
||||
@Override protected String getCategory() { return Settings.GAMEPLAY_CATEGORY; }
|
||||
}
|
||||
|
||||
/** Spells category of the config gui. */
|
||||
public static class SpellsCategory extends CategoryBase {
|
||||
|
||||
public SpellsCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
|
||||
super(owningScreen, owningEntryList, prop);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GuiScreen buildChildScreen(){
|
||||
// This GuiConfig object specifies the configID of the object and as such will force-save when it is closed.
|
||||
// The parent GuiConfig object's entryList will also be refreshed to reflect the changes.
|
||||
GuiConfig spellsMenu = new GuiConfig(this.owningScreen,
|
||||
(new ConfigElement(Wizardry.settings.getConfigCategory(Settings.SPELLS_CATEGORY)))
|
||||
.getChildElements(),
|
||||
this.owningScreen.modID, Settings.SPELLS_CATEGORY, false, false,
|
||||
Wizardry.NAME + " - " + I18n.format("config." + Wizardry.MODID + ".title." + Settings.SPELLS_CATEGORY));
|
||||
|
||||
spellsMenu.titleLine2 = I18n.format("config." + Wizardry.MODID + ".subtitle." + Settings.SPELLS_CATEGORY);
|
||||
|
||||
return spellsMenu;
|
||||
}
|
||||
|
||||
@Override protected String getCategory() { return Settings.SPELLS_CATEGORY; }
|
||||
}
|
||||
|
||||
/** Resistances category of the config gui. */
|
||||
public static class ResistancesCategory extends CategoryEntry {
|
||||
public static class ResistancesCategory extends CategoryBase {
|
||||
|
||||
public ResistancesCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
|
||||
super(owningScreen, owningEntryList, prop);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GuiScreen buildChildScreen(){
|
||||
// This GuiConfig object specifies the configID of the object and as such will force-save when it is closed.
|
||||
// The parent GuiConfig object's entryList will also be refreshed to reflect the changes.
|
||||
GuiConfig idsMenu = new GuiConfig(this.owningScreen,
|
||||
(new ConfigElement(Wizardry.settings.getConfigCategory(Settings.RESISTANCES_CATEGORY)))
|
||||
.getChildElements(),
|
||||
this.owningScreen.modID, Settings.RESISTANCES_CATEGORY, false, false,
|
||||
Wizardry.NAME + " - " + I18n.format("config." + Wizardry.MODID + ".title." + Settings.RESISTANCES_CATEGORY));
|
||||
|
||||
idsMenu.titleLine2 = I18n.format("config." + Wizardry.MODID + ".subtitle." + Settings.RESISTANCES_CATEGORY);
|
||||
|
||||
return idsMenu;
|
||||
|
||||
@Override protected String getCategory() { return Settings.RESISTANCES_CATEGORY; }
|
||||
}
|
||||
|
||||
/** Worldgen category of the config gui. */
|
||||
public static class WorldgenCategory extends CategoryBase {
|
||||
|
||||
public WorldgenCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
|
||||
super(owningScreen, owningEntryList, prop);
|
||||
}
|
||||
|
||||
@Override protected String getCategory() { return Settings.WORLDGEN_CATEGORY; }
|
||||
}
|
||||
|
||||
/** Client category of the config gui. */
|
||||
public static class ClientCategory extends CategoryBase {
|
||||
|
||||
public ClientCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
|
||||
super(owningScreen, owningEntryList, prop);
|
||||
}
|
||||
|
||||
@Override protected String getCategory() { return Settings.CLIENT_CATEGORY; }
|
||||
}
|
||||
|
||||
/** Commands category of the config gui. */
|
||||
public static class CommandsCategory extends CategoryBase {
|
||||
|
||||
public CommandsCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
|
||||
super(owningScreen, owningEntryList, prop);
|
||||
}
|
||||
|
||||
@Override protected String getCategory() { return Settings.COMMANDS_CATEGORY; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,8 +122,6 @@ public class GuiSpellDisplay extends Gui {
|
||||
|
||||
}else if(event.getType() == RenderGameOverlayEvent.ElementType.HOTBAR){
|
||||
|
||||
GlStateManager.pushAttrib();
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
GlStateManager.color(1, 1, 1);
|
||||
@@ -135,19 +133,19 @@ public class GuiSpellDisplay extends Gui {
|
||||
|
||||
// Cooldown bar
|
||||
if(cooldown > 0){
|
||||
this.drawTexturedModalRect(mirror ? left + 5 : left + 41, height - 8, 128, 6, 82, 6);
|
||||
this.drawTexturedModalRect(mirror ? left + 5 : left + 41, top + 28, 128, 6, 82, 6);
|
||||
|
||||
int l = (int)(((double)(spell.cooldown * cooldownMultiplier - cooldown) / (double)(spell.cooldown * cooldownMultiplier)) * 82);
|
||||
|
||||
this.drawTexturedModalRect(mirror ? left + 5 : left + 41, height - 8, 128, 0, l, 6);
|
||||
this.drawTexturedModalRect(mirror ? left + 5 : left + 41, top + 28, 128, 0, l, 6);
|
||||
}
|
||||
|
||||
// Spell illustration
|
||||
this.mc.renderEngine.bindTexture(discovered ? spell.getIcon() : Spells.none.getIcon());
|
||||
|
||||
WizardryUtilities.drawTexturedRect(mirror ? left + 94 : left + 2, top + 2, 0, 0, 32, 32, 32, 32);
|
||||
|
||||
GlStateManager.popAttrib();
|
||||
|
||||
// Blend needs to be left enabled here because otherwise the hotbar becomes opaque
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
GlStateManager.disableLighting();
|
||||
GlStateManager.enableRescaleNormal();
|
||||
GL11.glEnable(GL11.GL_COLOR_MATERIAL);
|
||||
GlStateManager.enableColorMaterial();
|
||||
GlStateManager.enableLighting();
|
||||
itemRender.zLevel = 100.0F;
|
||||
|
||||
@@ -204,7 +204,7 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
GlStateManager.enableLighting();
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
GlStateManager.enableDepth();
|
||||
RenderHelper.enableStandardItemLighting();
|
||||
|
||||
}
|
||||
@@ -219,7 +219,7 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
GlStateManager.disableLighting();
|
||||
GlStateManager.enableRescaleNormal();
|
||||
GL11.glEnable(GL11.GL_COLOR_MATERIAL);
|
||||
GlStateManager.enableColorMaterial();
|
||||
itemRender.zLevel = 0.0F;
|
||||
GlStateManager.disableLighting();
|
||||
|
||||
@@ -239,7 +239,7 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
GlStateManager.enableLighting();
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
GlStateManager.enableDepth();
|
||||
RenderHelper.enableStandardItemLighting();
|
||||
|
||||
}
|
||||
@@ -345,8 +345,8 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
|
||||
}else{
|
||||
|
||||
paragraph = paragraph.replaceAll("NEXT_SPELL_KEY", Keyboard.getKeyName(ClientProxy.NEXT_SPELL.getKeyCode()));
|
||||
paragraph = paragraph.replaceAll("PREVIOUS_SPELL_KEY", Keyboard.getKeyName(ClientProxy.PREVIOUS_SPELL.getKeyCode()));
|
||||
paragraph = paragraph.replaceAll("NEXT_SPELL_KEY", ClientProxy.NEXT_SPELL.getDisplayName());
|
||||
paragraph = paragraph.replaceAll("PREVIOUS_SPELL_KEY", ClientProxy.PREVIOUS_SPELL.getDisplayName());
|
||||
paragraph = paragraph.replaceAll("MANA_PER_CRYSTAL_MINUS_30", "" + (Constants.MANA_PER_CRYSTAL - 30));
|
||||
paragraph = paragraph.replaceAll("MANA_PER_CRYSTAL", "" + Constants.MANA_PER_CRYSTAL);
|
||||
paragraph = paragraph.replaceAll("BASIC_MAX_CHARGE", "" + Tier.BASIC.maxCharge);
|
||||
@@ -365,7 +365,7 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
paragraph = paragraph.replaceAll("SORCERY_COLOUR", Element.SORCERY.getFormattingCode());
|
||||
paragraph = paragraph.replaceAll("HEALING_COLOUR", Element.HEALING.getFormattingCode());
|
||||
paragraph = paragraph.replaceAll("RESET_COLOUR", "\u00A70");
|
||||
paragraph = paragraph.replaceAll("MCVERSION", "1.11.2");
|
||||
paragraph = paragraph.replaceAll("MCVERSION", "1.12.2");
|
||||
paragraph = paragraph.replaceAll("VERSION", Wizardry.VERSION);
|
||||
|
||||
int linesInParagraph = this.fontRenderer
|
||||
@@ -659,51 +659,36 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
craftingGrid.get(2).set(1, new ItemStack(WizardryItems.magic_silk));
|
||||
craftingResult = new ItemStack(WizardryItems.wizard_boots);
|
||||
RECIPES.add(ImmutablePair.of(craftingResult, craftingGrid));
|
||||
|
||||
if(Wizardry.settings.useAlternateScrollRecipe){
|
||||
craftingGrid = createGrid();
|
||||
craftingGrid.get(0).set(0, new ItemStack(Items.PAPER));
|
||||
craftingGrid.get(1).set(0, new ItemStack(Items.STRING));
|
||||
craftingGrid.get(2).set(0, new ItemStack(WizardryItems.magic_crystal));
|
||||
craftingResult = new ItemStack(WizardryItems.blank_scroll);
|
||||
RECIPES.add(ImmutablePair.of(craftingResult, craftingGrid));
|
||||
}else{
|
||||
craftingGrid = createGrid();
|
||||
craftingGrid.get(0).set(0, new ItemStack(Items.PAPER));
|
||||
craftingGrid.get(1).set(0, new ItemStack(Items.STRING));
|
||||
craftingResult = new ItemStack(WizardryItems.blank_scroll);
|
||||
RECIPES.add(ImmutablePair.of(craftingResult, craftingGrid));
|
||||
}
|
||||
|
||||
if(Wizardry.settings.firebombIsCraftable){
|
||||
craftingGrid = createGrid();
|
||||
craftingGrid.get(0).set(0, new ItemStack(Items.BLAZE_POWDER));
|
||||
craftingGrid.get(1).set(0, new ItemStack(Items.BLAZE_POWDER));
|
||||
craftingGrid.get(0).set(1, new ItemStack(Items.GLASS_BOTTLE));
|
||||
craftingGrid.get(1).set(1, new ItemStack(Items.GUNPOWDER));
|
||||
craftingResult = new ItemStack(WizardryItems.firebomb, 3);
|
||||
RECIPES.add(ImmutablePair.of(craftingResult, craftingGrid));
|
||||
}
|
||||
|
||||
if(Wizardry.settings.poisonBombIsCraftable){
|
||||
craftingGrid = createGrid();
|
||||
craftingGrid.get(0).set(0, new ItemStack(Items.SPIDER_EYE));
|
||||
craftingGrid.get(1).set(0, new ItemStack(Items.SPIDER_EYE));
|
||||
craftingGrid.get(0).set(1, new ItemStack(Items.GLASS_BOTTLE));
|
||||
craftingGrid.get(1).set(1, new ItemStack(Items.GUNPOWDER));
|
||||
craftingResult = new ItemStack(WizardryItems.poison_bomb, 3);
|
||||
RECIPES.add(ImmutablePair.of(craftingResult, craftingGrid));
|
||||
}
|
||||
|
||||
if(Wizardry.settings.smokeBombIsCraftable){
|
||||
craftingGrid = createGrid();
|
||||
craftingGrid.get(0).set(0, new ItemStack(Items.COAL));
|
||||
craftingGrid.get(1).set(0, new ItemStack(Items.COAL));
|
||||
craftingGrid.get(0).set(1, new ItemStack(Items.GLASS_BOTTLE));
|
||||
craftingGrid.get(1).set(1, new ItemStack(Items.GUNPOWDER));
|
||||
craftingResult = new ItemStack(WizardryItems.smoke_bomb, 3);
|
||||
RECIPES.add(ImmutablePair.of(craftingResult, craftingGrid));
|
||||
}
|
||||
|
||||
craftingGrid = createGrid();
|
||||
craftingGrid.get(0).set(0, new ItemStack(Items.PAPER));
|
||||
craftingGrid.get(1).set(0, new ItemStack(Items.STRING));
|
||||
craftingResult = new ItemStack(WizardryItems.blank_scroll);
|
||||
RECIPES.add(ImmutablePair.of(craftingResult, craftingGrid));
|
||||
|
||||
craftingGrid = createGrid();
|
||||
craftingGrid.get(0).set(0, new ItemStack(Items.BLAZE_POWDER));
|
||||
craftingGrid.get(1).set(0, new ItemStack(Items.BLAZE_POWDER));
|
||||
craftingGrid.get(0).set(1, new ItemStack(Items.GLASS_BOTTLE));
|
||||
craftingGrid.get(1).set(1, new ItemStack(Items.GUNPOWDER));
|
||||
craftingResult = new ItemStack(WizardryItems.firebomb, 3);
|
||||
RECIPES.add(ImmutablePair.of(craftingResult, craftingGrid));
|
||||
|
||||
craftingGrid = createGrid();
|
||||
craftingGrid.get(0).set(0, new ItemStack(Items.SPIDER_EYE));
|
||||
craftingGrid.get(1).set(0, new ItemStack(Items.SPIDER_EYE));
|
||||
craftingGrid.get(0).set(1, new ItemStack(Items.GLASS_BOTTLE));
|
||||
craftingGrid.get(1).set(1, new ItemStack(Items.GUNPOWDER));
|
||||
craftingResult = new ItemStack(WizardryItems.poison_bomb, 3);
|
||||
RECIPES.add(ImmutablePair.of(craftingResult, craftingGrid));
|
||||
|
||||
craftingGrid = createGrid();
|
||||
craftingGrid.get(0).set(0, new ItemStack(Items.COAL));
|
||||
craftingGrid.get(1).set(0, new ItemStack(Items.COAL));
|
||||
craftingGrid.get(0).set(1, new ItemStack(Items.GLASS_BOTTLE));
|
||||
craftingGrid.get(1).set(1, new ItemStack(Items.GUNPOWDER));
|
||||
craftingResult = new ItemStack(WizardryItems.smoke_bomb, 3);
|
||||
RECIPES.add(ImmutablePair.of(craftingResult, craftingGrid));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import electroblob.wizardry.item.ItemSpectralBow;
|
||||
import electroblob.wizardry.item.ItemWand;
|
||||
import electroblob.wizardry.packet.PacketControlInput;
|
||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import electroblob.wizardry.spell.Flight;
|
||||
import electroblob.wizardry.spell.ShadowWard;
|
||||
@@ -17,19 +18,26 @@ import electroblob.wizardry.tileentity.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.util.WandHelper;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiMerchant;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.client.renderer.RenderItem;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.item.EntityArmorStand;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.village.MerchantRecipe;
|
||||
import net.minecraftforge.client.event.FOVUpdateEvent;
|
||||
import net.minecraftforge.client.event.GuiContainerEvent;
|
||||
import net.minecraftforge.client.event.MouseEvent;
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||
import net.minecraftforge.client.event.RenderLivingEvent;
|
||||
@@ -40,6 +48,7 @@ import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
/**
|
||||
* Event handler responsible for all client-side only events, mostly rendering.
|
||||
@@ -47,6 +56,7 @@ import net.minecraftforge.fml.relauncher.Side;
|
||||
* @author Electroblob
|
||||
* @since Wizardry 1.0
|
||||
*/
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||
public final class WizardryClientEventHandler {
|
||||
|
||||
@@ -115,6 +125,60 @@ public final class WizardryClientEventHandler {
|
||||
event.setNewfov(event.getFov() * 1.0F - maxUseSeconds * 0.15F);
|
||||
}
|
||||
}
|
||||
|
||||
// Brute-force fix for crystals not showing up when a wizard is given a spell book in the trade GUI.
|
||||
@SubscribeEvent
|
||||
public static void onGuiDrawForegroundEvent(GuiContainerEvent.DrawForeground event){
|
||||
|
||||
if(event.getGuiContainer() instanceof GuiMerchant){
|
||||
|
||||
GuiMerchant gui = (GuiMerchant)event.getGuiContainer();
|
||||
// Note that gui.getMerchant() returns an NpcMerchant, not an EntityWizard.
|
||||
|
||||
// Using == the specific item rather than instanceof because that's how trades do it.
|
||||
if(gui.inventorySlots.getSlot(0).getStack().getItem() == WizardryItems.spell_book
|
||||
|| gui.inventorySlots.getSlot(1).getStack().getItem() == WizardryItems.spell_book){
|
||||
|
||||
for(MerchantRecipe trade : gui.getMerchant().getRecipes(Minecraft.getMinecraft().player)){
|
||||
if(trade.getItemToBuy().getItem() == WizardryItems.spell_book && trade.getSecondItemToBuy().isEmpty()){
|
||||
Slot slot = gui.inventorySlots.getSlot(2);
|
||||
// Uses reflection to draw the itemstack
|
||||
// It still doesn't look quite right because the slot highlight is behind the item, but it'll do
|
||||
// until/unless I find a better solution.
|
||||
renderItemAndTooltip(gui, trade.getItemToSell(), slot.xPos, slot.yPos, event.getMouseX(), event.getMouseY(),
|
||||
gui.getSlotUnderMouse() == slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void renderItemAndTooltip(GuiContainer gui, ItemStack stack, int x, int y, int mouseX, int mouseY, boolean tooltip){
|
||||
|
||||
RenderItem renderItem = Minecraft.getMinecraft().getRenderItem();
|
||||
GlStateManager.pushMatrix();
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
GlStateManager.disableLighting();
|
||||
GlStateManager.enableRescaleNormal();
|
||||
GlStateManager.enableColorMaterial();
|
||||
GlStateManager.enableLighting();
|
||||
renderItem.zLevel = 100.0F;
|
||||
|
||||
if(!stack.isEmpty()){
|
||||
renderItem.renderItemAndEffectIntoGUI(stack, x, y);
|
||||
renderItem.renderItemOverlays(Minecraft.getMinecraft().fontRenderer, stack, x, y);
|
||||
|
||||
if(tooltip){
|
||||
gui.drawHoveringText(gui.getItemToolTip(stack), mouseX + gui.getXSize()/2 - gui.width/2,
|
||||
mouseY + gui.getYSize()/2 - gui.height/2);
|
||||
}
|
||||
}
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
GlStateManager.enableLighting();
|
||||
GlStateManager.enableDepth();
|
||||
RenderHelper.enableStandardItemLighting();
|
||||
}
|
||||
|
||||
// Third person
|
||||
@SubscribeEvent
|
||||
@@ -161,7 +225,7 @@ public final class WizardryClientEventHandler {
|
||||
GlStateManager.disableLighting();
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
|
||||
// Disabling depth test allows it to be seen through everything.
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
GlStateManager.disableDepth();
|
||||
GlStateManager.color(1, 1, 1, 1);
|
||||
|
||||
GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height + 0.5, event.getZ());
|
||||
@@ -185,7 +249,7 @@ public final class WizardryClientEventHandler {
|
||||
|
||||
GlStateManager.enableCull();
|
||||
GlStateManager.enableLighting();
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
GlStateManager.enableDepth();
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
@@ -202,7 +266,7 @@ public final class WizardryClientEventHandler {
|
||||
GlStateManager.disableLighting();
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
|
||||
// Disabling depth test allows it to be seen through everything.
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
GlStateManager.disableDepth();
|
||||
GlStateManager.color(1, 1, 1, 1);
|
||||
|
||||
GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height + 0.5, event.getZ());
|
||||
@@ -226,7 +290,7 @@ public final class WizardryClientEventHandler {
|
||||
|
||||
GlStateManager.enableCull();
|
||||
GlStateManager.enableLighting();
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
GlStateManager.enableDepth();
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
@@ -247,7 +311,7 @@ public final class WizardryClientEventHandler {
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
|
||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
// Disabling depth test allows it to be seen through everything.
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
GlStateManager.disableDepth();
|
||||
|
||||
GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height * 0.6, event.getZ());
|
||||
|
||||
@@ -271,7 +335,7 @@ public final class WizardryClientEventHandler {
|
||||
GlStateManager.enableCull();
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.enableLighting();
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
GlStateManager.enableDepth();
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
@@ -285,8 +349,8 @@ public final class WizardryClientEventHandler {
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
GL11.glDepthMask(false);
|
||||
GlStateManager.disableDepth();
|
||||
GlStateManager.depthMask(false);
|
||||
OpenGlHelper.glBlendFunc(770, 771, 1, 0);
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GlStateManager.disableAlpha();
|
||||
@@ -303,8 +367,8 @@ public final class WizardryClientEventHandler {
|
||||
buffer.pos(0.0D, 0.0D, -90.0D).tex(0.0D, 0.0D).endVertex();
|
||||
tessellator.draw();
|
||||
|
||||
GL11.glDepthMask(true);
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
GlStateManager.depthMask(true);
|
||||
GlStateManager.enableDepth();
|
||||
GlStateManager.enableAlpha();
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
@@ -315,8 +379,8 @@ public final class WizardryClientEventHandler {
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
GL11.glDepthMask(false);
|
||||
GlStateManager.disableDepth();
|
||||
GlStateManager.depthMask(false);
|
||||
OpenGlHelper.glBlendFunc(770, 771, 1, 0);
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
GlStateManager.disableAlpha();
|
||||
@@ -333,8 +397,8 @@ public final class WizardryClientEventHandler {
|
||||
buffer.pos(0.0D, 0.0D, -90.0D).tex(0.0D, 0.0D).endVertex();
|
||||
|
||||
tessellator.draw();
|
||||
GL11.glDepthMask(true);
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
GlStateManager.depthMask(true);
|
||||
GlStateManager.enableDepth();
|
||||
GlStateManager.enableAlpha();
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package electroblob.wizardry.client;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.item.ItemWand;
|
||||
import electroblob.wizardry.packet.PacketControlInput;
|
||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Mod.EventBusSubscriber(Side.CLIENT)
|
||||
public class WizardryKeyHandler {
|
||||
|
||||
static boolean NkeyPressed = false;
|
||||
static boolean BkeyPressed = false;
|
||||
|
||||
// Changed to a tick event to allow mouse button keybinds
|
||||
// The 'lag' that happened previously was actually because the code only fired when a keyboard key was pressed!
|
||||
@SubscribeEvent
|
||||
public static void onTickEvent(TickEvent.ClientTickEvent event){
|
||||
|
||||
if(event.phase == TickEvent.Phase.END) return; // Only really needs to be once per tick
|
||||
|
||||
if(Wizardry.proxy instanceof ClientProxy){
|
||||
|
||||
EntityPlayer player = Minecraft.getMinecraft().player;
|
||||
|
||||
if(player != null){
|
||||
|
||||
ItemStack wand = player.getHeldItemMainhand();
|
||||
|
||||
if(!(wand.getItem() instanceof ItemWand)){
|
||||
wand = player.getHeldItemOffhand();
|
||||
// If the player isn't holding a wand, then nothing else needs to be done.
|
||||
if(!(wand.getItem() instanceof ItemWand)) return;
|
||||
}
|
||||
}
|
||||
|
||||
if(ClientProxy.NEXT_SPELL.isKeyDown() && Minecraft.getMinecraft().inGameHasFocus){
|
||||
if(!NkeyPressed){
|
||||
NkeyPressed = true;
|
||||
// Packet building
|
||||
IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.NEXT_SPELL_KEY);
|
||||
WizardryPacketHandler.net.sendToServer(msg);
|
||||
}
|
||||
}else{
|
||||
NkeyPressed = false;
|
||||
}
|
||||
|
||||
if(ClientProxy.PREVIOUS_SPELL.isKeyDown() && Minecraft.getMinecraft().inGameHasFocus){
|
||||
if(!BkeyPressed){
|
||||
BkeyPressed = true;
|
||||
// Packet building
|
||||
IMessage msg = new PacketControlInput.Message(
|
||||
PacketControlInput.ControlType.PREVIOUS_SPELL_KEY);
|
||||
WizardryPacketHandler.net.sendToServer(msg);
|
||||
}
|
||||
}else{
|
||||
BkeyPressed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
package electroblob.wizardry.client.model;
|
||||
|
||||
import net.minecraft.client.model.ModelBiped;
|
||||
import net.minecraft.client.model.ModelRenderer;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
public class ModelWizardArmour extends ModelBiped {
|
||||
public class ModelWizardArmour extends ModelWtfMojang {
|
||||
ModelRenderer Shape1;
|
||||
ModelRenderer Shape2;
|
||||
ModelRenderer Shape3;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package electroblob.wizardry.client.model;
|
||||
|
||||
import net.minecraft.client.model.ModelBiped;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityArmorStand;
|
||||
|
||||
public class ModelWtfMojang extends ModelBiped {
|
||||
|
||||
public ModelWtfMojang(float modelSize, float rotationYOffset, int textureWidth, int textureHeight) {
|
||||
super(modelSize, rotationYOffset, textureWidth, textureHeight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entityIn) {
|
||||
// [VanillaCopy] ModelArmorStandArmor
|
||||
// this prevents helmets from always facing south, and the armor "breathing" on the stand
|
||||
if (entityIn instanceof EntityArmorStand) {
|
||||
EntityArmorStand entityarmorstand = (EntityArmorStand) entityIn;
|
||||
this.bipedHead.rotateAngleX = 0.017453292F * entityarmorstand.getHeadRotation().getX();
|
||||
this.bipedHead.rotateAngleY = 0.017453292F * entityarmorstand.getHeadRotation().getY();
|
||||
this.bipedHead.rotateAngleZ = 0.017453292F * entityarmorstand.getHeadRotation().getZ();
|
||||
this.bipedHead.setRotationPoint(0.0F, 1.0F, 0.0F);
|
||||
this.bipedBody.rotateAngleX = 0.017453292F * entityarmorstand.getBodyRotation().getX();
|
||||
this.bipedBody.rotateAngleY = 0.017453292F * entityarmorstand.getBodyRotation().getY();
|
||||
this.bipedBody.rotateAngleZ = 0.017453292F * entityarmorstand.getBodyRotation().getZ();
|
||||
this.bipedLeftArm.rotateAngleX = 0.017453292F * entityarmorstand.getLeftArmRotation().getX();
|
||||
this.bipedLeftArm.rotateAngleY = 0.017453292F * entityarmorstand.getLeftArmRotation().getY();
|
||||
this.bipedLeftArm.rotateAngleZ = 0.017453292F * entityarmorstand.getLeftArmRotation().getZ();
|
||||
this.bipedRightArm.rotateAngleX = 0.017453292F * entityarmorstand.getRightArmRotation().getX();
|
||||
this.bipedRightArm.rotateAngleY = 0.017453292F * entityarmorstand.getRightArmRotation().getY();
|
||||
this.bipedRightArm.rotateAngleZ = 0.017453292F * entityarmorstand.getRightArmRotation().getZ();
|
||||
this.bipedLeftLeg.rotateAngleX = 0.017453292F * entityarmorstand.getLeftLegRotation().getX();
|
||||
this.bipedLeftLeg.rotateAngleY = 0.017453292F * entityarmorstand.getLeftLegRotation().getY();
|
||||
this.bipedLeftLeg.rotateAngleZ = 0.017453292F * entityarmorstand.getLeftLegRotation().getZ();
|
||||
this.bipedLeftLeg.setRotationPoint(1.9F, 11.0F, 0.0F);
|
||||
this.bipedRightLeg.rotateAngleX = 0.017453292F * entityarmorstand.getRightLegRotation().getX();
|
||||
this.bipedRightLeg.rotateAngleY = 0.017453292F * entityarmorstand.getRightLegRotation().getY();
|
||||
this.bipedRightLeg.rotateAngleZ = 0.017453292F * entityarmorstand.getRightLegRotation().getZ();
|
||||
this.bipedRightLeg.setRotationPoint(-1.9F, 11.0F, 0.0F);
|
||||
copyModelAngles(this.bipedHead, this.bipedHeadwear);
|
||||
} else super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entityIn);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -143,7 +143,6 @@ public abstract class ParticleCustomTexture extends Particle {
|
||||
float rotationYZ, float rotationXY, float rotationXZ){
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.pushAttrib();
|
||||
|
||||
this.applyGLStateChanges();
|
||||
|
||||
@@ -193,7 +192,6 @@ public abstract class ParticleCustomTexture extends Particle {
|
||||
|
||||
this.undoGLStateChanges();
|
||||
|
||||
GlStateManager.popAttrib();
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class RenderMagicLight extends TileEntitySpecialRenderer<TileEntityMagicL
|
||||
GlStateManager.scale((float)tileentity.timer / 10, (float)tileentity.timer / 10,
|
||||
(float)tileentity.timer / 10);
|
||||
}
|
||||
if(tileentity.timer > tileentity.maxTimer - 10){
|
||||
if(tileentity.timer > tileentity.maxTimer - 10 && tileentity.timer <= tileentity.maxTimer){
|
||||
GlStateManager.scale((float)(tileentity.maxTimer - tileentity.timer) / 10,
|
||||
(float)(tileentity.maxTimer - tileentity.timer) / 10,
|
||||
(float)(tileentity.maxTimer - tileentity.timer) / 10);
|
||||
|
||||
@@ -92,24 +92,20 @@ public class CommandViewAllies extends CommandBase {
|
||||
|
||||
if(WizardData.get(player) != null){
|
||||
|
||||
String string = "";
|
||||
Object playerList = null;
|
||||
Set<String> names = WizardData.get(player).allyNames;
|
||||
|
||||
if(!names.isEmpty()){
|
||||
for(String name : names){
|
||||
string = string + name + ", ";
|
||||
}
|
||||
// Cuts the last " ," off of the string.
|
||||
string = string.substring(0, string.length() - 2);
|
||||
playerList = joinNiceStringFromCollection(names);
|
||||
}else{
|
||||
string = I18n.format("commands." + Wizardry.MODID + ":allies.none");
|
||||
playerList = new TextComponentTranslation("commands." + Wizardry.MODID + ":allies.none");
|
||||
}
|
||||
|
||||
if(executeAsOtherPlayer){
|
||||
sender.sendMessage(
|
||||
new TextComponentTranslation("commands." + Wizardry.MODID + ":allies.list_other", player.getName(), string));
|
||||
new TextComponentTranslation("commands." + Wizardry.MODID + ":allies.list_other", player.getName(), playerList));
|
||||
}else{
|
||||
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":allies.list", string));
|
||||
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":allies.list", playerList));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package electroblob.wizardry.enchantment;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.registry.WizardryEnchantments;
|
||||
import electroblob.wizardry.spell.FreezingWeapon;
|
||||
@@ -10,11 +12,15 @@ import net.minecraft.enchantment.EnchantmentHelper;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.ContainerChest;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemBow;
|
||||
import net.minecraft.item.ItemEnchantedBook;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
|
||||
import net.minecraftforge.event.entity.item.ItemTossEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingDropsEvent;
|
||||
@@ -55,11 +61,18 @@ public interface Imbuement {
|
||||
if(stack.isItemEnchanted()){
|
||||
// No need to check what enchantments the item has, since remove() does nothing if the element does not
|
||||
// exist.
|
||||
Map<Enchantment, Integer> enchantments = EnchantmentHelper.getEnchantments(stack);
|
||||
// Removes the magic weapon enchantments from the enchantment map
|
||||
enchantments.entrySet().removeIf(entry -> entry.getKey() instanceof Imbuement);
|
||||
// Applies the new enchantment map to the item
|
||||
EnchantmentHelper.setEnchantments(enchantments, stack);
|
||||
NBTTagList enchantmentList = stack.getItem() == Items.ENCHANTED_BOOK ?
|
||||
ItemEnchantedBook.getEnchantments(stack) : stack.getEnchantmentTagList();
|
||||
// Check all enchantments of the item
|
||||
Iterator<NBTBase> enchantmentIt = enchantmentList.iterator();
|
||||
while(enchantmentIt.hasNext()){
|
||||
NBTTagCompound enchantmentTag = (NBTTagCompound) enchantmentIt.next();
|
||||
Enchantment enchantment = Enchantment.getEnchantmentByID(enchantmentTag.getShort("id"));
|
||||
// If the item contains a magic weapon enchantment, remove it from the item
|
||||
if(enchantment instanceof Imbuement){
|
||||
enchantmentIt.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,18 +83,23 @@ public interface Imbuement {
|
||||
// Still not sure if it's better to set stacks in slots or modify the itemstack list directly, but I would
|
||||
// imagine it's the former.
|
||||
for(Slot slot : event.getContainer().inventorySlots){
|
||||
if(slot.getStack().getItem() instanceof ItemEnchantedBook){
|
||||
ItemStack slotStack = slot.getStack();
|
||||
if(slotStack.getItem() instanceof ItemEnchantedBook){
|
||||
// We don't care about the level of the enchantments
|
||||
Map<Enchantment, Integer> enchantments = EnchantmentHelper.getEnchantments(slot.getStack());
|
||||
NBTTagList enchantmentList = ItemEnchantedBook.getEnchantments(slotStack);
|
||||
// Removes all imbuements
|
||||
if(enchantments.keySet().removeIf(e -> e instanceof Imbuement)){
|
||||
// If any imbuements were removed, replaces the enchantments on the book with the new ones, or
|
||||
// deletes the book entirely if there are none left.
|
||||
if(enchantments.isEmpty()){
|
||||
if(Iterables.removeIf(enchantmentList, tag -> {
|
||||
NBTTagCompound enchantmentTag = (NBTTagCompound) tag;
|
||||
return Enchantment.getEnchantmentByID(enchantmentTag.getShort("id"))
|
||||
instanceof Imbuement;
|
||||
})){
|
||||
// If any imbuements were removed, inform about the removal of the enchantment(s), or
|
||||
// delete the book entirely if there are none left.
|
||||
if(enchantmentList.isEmpty()){
|
||||
slot.putStack(ItemStack.EMPTY); // NOTE: Will need changing in 1.11
|
||||
Wizardry.logger.info("Deleted enchanted book with illegal enchantments");
|
||||
}else{
|
||||
EnchantmentHelper.setEnchantments(enchantments, slot.getStack());
|
||||
// Inform about enchantment removal
|
||||
Wizardry.logger.info("Removed illegal enchantments from enchanted book");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package electroblob.wizardry.entity.living;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
@@ -118,10 +117,10 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
|| (entity instanceof ISummonedCreature || entity instanceof EntityWizard
|
||||
// ... or in the whitelist ...
|
||||
|| Arrays.asList(Wizardry.settings.summonedCreatureTargetsWhitelist)
|
||||
.contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT)))
|
||||
.contains(EntityList.getKey(entity.getClass())))
|
||||
// ... and isn't in the blacklist ...
|
||||
&& !Arrays.asList(Wizardry.settings.summonedCreatureTargetsBlacklist)
|
||||
.contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))){
|
||||
.contains(EntityList.getKey(entity.getClass()))){
|
||||
// ... it can be attacked.
|
||||
return true;
|
||||
}
|
||||
@@ -266,6 +265,21 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
(NBTTagInt tag) -> Spell.get(tag.getInt()));
|
||||
this.hasTower = nbt.getBoolean("hasTower");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxSpawnedInChunk(){
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCanSpawnHere(){
|
||||
// Evil wizards can only spawn in the specified dimensions
|
||||
for(int id : Wizardry.settings.evilWizardDimensions){
|
||||
if(this.dimension == id) return super.getCanSpawnHere();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canDespawn(){
|
||||
|
||||
@@ -17,6 +17,7 @@ import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.util.text.translation.I18n;
|
||||
@@ -51,13 +52,22 @@ public class EntitySpiritHorse extends EntityHorse {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getExperiencePoints(EntityPlayer p_70693_1_){
|
||||
protected int getExperiencePoints(EntityPlayer player){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Item getDropItem(){
|
||||
protected boolean canDropLoot(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Item getDropItem(){
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceLocation getLootTable(){
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.world.DifficultyInstance;
|
||||
@@ -70,11 +71,6 @@ public class EntitySpiritWolf extends EntityWolf {
|
||||
super.onDeath(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getExperiencePoints(EntityPlayer p_70693_1_){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata){
|
||||
|
||||
@@ -147,11 +143,26 @@ public class EntitySpiritWolf extends EntityWolf {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getExperiencePoints(EntityPlayer player){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canDropLoot(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Item getDropItem(){
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceLocation getLootTable(){
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName(){
|
||||
if(getOwner() != null){
|
||||
|
||||
@@ -5,10 +5,11 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
@@ -23,29 +24,29 @@ import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import electroblob.wizardry.util.WandHelper;
|
||||
import electroblob.wizardry.util.WildcardTradeList;
|
||||
import electroblob.wizardry.util.WizardryParticleType;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityAgeable;
|
||||
import net.minecraft.entity.EntityCreature;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.entity.IEntityLivingData;
|
||||
import net.minecraft.entity.IMerchant;
|
||||
import net.minecraft.entity.INpc;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.EntityAIBase;
|
||||
import net.minecraft.entity.ai.EntityAIHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAILookAtTradePlayer;
|
||||
import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
|
||||
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
|
||||
import net.minecraft.entity.ai.EntityAIOpenDoor;
|
||||
import net.minecraft.entity.ai.EntityAIRestrictOpenDoor;
|
||||
import net.minecraft.entity.ai.EntityAISwimming;
|
||||
import net.minecraft.entity.ai.EntityAITradePlayer;
|
||||
import net.minecraft.entity.ai.EntityAIWander;
|
||||
import net.minecraft.entity.ai.EntityAIWatchClosest;
|
||||
import net.minecraft.entity.ai.EntityAIWatchClosest2;
|
||||
import net.minecraft.entity.effect.EntityLightningBolt;
|
||||
import net.minecraft.entity.monster.IMob;
|
||||
import net.minecraft.entity.passive.EntityVillager;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
@@ -75,22 +76,12 @@ import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
import net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
public class EntityWizard extends EntityVillager implements ISpellCaster, IEntityAdditionalSpawnData {
|
||||
|
||||
/* After much debugging, the error in the compiled mod (outside of eclipse) was traced back to this class,
|
||||
* specifically the methods copied in from EntityVillager when I changed this class to extend it. This figures,
|
||||
* since I had 1.2.1 working just fine before I did that, and it was the only thing I changed. Apparently, methods
|
||||
* and fields with obfuscated names like func_129090_a can cause problems when compiled. One of the ones here was
|
||||
* renamed and the other deleted since it was never called. Watch out for this in future (unless, of course, they
|
||||
* are overriding something, in which case it should be fine). */
|
||||
|
||||
// Extending EntityVillager turned out to be a pretty neat thing to do, since now zombies will attack wizards
|
||||
public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISpellCaster, IEntityAdditionalSpawnData {
|
||||
|
||||
private EntityAIAttackSpell spellCastingAI = new EntityAIAttackSpell(this, 0.5D, 14.0F, 30, 50);
|
||||
|
||||
@@ -99,19 +90,21 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
/** The entity selector passed into the new AI methods. */
|
||||
protected Predicate<Entity> targetSelector;
|
||||
|
||||
/** Copy of EntityVillager's buyingList, renamed to avoid confusion. */
|
||||
/** The wizard's trades. */
|
||||
private MerchantRecipeList trades;
|
||||
/** The wizard's current customer. */
|
||||
@Nullable
|
||||
private EntityPlayer customer;
|
||||
|
||||
private int timeUntilReset;
|
||||
|
||||
/** addDefaultEquipmentAndRecipies is called if this is true */
|
||||
private boolean updateRecipes;
|
||||
|
||||
/** Data parameter for the cooldown time for wizards healing themselves. */
|
||||
private static final DataParameter<Integer> HEAL_COOLDOWN = EntityDataManager.createKey(EntityWizard.class,
|
||||
DataSerializers.VARINT);
|
||||
private static final DataParameter<Integer> HEAL_COOLDOWN = EntityDataManager.createKey(EntityWizard.class, DataSerializers.VARINT);
|
||||
/** Data parameter for the wizard's element. */
|
||||
private static final DataParameter<Integer> ELEMENT = EntityDataManager.createKey(EntityWizard.class,
|
||||
DataSerializers.VARINT);
|
||||
private static final DataParameter<Integer> ELEMENT = EntityDataManager.createKey(EntityWizard.class, DataSerializers.VARINT);
|
||||
|
||||
// Field implementations
|
||||
private List<Spell> spells = new ArrayList<Spell>(4);
|
||||
@@ -138,6 +131,8 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
protected void initEntityAI(){
|
||||
|
||||
this.tasks.addTask(0, new EntityAISwimming(this));
|
||||
// Why would you go to the effort of making the IMerchant interface and then have the AI classes only accept
|
||||
// EntityVillager? N
|
||||
this.tasks.addTask(1, new EntityAITradePlayer(this));
|
||||
this.tasks.addTask(1, new EntityAILookAtTradePlayer(this));
|
||||
this.tasks.addTask(4, new EntityAIRestrictOpenDoor(this));
|
||||
@@ -160,10 +155,10 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
if((entity instanceof IMob || entity instanceof ISummonedCreature
|
||||
// ... or in the whitelist ...
|
||||
|| Arrays.asList(Wizardry.settings.summonedCreatureTargetsWhitelist)
|
||||
.contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT)))
|
||||
.contains(EntityList.getKey(entity.getClass())))
|
||||
// ... and isn't in the blacklist ...
|
||||
&& !Arrays.asList(Wizardry.settings.summonedCreatureTargetsBlacklist)
|
||||
.contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))){
|
||||
.contains(EntityList.getKey(entity.getClass()))){
|
||||
// ... it can be attacked.
|
||||
return true;
|
||||
}
|
||||
@@ -221,6 +216,55 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
return this.continuousSpell;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomer(EntityPlayer player){
|
||||
this.customer = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPlayer getCustomer(){
|
||||
return this.customer;
|
||||
}
|
||||
|
||||
public boolean isTrading(){
|
||||
return this.getCustomer() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifySellingItem(ItemStack stack){
|
||||
// Copied from EntityVillager
|
||||
if(!this.world.isRemote && this.livingSoundTime > -this.getTalkInterval() + 20){
|
||||
this.livingSoundTime = -this.getTalkInterval();
|
||||
this.playSound(stack.isEmpty() ? SoundEvents.ENTITY_VILLAGER_NO : SoundEvents.ENTITY_VILLAGER_YES, this.getSoundVolume(), this.getSoundPitch());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld(){
|
||||
return this.world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getPos(){
|
||||
return new BlockPos(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void setRecipes(MerchantRecipeList recipeList){
|
||||
// Apparently nothing goes here, and nothing's here in EntityVillager either...
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName(){
|
||||
return this.getElement().getWizardName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canDespawn(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLivingUpdate(){
|
||||
|
||||
@@ -301,8 +345,7 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
}
|
||||
}
|
||||
|
||||
// Super call removed because EntityVillager's version does things I don't want and the next one up is
|
||||
// in EntityLivingBase and does nothing.
|
||||
super.updateAITasks(); // This actually does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -338,11 +381,6 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName(){
|
||||
return this.getElement().getWizardName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound nbt){
|
||||
|
||||
@@ -369,7 +407,7 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
|
||||
if(nbt.hasKey("trades")){
|
||||
NBTTagCompound nbttagcompound1 = nbt.getCompoundTag("trades");
|
||||
this.trades = new MerchantRecipeList(nbttagcompound1);
|
||||
this.trades = new WildcardTradeList(nbttagcompound1);
|
||||
}
|
||||
|
||||
this.setElement(Element.values()[nbt.getInteger("element")]);
|
||||
@@ -381,16 +419,6 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
nbt.getTagList("towerBlocks", NBT.TAG_LONG), (NBTTagLong tag) -> BlockPos.fromLong(tag.getLong())));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canDespawn(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrading(){
|
||||
return this.getCustomer() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void useRecipe(MerchantRecipe merchantrecipe){
|
||||
|
||||
@@ -428,7 +456,7 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
|
||||
if(this.trades == null){
|
||||
|
||||
this.trades = new MerchantRecipeList();
|
||||
this.trades = new WildcardTradeList();
|
||||
|
||||
// All wizards will buy spell books
|
||||
ItemStack anySpellBook = new ItemStack(WizardryItems.spell_book, 1, OreDictionary.WILDCARD_VALUE);
|
||||
@@ -509,7 +537,7 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
Collections.shuffle(merchantrecipelist);
|
||||
|
||||
if(this.trades == null){
|
||||
this.trades = new MerchantRecipeList();
|
||||
this.trades = new WildcardTradeList();
|
||||
}
|
||||
|
||||
for(int j1 = 0; j1 < merchantrecipelist.size(); ++j1){
|
||||
@@ -659,11 +687,6 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
return new ItemStack(Blocks.STONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfession(VillagerProfession prof){
|
||||
// Disables Forge's stuff.
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata){
|
||||
|
||||
@@ -821,49 +844,72 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copied from their respective AI classes
|
||||
|
||||
public static class EntityAILookAtTradePlayer extends EntityAIWatchClosest {
|
||||
|
||||
private final EntityWizard wizard;
|
||||
|
||||
// EntityVillager overrides (that don't add features)
|
||||
public EntityAILookAtTradePlayer(EntityWizard wizard){
|
||||
super(wizard, EntityPlayer.class, 8.0F);
|
||||
this.wizard = wizard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMating(){
|
||||
return false;
|
||||
@Override
|
||||
public boolean shouldExecute(){
|
||||
if(this.wizard.isTrading()){
|
||||
this.closestEntity = this.wizard.getCustomer();
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class EntityAITradePlayer extends EntityAIBase {
|
||||
|
||||
private final EntityWizard wizard;
|
||||
|
||||
@Override
|
||||
public void setMating(boolean p_70947_1_){
|
||||
}
|
||||
public EntityAITradePlayer(EntityWizard wizard){
|
||||
this.wizard = wizard;
|
||||
this.setMutexBits(5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlaying(boolean p_70939_1_){
|
||||
}
|
||||
@Override
|
||||
public boolean shouldExecute(){
|
||||
|
||||
if(!this.wizard.isEntityAlive()){
|
||||
return false;
|
||||
}else if(this.wizard.isInWater()){
|
||||
return false;
|
||||
}else if(!this.wizard.onGround){
|
||||
return false;
|
||||
}else if(this.wizard.velocityChanged){
|
||||
return false;
|
||||
}else{
|
||||
|
||||
EntityPlayer entityplayer = this.wizard.getCustomer();
|
||||
|
||||
@Override
|
||||
public boolean isPlaying(){
|
||||
return false;
|
||||
}
|
||||
if(entityplayer == null){
|
||||
return false;
|
||||
}else if(this.wizard.getDistanceSq(entityplayer) > 16.0D){
|
||||
return false;
|
||||
}else{
|
||||
return entityplayer.openContainer != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLookingForHome(){
|
||||
}
|
||||
@Override
|
||||
public void startExecuting(){
|
||||
this.wizard.getNavigator().clearPath();
|
||||
}
|
||||
|
||||
// Doesn't say it, but this is in fact nullable.
|
||||
@Override
|
||||
public EntityVillager createChild(EntityAgeable par1EntityAgeable){
|
||||
return null;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void setRecipes(MerchantRecipeList par1MerchantRecipeList){
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStruckByLightning(EntityLightningBolt lightningBolt){
|
||||
// Restores the normal behaviour, replacing EntityVillager's witch conversion.
|
||||
this.attackEntityFrom(DamageSource.LIGHTNING_BOLT, 5.0F);
|
||||
// Entity's version does something strange with the private fire variable, but since I don't have access this
|
||||
// will probably be fine.
|
||||
this.setFire(8);
|
||||
@Override
|
||||
public void resetTask(){
|
||||
this.wizard.setCustomer((EntityPlayer)null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package electroblob.wizardry.entity.living;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@@ -182,18 +181,28 @@ public interface ISummonedCreature extends IEntityAdditionalSpawnData {
|
||||
if(!entity.isInvisible() && isValidTarget(entity)){
|
||||
|
||||
// ... and is a player, they can be attacked, since players can't be in the whitelist or the
|
||||
// blacklist.
|
||||
if(entity instanceof EntityPlayer) return true;
|
||||
// blacklist ...
|
||||
if(entity instanceof EntityPlayer){
|
||||
// ... unless the creature was summoned by a good wizard who the player has not angered.
|
||||
if(getCaster() instanceof EntityWizard){
|
||||
if(((EntityWizard)getCaster()).getRevengeTarget() != entity
|
||||
&& ((EntityWizard)getCaster()).getAttackTarget() != entity) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ... and is a mob, a summoned creature, a wizard ...
|
||||
if((entity instanceof IMob || entity instanceof ISummonedCreature
|
||||
|| (entity instanceof EntityWizard && !(getCaster() instanceof EntityWizard))
|
||||
// ... or in the whitelist ...
|
||||
|| Arrays.asList(Wizardry.settings.summonedCreatureTargetsWhitelist)
|
||||
.contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT)))
|
||||
.contains(EntityList.getKey(entity.getClass())))
|
||||
// ... and isn't in the blacklist ...
|
||||
&& !Arrays.asList(Wizardry.settings.summonedCreatureTargetsBlacklist)
|
||||
.contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))){
|
||||
.contains(EntityList.getKey(entity.getClass()))){
|
||||
// ... it can be attacked.
|
||||
return true;
|
||||
}
|
||||
@@ -362,11 +371,18 @@ public interface ISummonedCreature extends IEntityAdditionalSpawnData {
|
||||
if(event.getSource().isFireDamage()) newSource.setFireDamage();
|
||||
if(event.getSource().isProjectile()) newSource.setProjectile();
|
||||
|
||||
// For some reason Minecraft calculates knockback relative to DamageSource#getEntity. In vanilla this
|
||||
// For some reason Minecraft calculates knockback relative to DamageSource#getTrueSource. In vanilla this
|
||||
// is unnoticeable, but it looks a bit weird with summoned creatures involved - so this fixes that.
|
||||
if(WizardryUtilities.attackEntityWithoutKnockback(event.getEntity(), newSource, event.getAmount())){
|
||||
// Using event.getSource().getTrueSource() as this means the target is knocked back from the minion
|
||||
WizardryUtilities.applyStandardKnockback(event.getSource().getTrueSource(), event.getEntityLiving());
|
||||
((ISummonedCreature)event.getSource().getTrueSource()).onSuccessfulAttack(event.getEntityLiving());
|
||||
// If the target revenge-targeted the summoner, make it revenge-target the minion instead
|
||||
// (if it didn't revenge-target, do nothing)
|
||||
if(event.getEntityLiving().getRevengeTarget() == summoner
|
||||
&& event.getSource().getTrueSource() instanceof EntityLivingBase){
|
||||
event.getEntityLiving().setRevengeTarget((EntityLivingBase)event.getSource().getTrueSource());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
|
||||
/**
|
||||
* Same as {@link EntityMagicProjectile}, but with an additional blast multiplier field which is synced and saved to
|
||||
@@ -13,7 +12,7 @@ import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
* @author Electroblob
|
||||
* @since Wizardry 1.2
|
||||
*/
|
||||
public abstract class EntityBomb extends EntityMagicProjectile implements IEntityAdditionalSpawnData {
|
||||
public abstract class EntityBomb extends EntityMagicProjectile {
|
||||
|
||||
/** The entity blast multiplier. This is now synced and saved centrally from {@link EntityBomb}. */
|
||||
public float blastMultiplier = 1.0f;
|
||||
@@ -38,11 +37,13 @@ public abstract class EntityBomb extends EntityMagicProjectile implements IEntit
|
||||
@Override
|
||||
public void writeSpawnData(ByteBuf buffer){
|
||||
buffer.writeFloat(blastMultiplier);
|
||||
super.writeSpawnData(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSpawnData(ByteBuf buffer){
|
||||
blastMultiplier = buffer.readFloat();
|
||||
super.readSpawnData(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -434,7 +434,7 @@ public abstract class EntityMagicArrow extends Entity implements IProjectile, IE
|
||||
this.onBlockHit();
|
||||
|
||||
if(this.stuckInBlock.getMaterial() != Material.AIR){
|
||||
this.stuckInBlock.getBlock().onEntityCollidedWithBlock(this.world, raytraceresult.getBlockPos(),
|
||||
this.stuckInBlock.getBlock().onEntityCollision(this.world, raytraceresult.getBlockPos(),
|
||||
this.stuckInBlock, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package electroblob.wizardry.entity.projectile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.projectile.EntityThrowable;
|
||||
@@ -25,7 +24,7 @@ import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
* @author Electroblob
|
||||
* @see EntityBomb
|
||||
*/
|
||||
public abstract class EntityMagicProjectile extends EntityThrowable {
|
||||
public abstract class EntityMagicProjectile extends EntityThrowable implements IEntityAdditionalSpawnData {
|
||||
|
||||
public float damageMultiplier = 1.0f;
|
||||
|
||||
@@ -42,6 +41,8 @@ public abstract class EntityMagicProjectile extends EntityThrowable {
|
||||
// This is the standard set of parameters for this method, used by snowballs and ender pearls amongst others.
|
||||
this.shoot(thrower, thrower.rotationPitch, thrower.rotationYaw, 0.0f, this.getSpeed(), 1.0f);
|
||||
this.damageMultiplier = damageMultiplier;
|
||||
// Mojang's 'fix' for the projectile-hitting-thrower bug actually made the problem worse, hence the following line.
|
||||
this.ignoreEntity = thrower;
|
||||
}
|
||||
|
||||
public EntityMagicProjectile(World world, double x, double y, double z){
|
||||
@@ -78,17 +79,17 @@ public abstract class EntityMagicProjectile extends EntityThrowable {
|
||||
// inside a mob using commands, it wouldn't hit that mob. This is so minor that it's not worth sending a packet
|
||||
// for, though it may become more noticeable if spells firing from blocks are added.
|
||||
// TODO: Investigate whether this is still necessary in 1.12
|
||||
if(this.world.isRemote){
|
||||
|
||||
List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().expand(this.motionX, this.motionY, this.motionZ).grow(1.0D));
|
||||
|
||||
for(Entity entity : list){ // Why does vanilla still not use a for-each loop?
|
||||
if(entity.canBeCollidedWith() && this.ticksExisted < 2 && this.ignoreEntity == null){
|
||||
this.ignoreEntity = entity;
|
||||
}
|
||||
}
|
||||
// Pretty sure EntityThrowable handles the rest.
|
||||
}
|
||||
// if(this.world.isRemote){
|
||||
//
|
||||
// List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().expand(this.motionX, this.motionY, this.motionZ).grow(1.0D));
|
||||
//
|
||||
// for(Entity entity : list){ // Why does vanilla still not use a for-each loop?
|
||||
// if(entity.canBeCollidedWith() && this.ticksExisted < 2 && this.ignoreEntity == null){
|
||||
// this.ignoreEntity = entity;
|
||||
// }
|
||||
// }
|
||||
// // Pretty sure EntityThrowable handles the rest.
|
||||
// }
|
||||
|
||||
super.onUpdate();
|
||||
}
|
||||
@@ -105,4 +106,21 @@ public abstract class EntityMagicProjectile extends EntityThrowable {
|
||||
nbttagcompound.setFloat("damageMultiplier", damageMultiplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
// For now, we're only writing when the thrower exists, so subclasses MUST CALL SUPER LAST.
|
||||
// TODO: Figure out whether there's a default value we can write that is never used as an entity id (0? -1? +/-MAX_VALUE?)
|
||||
public void writeSpawnData(ByteBuf data){
|
||||
if(this.getThrower() != null) data.writeInt(this.getThrower().getEntityId());
|
||||
}
|
||||
|
||||
@Override
|
||||
// For now, we're only writing when the thrower exists, so subclasses MUST CALL SUPER LAST.
|
||||
public void readSpawnData(ByteBuf data){
|
||||
if(data.isReadable()){
|
||||
Entity entity = this.world.getEntityByID(data.readInt());
|
||||
if(entity instanceof EntityLivingBase) this.thrower = (EntityLivingBase)entity;
|
||||
this.ignoreEntity = this.thrower;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import electroblob.wizardry.util.MagicDamage;
|
||||
import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||
import electroblob.wizardry.util.WizardryParticleType;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -20,9 +19,6 @@ import net.minecraft.world.World;
|
||||
|
||||
public class EntitySparkBomb extends EntityBomb {
|
||||
|
||||
/** For client use, because thrower field is not visible. */
|
||||
private int casterID;
|
||||
|
||||
public EntitySparkBomb(World par1World){
|
||||
super(par1World);
|
||||
}
|
||||
@@ -84,7 +80,7 @@ public class EntitySparkBomb extends EntityBomb {
|
||||
&& ((EntityPlayer)targets.get(i)).capabilities.isCreativeMode);
|
||||
|
||||
// Detects (client side) if target is the thrower, to stop particles being spawned around them.
|
||||
if(flag && world.isRemote && targets.get(i).getEntityId() == this.casterID) flag = false;
|
||||
//if(flag && world.isRemote && targets.get(i).getEntityId() == this.casterID) flag = false;
|
||||
|
||||
if(flag){
|
||||
|
||||
@@ -120,16 +116,4 @@ public class EntitySparkBomb extends EntityBomb {
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpawnData(ByteBuf data){
|
||||
super.writeSpawnData(data);
|
||||
data.writeInt(this.getThrower().getEntityId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSpawnData(ByteBuf data){
|
||||
super.readSpawnData(data);
|
||||
this.casterID = data.readInt();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package electroblob.wizardry.item;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.constants.Constants;
|
||||
@@ -8,20 +12,19 @@ import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.registry.WizardryAdvancementTriggers;
|
||||
import electroblob.wizardry.registry.WizardryTabs;
|
||||
import electroblob.wizardry.spell.Petrify;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import net.minecraft.client.model.ModelBiped;
|
||||
import net.minecraft.client.util.ITooltipFlag;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.attributes.AttributeModifier;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.EntityEquipmentSlot;
|
||||
import net.minecraft.item.EnumAction;
|
||||
import net.minecraft.item.ItemArmor;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.EnumHandSide;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.ISpecialArmor;
|
||||
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
@@ -29,8 +32,13 @@ import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
public class ItemWizardArmour extends ItemArmor implements ISpecialArmor {
|
||||
public class ItemWizardArmour extends ItemArmor {
|
||||
|
||||
//VanillaCopy, ItemArmor has this set to private for some reason.
|
||||
public static final UUID[] ARMOR_MODIFIERS = new UUID[] {UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B"), UUID.fromString("D8499B04-0E66-4726-AB29-64469D734E0D"), UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E"), UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150")};
|
||||
//Damage reduction values that used to be in WizardryItems.SILK [feet, legs, chest, head]
|
||||
private static int[] reductions = new int[]{2, 4, 5, 2};
|
||||
|
||||
public Element element;
|
||||
|
||||
public ItemWizardArmour(ArmorMaterial material, int renderIndex, EntityEquipmentSlot armourType, Element element){
|
||||
@@ -149,73 +157,41 @@ public class ItemWizardArmour extends ItemArmor implements ISpecialArmor {
|
||||
public boolean getIsRepairable(ItemStack stack, ItemStack par2ItemStack){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArmorProperties getProperties(EntityLivingBase player, ItemStack armor, DamageSource source, double damage,
|
||||
int slotIndex){
|
||||
|
||||
EntityEquipmentSlot slot = getArmorSlotFromIndex(slotIndex);
|
||||
|
||||
if(!source.isUnblockable() && armor.getItemDamage() < armor.getMaxDamage()){
|
||||
if(armor.hasTagCompound() && armor.getTagCompound().getBoolean("legendary")){
|
||||
// Legendary armour gives full 10 shields, like diamond.
|
||||
return new ArmorProperties(0, ArmorMaterial.DIAMOND.getDamageReductionAmount(slot) / 25D,
|
||||
armor.getMaxDamage() + 1 - armor.getItemDamage());
|
||||
}else{
|
||||
return new ArmorProperties(0, this.damageReduceAmount / 25D,
|
||||
armor.getMaxDamage() + 1 - armor.getItemDamage());
|
||||
}
|
||||
}else{
|
||||
return new ArmorProperties(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArmorDisplay(EntityPlayer player, ItemStack armor, int slotIndex){
|
||||
|
||||
EntityEquipmentSlot slot = getArmorSlotFromIndex(slotIndex);
|
||||
|
||||
if(armor.getItemDamage() < armor.getMaxDamage()){
|
||||
if(armor.hasTagCompound() && armor.getTagCompound().getBoolean("legendary")){
|
||||
// Legendary armour gives full 10 shields, like diamond.
|
||||
return ArmorMaterial.DIAMOND.getDamageReductionAmount(slot);
|
||||
}else{
|
||||
return this.getArmorMaterial().getDamageReductionAmount(slot);
|
||||
}
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void damageArmor(EntityLivingBase entity, ItemStack stack, DamageSource source, int damage, int slot){
|
||||
if(stack.getItemDamage() < stack.getMaxDamage()){
|
||||
if(stack.getItemDamage() + damage > stack.getMaxDamage()){
|
||||
// Note for reference: this is the method to use, despite how it sounds attemptDamageItem() is called
|
||||
// by this one, not the other way round.
|
||||
stack.damageItem(stack.getMaxDamage() - stack.getItemDamage(), entity);
|
||||
}else{
|
||||
stack.damageItem(damage, entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the EntityEquipmentSlot for which index() returns an integer equal to the passed in slotIndex and which
|
||||
* is an armour slot (not a hand slot). This only exists because the 1.10.2/1.11.2 versions of Forge still uses an
|
||||
* integer slot index in ISpecialArmor instead of an EntityEquipmentSlot.
|
||||
|
||||
/*
|
||||
* Properly handles the defense value of the armor. This method is responisble for the tooltip on top of
|
||||
* the armor value. It is also what handles armor toughness, but the wizard armor had a value of 0 for that.
|
||||
*/
|
||||
// NOTE: Remove in 1.12.2
|
||||
private EntityEquipmentSlot getArmorSlotFromIndex(int slotIndex){
|
||||
// Had to pick something to begin with.
|
||||
EntityEquipmentSlot slot = EntityEquipmentSlot.HEAD;
|
||||
|
||||
for(EntityEquipmentSlot s : WizardryUtilities.ARMOUR_SLOTS){
|
||||
if(s.getIndex() == slotIndex){
|
||||
slot = s;
|
||||
@Override
|
||||
public Multimap<String, AttributeModifier> getAttributeModifiers(EntityEquipmentSlot slot, ItemStack stack){
|
||||
|
||||
Multimap<String, AttributeModifier> map = HashMultimap.create();
|
||||
|
||||
if(stack.getItemDamage() < stack.getMaxDamage() && this.armorType == slot){
|
||||
|
||||
int defense = reductions[slot.getIndex()];
|
||||
float toughness = 0f;
|
||||
|
||||
if(stack.hasTagCompound() && stack.getTagCompound().getBoolean("legendary")) {
|
||||
defense = ArmorMaterial.DIAMOND.getDamageReductionAmount(slot);
|
||||
toughness = ArmorMaterial.DIAMOND.getToughness();
|
||||
}
|
||||
|
||||
map.put(SharedMonsterAttributes.ARMOR.getName(), new AttributeModifier(ARMOR_MODIFIERS[slot.getIndex()],
|
||||
"Armor modifier", defense, 0));
|
||||
map.put(SharedMonsterAttributes.ARMOR.getName(), new AttributeModifier(ARMOR_MODIFIERS[slot.getIndex()],
|
||||
"Armor toughness", toughness, 0));
|
||||
}
|
||||
return slot;
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
// Fixes wizard armor breaking by disallowing setting damage above the max, since damageArmor is not always called.
|
||||
// Since ISpecialArmor has been removed from this class, this may no longer be necessary, but keeping it won't hurt.
|
||||
@Override
|
||||
public void setDamage(ItemStack stack, int damage) {
|
||||
if(damage <= stack.getMaxDamage()) super.setDamage(stack, damage);
|
||||
else super.setDamage(stack, stack.getMaxDamage());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
||||
@@ -108,7 +108,7 @@ public class RandomSpell extends LootFunction {
|
||||
}
|
||||
}else{
|
||||
// In theory, swapping this line to the commented one should make absolutely no difference.
|
||||
element = elements.get(random.nextInt(tiers.size()));
|
||||
element = elements.get(random.nextInt(elements.size()));
|
||||
// element = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,10 +34,6 @@ public class PacketSyncSettings implements IMessageHandler<Message, IMessage> {
|
||||
}
|
||||
|
||||
private static void copySettings(Message message){
|
||||
Wizardry.settings.firebombIsCraftable = message.settings.firebombIsCraftable;
|
||||
Wizardry.settings.poisonBombIsCraftable = message.settings.poisonBombIsCraftable;
|
||||
Wizardry.settings.smokeBombIsCraftable = message.settings.smokeBombIsCraftable;
|
||||
Wizardry.settings.useAlternateScrollRecipe = message.settings.useAlternateScrollRecipe;
|
||||
Wizardry.settings.discoveryMode = message.settings.discoveryMode;
|
||||
// Wizardry.settings.maxSpellCommandMultiplier = message.settings.maxSpellCommandMultiplier;
|
||||
// Wizardry.settings.castCommandName = message.settings.castCommandName;
|
||||
@@ -65,10 +61,6 @@ public class PacketSyncSettings implements IMessageHandler<Message, IMessage> {
|
||||
// This is also a great reason to have the settings as an actual object.
|
||||
settings = new Settings();
|
||||
// The order is important
|
||||
settings.firebombIsCraftable = buf.readBoolean();
|
||||
settings.poisonBombIsCraftable = buf.readBoolean();
|
||||
settings.smokeBombIsCraftable = buf.readBoolean();
|
||||
settings.useAlternateScrollRecipe = buf.readBoolean();
|
||||
settings.discoveryMode = buf.readBoolean();
|
||||
// settings.maxSpellCommandMultiplier = buf.readDouble();
|
||||
// settings.castCommandName = ByteBufUtils.readUTF8String(buf);
|
||||
@@ -79,10 +71,6 @@ public class PacketSyncSettings implements IMessageHandler<Message, IMessage> {
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buf){
|
||||
buf.writeBoolean(settings.firebombIsCraftable);
|
||||
buf.writeBoolean(settings.poisonBombIsCraftable);
|
||||
buf.writeBoolean(settings.smokeBombIsCraftable);
|
||||
buf.writeBoolean(settings.useAlternateScrollRecipe);
|
||||
buf.writeBoolean(settings.discoveryMode);
|
||||
// buf.writeDouble(settings.maxSpellCommandMultiplier);
|
||||
// ByteBufUtils.writeUTF8String(buf, settings.castCommandName);
|
||||
|
||||
@@ -40,25 +40,18 @@ public final class WizardryBlocks {
|
||||
|
||||
// setSoundType should be public, but in this particular version it isn't... which is a bit of a pain.
|
||||
|
||||
public static final Block arcane_workbench = new BlockArcaneWorkbench().setHardness(1.0F)
|
||||
.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
public static final Block crystal_ore = new BlockCrystalOre(Material.ROCK).setHardness(3.0F)
|
||||
.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
public static final Block arcane_workbench = new BlockArcaneWorkbench().setHardness(1.0F).setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
public static final Block crystal_ore = new BlockCrystalOre(Material.ROCK).setHardness(3.0F).setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
public static final Block petrified_stone = new BlockStatue(Material.ROCK).setHardness(1.5F).setResistance(10.0F);
|
||||
public static final Block ice_statue = new BlockStatue(Material.ICE).setHardness(0.5F).setLightOpacity(3);
|
||||
public static final Block magic_light = new BlockMagicLight(Material.CIRCUITS);
|
||||
public static final Block crystal_flower = new BlockCrystalFlower(Material.PLANTS).setHardness(0.0F)
|
||||
.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
public static final Block crystal_flower = new BlockCrystalFlower(Material.PLANTS).setHardness(0.0F).setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
public static final Block snare = new BlockSnare(Material.PLANTS).setHardness(0.0F);
|
||||
public static final Block transportation_stone = new BlockTransportationStone(Material.ROCK).setHardness(0.0F)
|
||||
.setLightLevel(0.5f).setLightOpacity(0).setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
public static final Block spectral_block = new BlockSpectral(Material.GLASS).setLightLevel(0.7f).setLightOpacity(0)
|
||||
.setBlockUnbreakable().setResistance(6000000.0F);
|
||||
public static final Block crystal_block = new Block(Material.IRON).setHardness(5.0F).setResistance(10.0F)
|
||||
.setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
public static final Block transportation_stone = new BlockTransportationStone(Material.ROCK).setHardness(0.3F).setLightLevel(0.5f).setLightOpacity(0).setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
public static final Block spectral_block = new BlockSpectral(Material.GLASS).setLightLevel(0.7f).setLightOpacity(0).setBlockUnbreakable().setResistance(6000000.0F);
|
||||
public static final Block crystal_block = new Block(Material.IRON).setHardness(5.0F).setResistance(10.0F).setCreativeTab(WizardryTabs.WIZARDRY);
|
||||
public static final Block meteor = new Block(Material.ROCK).setLightLevel(1);
|
||||
public static final Block vanishing_cobweb = new BlockVanishingCobweb(Material.WEB).setLightOpacity(1)
|
||||
.setHardness(4.0F);
|
||||
public static final Block vanishing_cobweb = new BlockVanishingCobweb(Material.WEB).setLightOpacity(1).setHardness(4.0F);
|
||||
|
||||
static{
|
||||
// This is here because Block#setHarvestLevel isn't chainable.
|
||||
@@ -77,7 +70,7 @@ public final class WizardryBlocks {
|
||||
*/
|
||||
public static void registerBlock(IForgeRegistry<Block> registry, Block block, String name){
|
||||
block.setRegistryName(Wizardry.MODID, name);
|
||||
block.setUnlocalizedName(block.getRegistryName().toString());
|
||||
block.setTranslationKey(block.getRegistryName().toString());
|
||||
registry.register(block);
|
||||
}
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ public final class WizardryItems {
|
||||
public static final Item armour_upgrade = new ItemArmourUpgrade();
|
||||
|
||||
public static final ArmorMaterial SILK = EnumHelper.addArmorMaterial("SILK",
|
||||
"wizardry/textures/armour/wizard_armour", 15, new int[]{2, 5, 4, 2}, 0,
|
||||
"wizardry/textures/armour/wizard_armour", 15, new int[]{0, 0, 0, 0}, 0,
|
||||
SoundEvents.ITEM_ARMOR_EQUIP_LEATHER, 0.0F);
|
||||
|
||||
// Saw a post somewhere that said you have to put these in the init methods rather than defining them as constants.
|
||||
@@ -271,7 +271,7 @@ public final class WizardryItems {
|
||||
*/
|
||||
public static void registerItem(IForgeRegistry<Item> registry, Item item, String name){
|
||||
item.setRegistryName(Wizardry.MODID, name);
|
||||
item.setUnlocalizedName(item.getRegistryName().toString());
|
||||
item.setTranslationKey(item.getRegistryName().toString());
|
||||
registry.register(item);
|
||||
}
|
||||
|
||||
|
||||
@@ -73,11 +73,10 @@ import electroblob.wizardry.util.WizardryUtilities;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EnumCreatureType;
|
||||
import net.minecraft.init.Biomes;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.inventory.EntityEquipmentSlot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.FurnaceRecipes;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.storage.loot.LootTableList;
|
||||
@@ -89,7 +88,6 @@ import net.minecraftforge.fml.common.registry.EntityRegistry;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
import net.minecraftforge.oredict.ShapedOreRecipe;
|
||||
import net.minecraftforge.oredict.ShapelessOreRecipe;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
|
||||
@@ -245,53 +243,18 @@ public final class WizardryRegistry {
|
||||
EntityRegistry.registerEgg(registryName, eggColour, spotColour);
|
||||
}
|
||||
|
||||
/** Called from the init method in the main mod class to register all the recipes. */
|
||||
/** Now only deals with the dynamic crafting recipes and the smelting recipes. */
|
||||
@SubscribeEvent
|
||||
public static void registerRecipes(RegistryEvent.Register<IRecipe> event){
|
||||
|
||||
IForgeRegistry<IRecipe> registry = event.getRegistry();
|
||||
|
||||
ItemStack magicCrystalStack = new ItemStack(WizardryItems.magic_crystal);
|
||||
ItemStack magicWandStack = new ItemStack(WizardryItems.magic_wand, 1, Tier.BASIC.maxCharge);
|
||||
ItemStack goldNuggetStack = new ItemStack(Items.GOLD_NUGGET);
|
||||
ItemStack stickStack = new ItemStack(Items.STICK);
|
||||
ItemStack bookStack = new ItemStack(Items.BOOK);
|
||||
ItemStack spellBookStack = new ItemStack(WizardryItems.spell_book, 1, Spells.magic_missile.id());
|
||||
Ingredient crystalFlowerStack = Ingredient.fromStacks(new ItemStack(WizardryBlocks.crystal_flower));
|
||||
ItemStack magicCrystalStack1 = new ItemStack(WizardryItems.magic_crystal, 2);
|
||||
ItemStack magicCrystalStack2 = new ItemStack(WizardryItems.magic_crystal, 9);
|
||||
Ingredient crystalBlockStack = Ingredient.fromStacks(new ItemStack(WizardryBlocks.crystal_block));
|
||||
ItemStack manaFlaskStack = new ItemStack(WizardryItems.mana_flask);
|
||||
Ingredient bottleStack = Ingredient.fromStacks(new ItemStack(Items.GLASS_BOTTLE));
|
||||
Ingredient gunpowderStack = Ingredient.fromStacks(new ItemStack(Items.GUNPOWDER));
|
||||
Ingredient blazePowderStack = Ingredient.fromStacks(new ItemStack(Items.BLAZE_POWDER));
|
||||
Ingredient spiderEyeStack = Ingredient.fromStacks(new ItemStack(Items.SPIDER_EYE));
|
||||
// Coal or charcoal is equally fine, hence the wildcard value
|
||||
Ingredient coalStack = Ingredient.fromStacks(new ItemStack(Items.COAL, 1, OreDictionary.WILDCARD_VALUE));
|
||||
ItemStack firebombStack = new ItemStack(WizardryItems.firebomb, 3);
|
||||
ItemStack poisonBombStack = new ItemStack(WizardryItems.poison_bomb, 3);
|
||||
ItemStack smokeBombStack = new ItemStack(WizardryItems.smoke_bomb, 3);
|
||||
ItemStack scrollStack = new ItemStack(WizardryItems.blank_scroll);
|
||||
Ingredient paperStack = Ingredient.fromStacks(new ItemStack(Items.PAPER));
|
||||
Ingredient stringStack = Ingredient.fromStacks(new ItemStack(Items.STRING));
|
||||
|
||||
registry.register(new ShapedOreRecipe(null, magicWandStack, " x", " y ", "z ", 'x', magicCrystalStack, 'y', stickStack, 'z', goldNuggetStack).setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/magic_wand")));
|
||||
registry.register(new ShapedOreRecipe(null, spellBookStack, " x ", "xyx", " x ", 'x', magicCrystalStack, 'y', bookStack).setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/spellbook")));
|
||||
|
||||
registry.register(new ShapelessOreRecipe(null, magicCrystalStack1, crystalFlowerStack).setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/magic_crystal_1")));
|
||||
registry.register(new ShapelessOreRecipe(null, magicCrystalStack2, crystalBlockStack).setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/magic_crystal_2")));
|
||||
|
||||
if(Wizardry.settings.firebombIsCraftable) registry.register(new ShapelessOreRecipe(null, firebombStack, bottleStack, gunpowderStack, blazePowderStack, blazePowderStack).setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/fire_bomb")));
|
||||
if(Wizardry.settings.poisonBombIsCraftable) registry.register(new ShapelessOreRecipe(null, poisonBombStack, bottleStack, gunpowderStack, spiderEyeStack, spiderEyeStack).setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/poison_bomb")));
|
||||
if(Wizardry.settings.smokeBombIsCraftable) registry.register(new ShapelessOreRecipe(null, smokeBombStack, bottleStack, gunpowderStack, coalStack, coalStack).setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/smoke_bomb")));
|
||||
|
||||
if(Wizardry.settings.useAlternateScrollRecipe){
|
||||
registry.register(new ShapelessOreRecipe(null, scrollStack, paperStack, stringStack, magicCrystalStack).setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/blank_scroll")));
|
||||
}else{
|
||||
registry.register(new ShapelessOreRecipe(null, scrollStack, paperStack, stringStack).setRegistryName(new ResourceLocation(Wizardry.MODID, "recipes/blank_scroll")));
|
||||
}
|
||||
|
||||
|
||||
FurnaceRecipes.instance().addSmeltingRecipeForBlock(WizardryBlocks.crystal_ore, new ItemStack(WizardryItems.magic_crystal), 0.5f);
|
||||
|
||||
// Mana flask recipes
|
||||
|
||||
ItemStack manaFlaskStack = new ItemStack(WizardryItems.mana_flask);
|
||||
|
||||
ItemStack miscWandStack;
|
||||
|
||||
for(Element element : Element.values()){
|
||||
@@ -303,7 +266,6 @@ public final class WizardryRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ItemStack miscArmourStack;
|
||||
|
||||
for(Element element : Element.values()){
|
||||
|
||||
@@ -5,8 +5,6 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Ordering;
|
||||
|
||||
import electroblob.wizardry.item.ItemScroll;
|
||||
import electroblob.wizardry.item.ItemSpellBook;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
@@ -33,7 +31,7 @@ public final class WizardryTabs {
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public ItemStack getTabIconItem(){
|
||||
public ItemStack createIcon(){
|
||||
return new ItemStack(WizardryItems.wizard_handbook);
|
||||
}
|
||||
|
||||
@@ -44,11 +42,12 @@ public final class WizardryTabs {
|
||||
Collections.sort(items, itemSorter);
|
||||
}
|
||||
};
|
||||
|
||||
public static final CreativeTabs SPELLS = new CreativeTabs("ebwizardryspells"){
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public ItemStack getTabIconItem(){
|
||||
public ItemStack createIcon(){
|
||||
return new ItemStack(WizardryItems.spell_book);
|
||||
}
|
||||
|
||||
@@ -103,7 +102,14 @@ public final class WizardryTabs {
|
||||
WizardryItems.wizard_boots_sorcery, WizardryItems.wizard_hat_healing, WizardryItems.wizard_robe_healing,
|
||||
WizardryItems.wizard_leggings_healing, WizardryItems.wizard_boots_healing);
|
||||
|
||||
itemSorter = Ordering.explicit(orderedItemList).onResultOf(ItemStack::getItem);
|
||||
itemSorter = (stack1, stack2) -> {
|
||||
// Neither stack is in the creative tab
|
||||
if(!orderedItemList.contains(stack1.getItem()) && !orderedItemList.contains(stack2.getItem())) return 0;
|
||||
if(!orderedItemList.contains(stack1.getItem())) return 1; // Only stack 2 is in the creative tab
|
||||
if(!orderedItemList.contains(stack2.getItem())) return -1; // Only stack 1 is in the creative tab
|
||||
// Both stacks are in the creative tab
|
||||
return orderedItemList.indexOf(stack1.getItem()) - orderedItemList.indexOf(stack2.getItem());
|
||||
};
|
||||
|
||||
spellItemSorter = (stack1, stack2) -> {
|
||||
|
||||
|
||||
@@ -79,36 +79,41 @@ public class FlameRay extends Spell {
|
||||
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
|
||||
SpellModifiers modifiers){
|
||||
|
||||
Vec3d vec = new Vec3d(target.posX - caster.posX, target.posY - caster.posY, target.posZ - caster.posZ)
|
||||
.normalize();
|
||||
|
||||
if(target != null){
|
||||
|
||||
Vec3d vec = new Vec3d(target.posX - caster.posX, target.posY - caster.posY, target.posZ - caster.posZ).normalize();
|
||||
|
||||
target.setFire(10);
|
||||
WizardryUtilities.attackEntityWithoutKnockback(target,
|
||||
MagicDamage.causeDirectMagicDamage(caster, DamageType.FIRE),
|
||||
3.0f * modifiers.get(SpellModifiers.DAMAGE));
|
||||
}
|
||||
if(world.isRemote){
|
||||
for(int i = 0; i < 20; i++){
|
||||
double x1 = caster.posX + vec.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
|
||||
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.y * i / 2 + world.rand.nextFloat() / 5
|
||||
- 0.1f;
|
||||
double z1 = caster.posZ + vec.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
|
||||
Wizardry.proxy.spawnParticle(WizardryParticleType.MAGIC_FIRE, world, x1, y1, z1,
|
||||
vec.x * modifiers.get(WizardryItems.range_upgrade),
|
||||
vec.y * modifiers.get(WizardryItems.range_upgrade),
|
||||
vec.z * modifiers.get(WizardryItems.range_upgrade), 0);
|
||||
Wizardry.proxy.spawnParticle(WizardryParticleType.MAGIC_FIRE, world, x1, y1, z1,
|
||||
vec.x * modifiers.get(WizardryItems.range_upgrade),
|
||||
vec.y * modifiers.get(WizardryItems.range_upgrade),
|
||||
vec.z * modifiers.get(WizardryItems.range_upgrade), 0);
|
||||
|
||||
if(world.isRemote){
|
||||
for(int i = 0; i < 20; i++){
|
||||
double x1 = caster.posX + vec.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
|
||||
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.y * i / 2 + world.rand.nextFloat() / 5
|
||||
- 0.1f;
|
||||
double z1 = caster.posZ + vec.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
|
||||
Wizardry.proxy.spawnParticle(WizardryParticleType.MAGIC_FIRE, world, x1, y1, z1,
|
||||
vec.x * modifiers.get(WizardryItems.range_upgrade),
|
||||
vec.y * modifiers.get(WizardryItems.range_upgrade),
|
||||
vec.z * modifiers.get(WizardryItems.range_upgrade), 0);
|
||||
Wizardry.proxy.spawnParticle(WizardryParticleType.MAGIC_FIRE, world, x1, y1, z1,
|
||||
vec.x * modifiers.get(WizardryItems.range_upgrade),
|
||||
vec.y * modifiers.get(WizardryItems.range_upgrade),
|
||||
vec.z * modifiers.get(WizardryItems.range_upgrade), 0);
|
||||
}
|
||||
}
|
||||
|
||||
if(ticksInUse % 16 == 0){
|
||||
if(ticksInUse == 0) caster.playSound(SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
|
||||
caster.playSound(WizardrySounds.SPELL_LOOP_FIRE, 0.5F, 1.0f);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
if(ticksInUse % 16 == 0){
|
||||
if(ticksInUse == 0) caster.playSound(SoundEvents.ENTITY_BLAZE_SHOOT, 1, 1);
|
||||
caster.playSound(WizardrySounds.SPELL_LOOP_FIRE, 0.5F, 1.0f);
|
||||
}
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -149,7 +149,7 @@ public class IceAge extends Spell {
|
||||
world.setBlockState(pos.down(), Blocks.OBSIDIAN.getDefaultState());
|
||||
}else if(world.getBlockState(pos.down()) == Blocks.FLOWING_LAVA.getDefaultState()){
|
||||
world.setBlockState(pos.down(), Blocks.COBBLESTONE.getDefaultState());
|
||||
}else{
|
||||
}else if(Blocks.SNOW_LAYER.canPlaceBlockAt(world, pos)){
|
||||
world.setBlockState(pos, Blocks.SNOW_LAYER.getDefaultState());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,39 +72,43 @@ public class LifeDrain extends Spell {
|
||||
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target,
|
||||
SpellModifiers modifiers){
|
||||
|
||||
Vec3d vec = new Vec3d(target.posX - caster.posX, target.posY - caster.posY, target.posZ - caster.posZ)
|
||||
.normalize();
|
||||
|
||||
if(target != null){
|
||||
|
||||
Vec3d vec = new Vec3d(target.posX - caster.posX, target.posY - caster.posY, target.posZ - caster.posZ).normalize();
|
||||
|
||||
if(ticksInUse % 12 == 0){
|
||||
WizardryUtilities.attackEntityWithoutKnockback(target,
|
||||
MagicDamage.causeDirectMagicDamage(caster, DamageType.MAGIC),
|
||||
2.0f * modifiers.get(SpellModifiers.DAMAGE));
|
||||
caster.heal(1);
|
||||
}
|
||||
}
|
||||
if(world.isRemote){
|
||||
for(int i = 5; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
|
||||
// I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet!
|
||||
double x1 = caster.posX + vec.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
|
||||
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.y * i / 2 + world.rand.nextFloat() / 5
|
||||
- 0.1f;
|
||||
double z1 = caster.posZ + vec.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
|
||||
// world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord);
|
||||
if(i % 5 == 0){
|
||||
Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
|
||||
0, 0.1f, 0.0f, 0.0f);
|
||||
|
||||
if(world.isRemote){
|
||||
for(int i = 5; i < (int)(25 * modifiers.get(WizardryItems.range_upgrade)); i += 2){
|
||||
// I figured it out! when on client side, entityplayer.posY is at the eyes, not the feet!
|
||||
double x1 = caster.posX + vec.x * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
|
||||
double y1 = caster.posY + caster.getEyeHeight() - 0.4f + vec.y * i / 2 + world.rand.nextFloat() / 5
|
||||
- 0.1f;
|
||||
double z1 = caster.posZ + vec.z * i / 2 + world.rand.nextFloat() / 5 - 0.1f;
|
||||
// world.spawnParticle("mobSpell", x1, y1, z1, -1*look.xCoord, -1*look.yCoord, -1*look.zCoord);
|
||||
if(i % 5 == 0){
|
||||
Wizardry.proxy.spawnParticle(WizardryParticleType.DARK_MAGIC, world, x1, y1, z1, 0.0d, 0.0d, 0.0d,
|
||||
0, 0.1f, 0.0f, 0.0f);
|
||||
}
|
||||
Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, -0.05 * vec.x * i,
|
||||
-0.05 * vec.y * i, -0.05 * vec.z * i, 8 + world.rand.nextInt(6), 0.5f, 0.0f, 0.0f);
|
||||
}
|
||||
Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, x1, y1, z1, -0.05 * vec.x * i,
|
||||
-0.05 * vec.y * i, -0.05 * vec.z * i, 8 + world.rand.nextInt(6), 0.5f, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
if(ticksInUse % 18 == 0){
|
||||
if(ticksInUse == 0) caster.playSound(WizardrySounds.SPELL_SUMMONING, 1.0F, 0.6f);
|
||||
caster.playSound(WizardrySounds.SPELL_LOOP_CRACKLE, 2.0F, 1.0f);
|
||||
}
|
||||
|
||||
if(ticksInUse % 18 == 0){
|
||||
if(ticksInUse == 0) caster.playSound(WizardrySounds.SPELL_SUMMONING, 1.0F, 0.6f);
|
||||
caster.playSound(WizardrySounds.SPELL_LOOP_CRACKLE, 2.0F, 1.0f);
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package electroblob.wizardry.spell;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
@@ -14,6 +15,7 @@ import electroblob.wizardry.util.SpellModifiers;
|
||||
import electroblob.wizardry.util.WizardryParticleType;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.INpc;
|
||||
@@ -143,7 +145,8 @@ public class MindControl extends Spell {
|
||||
/** Returns true if the given entity can be mind controlled (i.e. is not a player, npc, evil wizard or boss). */
|
||||
public static boolean canControl(EntityLivingBase target){
|
||||
return target instanceof EntityLiving && target.isNonBoss() && !(target instanceof INpc)
|
||||
&& !(target instanceof EntityEvilWizard);
|
||||
&& !(target instanceof EntityEvilWizard) && !Arrays.asList(Wizardry.settings.mindControlTargetsBlacklist)
|
||||
.contains(EntityList.getKey(target.getClass()));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,11 +203,11 @@ public class MindControl extends Spell {
|
||||
|
||||
Entity caster = WizardryUtilities.getEntityByUUID(world, entityNBT.getUniqueId(MindControl.NBT_KEY));
|
||||
|
||||
// If the current target is already a valid mind control target, nothing happens.
|
||||
if(WizardryUtilities.isValidTarget(caster, currentTarget)) return;
|
||||
|
||||
if(caster instanceof EntityLivingBase){
|
||||
|
||||
// If the current target is already a valid mind control target, nothing happens.
|
||||
if(WizardryUtilities.isValidTarget(caster, currentTarget)) return;
|
||||
|
||||
if(MindControl.findMindControlTarget(entity, (EntityLivingBase)caster, world)){
|
||||
// If it worked, skip setting the target to null.
|
||||
return;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package electroblob.wizardry.spell;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -364,8 +365,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
||||
}
|
||||
}
|
||||
|
||||
// ================================================ Static methods
|
||||
// ==================================================
|
||||
// ================================================ Static methods ==================================================
|
||||
|
||||
/**
|
||||
* Returns the total number of registered spells, excluding the 'None' spell. Returns the same number that would be
|
||||
@@ -399,17 +399,16 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
||||
*/
|
||||
public static Spell get(String name){
|
||||
ResourceLocation key = new ResourceLocation(name);
|
||||
if(key.getResourceDomain().equals("minecraft")) key = new ResourceLocation(Wizardry.MODID, name);
|
||||
if(key.getNamespace().equals("minecraft")) key = new ResourceLocation(Wizardry.MODID, name);
|
||||
return ((ForgeRegistry<Spell>)registry).getValue(key);
|
||||
}
|
||||
|
||||
/** Returns a list of all registered spells' registry names, excluding the 'none' spell. Used in commands. */
|
||||
public static String[] getSpellNames(){
|
||||
public static Collection<ResourceLocation> getSpellNames(){
|
||||
// Maybe it would be better to store all of this statically?
|
||||
Set<ResourceLocation> keys = new HashSet<ResourceLocation>(registry.getKeys());
|
||||
keys.remove(registry.getKey(Spells.none));
|
||||
// Streams!
|
||||
return keys.stream().map(ResourceLocation::toString).toArray(String[]::new);
|
||||
return keys;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -331,7 +331,7 @@ public class ContainerArcaneWorkbench extends Container {
|
||||
// This needs to happen so the charging works on the new wand, not the old one.
|
||||
wand = this.getSlot(WAND_SLOT).getStack();
|
||||
|
||||
}else{
|
||||
}else if(WandHelper.isWandUpgrade(upgrade.getItem())){
|
||||
|
||||
// Special upgrades
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
public class TileEntityArcaneWorkbench extends TileEntity implements IInventory, ITickable {
|
||||
|
||||
/** The inventory of the arcane workbench. */
|
||||
private NonNullList<ItemStack> inventory;
|
||||
/** Controls the rotation of the rune. */
|
||||
public float timer = 0;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
@@ -107,8 +108,7 @@ public class TileEntityStatue extends TileEntity implements ITickable {
|
||||
// Breaks the block at light levels of 7 or below, with a higher chance the lower the light level.
|
||||
// The chance is (8 - light level)/12, so at light 0 the chance is 3/4 and at light 7 the chance is 1/12.
|
||||
if(!this.world.isRemote && this.timer % 200 == 0 && this.timer > lifetime && !this.isIce && this.position == 1){
|
||||
// TESTME: There are about 10 different light-related methods in world now... is this the right one?
|
||||
if(this.world.getLight(pos) < this.world.rand.nextInt(12) - 3){
|
||||
if(WizardryUtilities.getLightLevel(world, pos) < this.world.rand.nextInt(12) - 3){
|
||||
// This is all that is needed because destroyBlock invokes the breakBlock function in
|
||||
// BlockPetrifiedStone
|
||||
// and that function handles all the spawning and stuff.
|
||||
|
||||
@@ -64,9 +64,9 @@ import net.minecraft.util.EntityDamageSource;
|
||||
public class MagicDamage extends EntityDamageSource implements IElementalDamage {
|
||||
|
||||
/** The name of the damagesource for direct magic damage from the wizardry mod. */
|
||||
public static final String DIRECT_MAGIC_DAMAGE = "wizardryMagic";
|
||||
public static final String DIRECT_MAGIC_DAMAGE = "wizardry_magic";
|
||||
/** The name of the damagesource for indirect magic damage from the wizardry mod. */
|
||||
public static final String INDIRECT_MAGIC_DAMAGE = "indirectWizardryMagic";
|
||||
public static final String INDIRECT_MAGIC_DAMAGE = "indirect_wizardry_magic";
|
||||
// Technically, I don't need to specify that the classes in this map must extend entity, but it's good practice to.
|
||||
private static final Map<Class<? extends Entity>, DamageType[]> immunityMapping = new HashMap<Class<? extends Entity>, DamageType[]>();
|
||||
|
||||
@@ -169,7 +169,7 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DamageSource called "wizardryMagic" with the given entity as the caster. Use in preference to vanilla
|
||||
* Returns a DamageSource called "wizardry_magic" with the given entity as the caster. Use in preference to vanilla
|
||||
* types to allow things to distinguish between magic and regular melee/swords. Unlike DamageSource.MAGIC, it does
|
||||
* not bypass armour and has a player as the source (rather than nothing). It is still classed as magic damage (for
|
||||
* the record, all this does in vanilla is make witches 85% resistant to it - but that seems kinda right anyway).
|
||||
@@ -190,7 +190,7 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DamageSource called "wizardryMagic" with the given entity as the caster. Use in preference to vanilla
|
||||
* Returns a DamageSource called "wizardry_magic" with the given entity as the caster. Use in preference to vanilla
|
||||
* types to allow things to distinguish between magic and regular melee/swords. Unlike DamageSource.MAGIC, it does
|
||||
* not bypass armour and has a player as the source (rather than nothing). It is still classed as magic damage (for
|
||||
* the record, all this does in vanilla is make witches 85% resistant to it - but that seems kinda right anyway).
|
||||
@@ -212,7 +212,7 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DamageSource called "indirectWizardryMagic" with the player as the caster. Use in preference to vanilla
|
||||
* Returns a DamageSource called "indirect_wizardry_magic" with the player as the caster. Use in preference to vanilla
|
||||
* types to allow things to distinguish between magic and regular arrows/throwables. Unlike
|
||||
* DamageSource.causeIndirectMagicDamage, it does not bypass armour. It is still classed as magic damage (for the
|
||||
* record, all this does in vanilla is make witches 85% resistant to it - but that seems kinda right anyway).
|
||||
@@ -234,7 +234,7 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a DamageSource called "indirectWizardryMagic" with the player as the caster. Use in preference to vanilla
|
||||
* Returns a DamageSource called "indirect_wizardry_magic" with the player as the caster. Use in preference to vanilla
|
||||
* types to allow things to distinguish between magic and regular arrows/throwables. Unlike
|
||||
* DamageSource.causeIndirectMagicDamage, it does not bypass armour. It is still classed as magic damage (for the
|
||||
* record, all this does in vanilla is make witches 85% resistant to it - but that seems kinda right anyway).
|
||||
|
||||
@@ -107,7 +107,7 @@ public final class WandHelper {
|
||||
|
||||
int selectedSpell = wand.getTagCompound().getInteger(SELECTED_SPELL_KEY);
|
||||
|
||||
if(selectedSpell < spells.length){
|
||||
if(selectedSpell >= 0 && selectedSpell < spells.length){
|
||||
return spells[selectedSpell];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package electroblob.wizardry.util;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.village.MerchantRecipe;
|
||||
import net.minecraft.village.MerchantRecipeList;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
/** Custom version of {@link MerchantRecipeList} which allows wildcard recipes (i.e. trades which accept items with any
|
||||
* damage value). Function is otherwise identical. For some reason this feature was removed in 1.11.
|
||||
* @author Electroblob
|
||||
* @since Wizardry 4.1 */
|
||||
@SuppressWarnings("serial")
|
||||
public class WildcardTradeList extends MerchantRecipeList {
|
||||
|
||||
public WildcardTradeList(){
|
||||
super();
|
||||
}
|
||||
|
||||
public WildcardTradeList(NBTTagCompound tag){
|
||||
super(tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MerchantRecipe canRecipeBeUsed(ItemStack offer1, ItemStack offer2, int index){
|
||||
|
||||
if(index > 0 && index < this.size()){
|
||||
|
||||
MerchantRecipe merchantrecipe1 = (MerchantRecipe)this.get(index);
|
||||
return !this.areItemStacksExactlyEqual(offer1, merchantrecipe1.getItemToBuy()) || (!offer2.isEmpty() || merchantrecipe1.hasSecondItemToBuy()) && (!merchantrecipe1.hasSecondItemToBuy() || !this.areItemStacksExactlyEqual(offer2, merchantrecipe1.getSecondItemToBuy())) || offer1.getCount() < merchantrecipe1.getItemToBuy().getCount() || merchantrecipe1.hasSecondItemToBuy() && offer2.getCount() < merchantrecipe1.getSecondItemToBuy().getCount() ? null : merchantrecipe1;
|
||||
|
||||
}else{
|
||||
|
||||
for(int i = 0; i < this.size(); ++i){
|
||||
|
||||
MerchantRecipe merchantrecipe = (MerchantRecipe)this.get(i);
|
||||
|
||||
if (this.areItemStacksExactlyEqual(offer1, merchantrecipe.getItemToBuy()) && offer1.getCount() >= merchantrecipe.getItemToBuy().getCount() && (!merchantrecipe.hasSecondItemToBuy() && offer2.isEmpty() || merchantrecipe.hasSecondItemToBuy() && this.areItemStacksExactlyEqual(offer2, merchantrecipe.getSecondItemToBuy()) && offer2.getCount() >= merchantrecipe.getSecondItemToBuy().getCount())){
|
||||
return merchantrecipe;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean areItemStacksExactlyEqual(ItemStack stack1, ItemStack stack2){
|
||||
// Added to allow wildcards; this line is the only actual change.
|
||||
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.
|
||||
&& stack1.getItem() == stack2.getItem()) return true;
|
||||
|
||||
return ItemStack.areItemsEqual(stack1, stack2) && (!stack2.hasTagCompound() || stack1.hasTagCompound() && NBTUtil.areNBTEquals(stack2.getTagCompound(), stack1.getTagCompound(), false));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -98,6 +98,26 @@ public final class WizardryUtilities {
|
||||
// SECTION Block/Entity/World Utilities
|
||||
// ===============================================================================================================
|
||||
|
||||
/**
|
||||
* Returns the actual light level, taking natural light (skylight) and artificial light (block light) into account.
|
||||
* This uses the same logic as mob spawning.
|
||||
*
|
||||
* @return The light level, from 0 (pitch darkness) to 15 (full daylight/at a torch).
|
||||
*/
|
||||
public static int getLightLevel(World world, BlockPos pos){
|
||||
|
||||
int i = world.getLightFromNeighbors(pos);
|
||||
|
||||
if(world.isThundering()){
|
||||
int j = world.getSkylightSubtracted();
|
||||
world.setSkylightSubtracted(10);
|
||||
i = world.getLightFromNeighbors(pos);
|
||||
world.setSkylightSubtracted(j);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the block at the given coordinates can be replaced by another one (works as if a block is being
|
||||
* placed by a player). True for air, liquids, vines, tall grass and snow layers but not for flowers, signs etc.
|
||||
@@ -520,7 +540,7 @@ public final class WizardryUtilities {
|
||||
|
||||
Vec3d start = new Vec3d(entity.posX, entity.getEntityBoundingBox().minY + entity.getEyeHeight(), entity.posZ);
|
||||
Vec3d look = entity.getLookVec();
|
||||
Vec3d end = start.addVector(look.x * range, look.y * range, look.z * range);
|
||||
Vec3d end = start.add(look.x * range, look.y * range, look.z * range);
|
||||
return world.rayTraceBlocks(start, end, hitLiquids);
|
||||
}
|
||||
|
||||
@@ -873,7 +893,7 @@ public final class WizardryUtilities {
|
||||
// The original tag list should remain unchanged, hence the copy.
|
||||
NBTTagList tagList2 = (NBTTagList)tagList.copy();
|
||||
|
||||
while(!tagList2.hasNoTags()){
|
||||
while(!tagList2.isEmpty()){
|
||||
NBTBase tag = tagList2.removeTag(0);
|
||||
// Why oh why is NBTTagList not parametrised? It even has a tagType field, so it must know!
|
||||
try{
|
||||
@@ -942,7 +962,7 @@ public final class WizardryUtilities {
|
||||
*
|
||||
* @return False under any of the following circumstances, true otherwise:
|
||||
* <p>
|
||||
* - Either entity is null
|
||||
* - The target is null
|
||||
* <p>
|
||||
* - The target is the attacker (this isn't as stupid as it sounds - anything with an AoE might cause this
|
||||
* to be true, as can summoned creatures)
|
||||
@@ -951,10 +971,18 @@ public final class WizardryUtilities {
|
||||
* attacker need not be an ally of the target)
|
||||
* <p>
|
||||
* - The target is a creature that was summoned/controlled by the attacker or by an ally of the attacker.
|
||||
* <p>
|
||||
* <i>As of wizardry 4.1.2, this method now returns <b>true</b> instead of false if the attacker is null. This
|
||||
* is because in the vast majority of cases, it makes more sense this way: if a construct has no caster, it
|
||||
* should affect all entities; if a minion has no caster is should target all entities; etc.</i>
|
||||
*/
|
||||
public static boolean isValidTarget(Entity attacker, Entity target){
|
||||
|
||||
if(attacker == null || target == null) return false;
|
||||
// Always return true if the attacker is null
|
||||
if(attacker == null) return true;
|
||||
|
||||
// Always return false if the target is null
|
||||
if(target == null) return false;
|
||||
|
||||
// Tests whether the target is the attacker
|
||||
if(target == attacker) return false;
|
||||
|
||||
@@ -655,20 +655,35 @@ commands.ebwizardry:discoverspell.removespell=Removed %1$s from %2$s's spell dis
|
||||
|
||||
config.ebwizardry.title.general=Mod Options
|
||||
|
||||
config.ebwizardry.category.spells=Configure Spells
|
||||
config.ebwizardry.category.gameplay=Gameplay Settings
|
||||
config.ebwizardry.category.gameplay.tooltip=Configure wizardry's general gameplay
|
||||
config.ebwizardry.title.gameplay=Gameplay Settings
|
||||
config.ebwizardry.subtitle.gameplay=Global settings that affect game mechanics.
|
||||
|
||||
config.ebwizardry.category.worldgen=World Generation Settings
|
||||
config.ebwizardry.category.worldgen.tooltip=Configure wizardry's world generation features
|
||||
config.ebwizardry.title.worldgen=World Generation Settings
|
||||
config.ebwizardry.subtitle.worldgen=Settings that affect world generation.
|
||||
|
||||
config.ebwizardry.category.commands=Command Settings
|
||||
config.ebwizardry.category.commands.tooltip=Configure wizardry's commands
|
||||
config.ebwizardry.title.commands=Command Settings
|
||||
config.ebwizardry.subtitle.commands=Settings for the commands added by Wizardry.
|
||||
|
||||
config.ebwizardry.category.client=Client Settings
|
||||
config.ebwizardry.category.client.tooltip=Configure wizardry's display and controls
|
||||
config.ebwizardry.title.client=Client Settings
|
||||
config.ebwizardry.subtitle.client=Client-side settings that only affect the local minecraft game.
|
||||
|
||||
config.ebwizardry.category.spells=Spell Configuration
|
||||
config.ebwizardry.category.spells.tooltip=Select which spells are enabled
|
||||
config.ebwizardry.title.spells=Spell Configuration
|
||||
config.ebwizardry.subtitle.spells=Set a spell to false to disable it.
|
||||
|
||||
config.ebwizardry.category.resistances=Configure Resistances
|
||||
config.ebwizardry.category.resistances=Resistance Configuration
|
||||
config.ebwizardry.category.resistances.tooltip=Configure which mobs are immune to different types of magic
|
||||
config.ebwizardry.title.resistances=Resistance Configuration
|
||||
config.ebwizardry.subtitle.resistances=See descriptions of individual options for more details.
|
||||
|
||||
config.ebwizardry.category.ids=Configure IDs
|
||||
config.ebwizardry.category.ids.tooltip=Change the IDs used by wizardry
|
||||
config.ebwizardry.title.ids=ID Configuration
|
||||
config.ebwizardry.subtitle.ids=Change these IDs if they conflict with another mod.
|
||||
config.ebwizardry.subtitle.resistances=Settings which allow entities to be made immune to certain types of magic.
|
||||
|
||||
config.ebwizardry.tower_rarity=Tower Rarity
|
||||
config.ebwizardry.ore_dimensions=Ore Dimensions
|
||||
@@ -685,7 +700,7 @@ config.ebwizardry.show_summoned_creature_names=Show Summoned Creature Names
|
||||
config.ebwizardry.friendly_fire=Friendly Fire
|
||||
config.ebwizardry.telekinetic_disarmament=Telekinetic Disarmament
|
||||
config.ebwizardry.discovery_mode=Discovery Mode
|
||||
config.ebwizardry.enable_shift_scrolling=Enable Shift-_scrolling
|
||||
config.ebwizardry.enable_shift_scrolling=Enable Shift-scrolling
|
||||
config.ebwizardry.minion_revenge_targeting=Minion Revenge Targeting
|
||||
config.ebwizardry.player_damage_scaling=Player Damage Scaling Factor
|
||||
config.ebwizardry.npc_damage_scaling=NPC Damage Scaling Factor
|
||||
@@ -697,6 +712,8 @@ config.ebwizardry.cast_command_name=Cast Spell Command Name
|
||||
config.ebwizardry.discoverspell_command_name=Discover Spell Command Name
|
||||
config.ebwizardry.ally_command_name=Set Ally Command Name
|
||||
config.ebwizardry.allies_command_name=View Allies Command Name
|
||||
config.ebwizardry.mind_control_targets_blacklist=Mind Control Targets Blacklist
|
||||
config.ebwizardry.evil_wizard_dimensions=Evil Wizard Dimensions
|
||||
|
||||
config.ebwizardry.mobs_immune_to_fire=Mobs Immune To Fire
|
||||
config.ebwizardry.mobs_immune_to_ice=Mobs Immune To Ice
|
||||
@@ -717,25 +734,27 @@ config.ebwizardry.use_alternate_scroll_recipe.tooltip=Whether to require a magic
|
||||
config.ebwizardry.teleport_through_unbreakable_blocks.tooltip=Whether players are allowed to teleport through unbreakable blocks (e.g. bedrock) using the phase step spell.
|
||||
config.ebwizardry.show_summoned_creature_names.tooltip=Whether to show summoned creatures' names and owners above their heads.
|
||||
config.ebwizardry.friendly_fire.tooltip=Whether to allow players to damage their designated allies using magic.
|
||||
config.ebwizardry.telekinetic_disarmament.tooltip=Whether to allow players to disarm other players using the telekinesis spell.ebwizardry: Set to false to prevent stealing of items.
|
||||
config.ebwizardry.telekinetic_disarmament.tooltip=Whether to allow players to disarm other players using the telekinesis spell. Set to false to prevent stealing of items.
|
||||
config.ebwizardry.discovery_mode.tooltip=For those who like a sense of mystery! When set to true, spells you haven't cast yet will be unreadable until you cast them (on a per-world basis). Has no effect when in creative mode. Spells of identification will be unobtainable in survival mode if this is false.
|
||||
config.ebwizardry.enable_shift_scrolling.tooltip=Whether you can switch between spells on a wand by scrolling with the mouse wheel while sneaking. Note that this will only affect you; other players connected to the same server obey their own settings.
|
||||
config.ebwizardry.minion_revenge_targeting.tooltip=Whether summoned creatures can revenge attack their owner if their owner attacks them.
|
||||
config.ebwizardry.player_damage_scaling.tooltip=Global damage scaling factor for the damage dealt by players casting spells, relative to 1.
|
||||
config.ebwizardry.npc_damage_scaling.tooltip=Global damage scaling factor for the damage dealt by NPCs casting spells, relative to 1.
|
||||
config.ebwizardry.cast_command_multiplier_limit.tooltip=Upper limit for the multipliers passed into the /cast command. This is here to stop players from accidentally breaking a world/server. Large blast mutipliers can cause extreme lag - you have been warned!
|
||||
config.ebwizardry.summoned_creature_targets_whitelist.tooltip=List of names of entities which summoned creatures and wizards are allowed to attack, in addition to the defaults. Add mod creatures to this list if you want summoned creatures to attack them and they aren't already doing so. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry.wizard).
|
||||
config.ebwizardry.summoned_creature_targets_blacklist.tooltip=List of names of entities which summoned creatures and wizards are specifically not allowed to attack, overriding the defaults and the whitelist. Add creatures to this list if allowing them to be attacked causes problems or is too destructive (removing creepers from this list is done at your own risk!). Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry.wizard).
|
||||
config.ebwizardry.summoned_creature_targets_whitelist.tooltip=List of names of entities which summoned creatures and wizards are allowed to attack, in addition to the defaults. Add mod creatures to this list if you want summoned creatures to attack them and they aren't already doing so. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
config.ebwizardry.summoned_creature_targets_blacklist.tooltip=List of names of entities which summoned creatures and wizards are specifically not allowed to attack, overriding the defaults and the whitelist. Add creatures to this list if allowing them to be attacked causes problems or is too destructive (removing creepers from this list is done at your own risk!). Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
config.ebwizardry.spell_hud_position.tooltip=The position of the spell HUD.
|
||||
config.ebwizardry.cast_command_name.tooltip=The name of the /cast command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /cast you would type /magic instead.
|
||||
config.ebwizardry.discoverspell_command_name.tooltip=The name of the /discoverspell command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /discoverspell you would type /magic instead.
|
||||
config.ebwizardry.ally_command_name.tooltip=The name of the /ally command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /ally you would type /magic instead.
|
||||
config.ebwizardry.allies_command_name.tooltip=The name of the /allies command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /allies you would type /magic instead.
|
||||
config.ebwizardry.mind_control_targets_blacklist.tooltip=List of names of entities which cannot be mind controlled, in addition to the defaults. Add creatures to this list if allowing them to be mind-controlled causes problems or could be exploited. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
config.ebwizardry.evil_wizard_dimensions.tooltip=List of dimension ids in which evil wizards can spawn.
|
||||
|
||||
config.ebwizardry.mobs_immune_to_fire.tooltip=List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry.wizard).
|
||||
config.ebwizardry.mobs_immune_to_ice.tooltip=List of names of entities that are immune to ice, in addition to the defaults. Add mod creatures to this list if you want them to be immune to ice magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry.wizard).
|
||||
config.ebwizardry.mobs_immune_to_lightning.tooltip=List of names of entities that are immune to lightning, in addition to the defaults. Add mod creatures to this list if you want them to be immune to lightning magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry.wizard).
|
||||
config.ebwizardry.mobs_immune_to_wither.tooltip=List of names of entities that are immune to wither effects, in addition to the defaults. Add mod creatures to this list if you want them to be immune to withering magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry.wizard).
|
||||
config.ebwizardry.mobs_immune_to_poison.tooltip=List of names of entities that are immune to poison, in addition to the defaults. Add mod creatures to this list if you want them to be immune to poison magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry.wizard).
|
||||
config.ebwizardry.mobs_immune_to_fire.tooltip=List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
config.ebwizardry.mobs_immune_to_ice.tooltip=List of names of entities that are immune to ice, in addition to the defaults. Add mod creatures to this list if you want them to be immune to ice magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
config.ebwizardry.mobs_immune_to_lightning.tooltip=List of names of entities that are immune to lightning, in addition to the defaults. Add mod creatures to this list if you want them to be immune to lightning magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
config.ebwizardry.mobs_immune_to_wither.tooltip=List of names of entities that are immune to wither effects, in addition to the defaults. Add mod creatures to this list if you want them to be immune to withering magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
config.ebwizardry.mobs_immune_to_poison.tooltip=List of names of entities that are immune to poison, in addition to the defaults. Add mod creatures to this list if you want them to be immune to poison magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
|
||||
wizard.debug=%1$s, %2$s, %3$s
|
||||
|
||||
@@ -655,20 +655,35 @@ commands.ebwizardry:discoverspell.removespell=Removed %1$s from %2$s's spell dis
|
||||
|
||||
config.ebwizardry.title.general=Mod Options
|
||||
|
||||
config.ebwizardry.category.spells=Configure Spells
|
||||
config.ebwizardry.category.gameplay=Gameplay Settings
|
||||
config.ebwizardry.category.gameplay.tooltip=Configure wizardry's general gameplay
|
||||
config.ebwizardry.title.gameplay=Gameplay Settings
|
||||
config.ebwizardry.subtitle.gameplay=Global settings that affect game mechanics.
|
||||
|
||||
config.ebwizardry.category.worldgen=World Generation Settings
|
||||
config.ebwizardry.category.worldgen.tooltip=Configure wizardry's world generation features
|
||||
config.ebwizardry.title.worldgen=World Generation Settings
|
||||
config.ebwizardry.subtitle.worldgen=Settings that affect world generation.
|
||||
|
||||
config.ebwizardry.category.commands=Command Settings
|
||||
config.ebwizardry.category.commands.tooltip=Configure wizardry's commands
|
||||
config.ebwizardry.title.commands=Command Settings
|
||||
config.ebwizardry.subtitle.commands=Settings for the commands added by Wizardry.
|
||||
|
||||
config.ebwizardry.category.client=Client Settings
|
||||
config.ebwizardry.category.client.tooltip=Configure wizardry's display and controls
|
||||
config.ebwizardry.title.client=Client Settings
|
||||
config.ebwizardry.subtitle.client=Client-side settings that only affect the local minecraft game.
|
||||
|
||||
config.ebwizardry.category.spells=Spell Configuration
|
||||
config.ebwizardry.category.spells.tooltip=Select which spells are enabled
|
||||
config.ebwizardry.title.spells=Spell Configuration
|
||||
config.ebwizardry.subtitle.spells=Set a spell to false to disable it.
|
||||
|
||||
config.ebwizardry.category.resistances=Configure Resistances
|
||||
config.ebwizardry.category.resistances=Resistance Configuration
|
||||
config.ebwizardry.category.resistances.tooltip=Configure which mobs are immune to different types of magic
|
||||
config.ebwizardry.title.resistances=Resistance Configuration
|
||||
config.ebwizardry.subtitle.resistances=See descriptions of individual options for more details.
|
||||
|
||||
config.ebwizardry.category.ids=Configure IDs
|
||||
config.ebwizardry.category.ids.tooltip=Change the IDs used by wizardry
|
||||
config.ebwizardry.title.ids=ID Configuration
|
||||
config.ebwizardry.subtitle.ids=Change these IDs if they conflict with another mod.
|
||||
config.ebwizardry.subtitle.resistances=Settings which allow entities to be made immune to certain types of magic.
|
||||
|
||||
config.ebwizardry.tower_rarity=Tower Rarity
|
||||
config.ebwizardry.ore_dimensions=Ore Dimensions
|
||||
@@ -685,7 +700,7 @@ config.ebwizardry.show_summoned_creature_names=Show Summoned Creature Names
|
||||
config.ebwizardry.friendly_fire=Friendly Fire
|
||||
config.ebwizardry.telekinetic_disarmament=Telekinetic Disarmament
|
||||
config.ebwizardry.discovery_mode=Discovery Mode
|
||||
config.ebwizardry.enable_shift_scrolling=Enable Shift-_scrolling
|
||||
config.ebwizardry.enable_shift_scrolling=Enable Shift-scrolling
|
||||
config.ebwizardry.minion_revenge_targeting=Minion Revenge Targeting
|
||||
config.ebwizardry.player_damage_scaling=Player Damage Scaling Factor
|
||||
config.ebwizardry.npc_damage_scaling=NPC Damage Scaling Factor
|
||||
@@ -697,6 +712,8 @@ config.ebwizardry.cast_command_name=Cast Spell Command Name
|
||||
config.ebwizardry.discoverspell_command_name=Discover Spell Command Name
|
||||
config.ebwizardry.ally_command_name=Set Ally Command Name
|
||||
config.ebwizardry.allies_command_name=View Allies Command Name
|
||||
config.ebwizardry.mind_control_targets_blacklist=Mind Control Targets Blacklist
|
||||
config.ebwizardry.evil_wizard_dimensions=Evil Wizard Dimensions
|
||||
|
||||
config.ebwizardry.mobs_immune_to_fire=Mobs Immune To Fire
|
||||
config.ebwizardry.mobs_immune_to_ice=Mobs Immune To Ice
|
||||
@@ -717,25 +734,27 @@ config.ebwizardry.use_alternate_scroll_recipe.tooltip=Whether to require a magic
|
||||
config.ebwizardry.teleport_through_unbreakable_blocks.tooltip=Whether players are allowed to teleport through unbreakable blocks (e.g. bedrock) using the phase step spell.
|
||||
config.ebwizardry.show_summoned_creature_names.tooltip=Whether to show summoned creatures' names and owners above their heads.
|
||||
config.ebwizardry.friendly_fire.tooltip=Whether to allow players to damage their designated allies using magic.
|
||||
config.ebwizardry.telekinetic_disarmament.tooltip=Whether to allow players to disarm other players using the telekinesis spell.ebwizardry: Set to false to prevent stealing of items.
|
||||
config.ebwizardry.telekinetic_disarmament.tooltip=Whether to allow players to disarm other players using the telekinesis spell. Set to false to prevent stealing of items.
|
||||
config.ebwizardry.discovery_mode.tooltip=For those who like a sense of mystery! When set to true, spells you haven't cast yet will be unreadable until you cast them (on a per-world basis). Has no effect when in creative mode. Spells of identification will be unobtainable in survival mode if this is false.
|
||||
config.ebwizardry.enable_shift_scrolling.tooltip=Whether you can switch between spells on a wand by scrolling with the mouse wheel while sneaking. Note that this will only affect you; other players connected to the same server obey their own settings.
|
||||
config.ebwizardry.minion_revenge_targeting.tooltip=Whether summoned creatures can revenge attack their owner if their owner attacks them.
|
||||
config.ebwizardry.player_damage_scaling.tooltip=Global damage scaling factor for the damage dealt by players casting spells, relative to 1.
|
||||
config.ebwizardry.npc_damage_scaling.tooltip=Global damage scaling factor for the damage dealt by NPCs casting spells, relative to 1.
|
||||
config.ebwizardry.cast_command_multiplier_limit.tooltip=Upper limit for the multipliers passed into the /cast command. This is here to stop players from accidentally breaking a world/server. Large blast mutipliers can cause extreme lag - you have been warned!
|
||||
config.ebwizardry.summoned_creature_targets_whitelist.tooltip=List of names of entities which summoned creatures and wizards are allowed to attack, in addition to the defaults. Add mod creatures to this list if you want summoned creatures to attack them and they aren't already doing so. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry.wizard).
|
||||
config.ebwizardry.summoned_creature_targets_blacklist.tooltip=List of names of entities which summoned creatures and wizards are specifically not allowed to attack, overriding the defaults and the whitelist. Add creatures to this list if allowing them to be attacked causes problems or is too destructive (removing creepers from this list is done at your own risk!). Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry.wizard).
|
||||
config.ebwizardry.summoned_creature_targets_whitelist.tooltip=List of names of entities which summoned creatures and wizards are allowed to attack, in addition to the defaults. Add mod creatures to this list if you want summoned creatures to attack them and they aren't already doing so. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
config.ebwizardry.summoned_creature_targets_blacklist.tooltip=List of names of entities which summoned creatures and wizards are specifically not allowed to attack, overriding the defaults and the whitelist. Add creatures to this list if allowing them to be attacked causes problems or is too destructive (removing creepers from this list is done at your own risk!). Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
config.ebwizardry.spell_hud_position.tooltip=The position of the spell HUD.
|
||||
config.ebwizardry.cast_command_name.tooltip=The name of the /cast command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /cast you would type /magic instead.
|
||||
config.ebwizardry.discoverspell_command_name.tooltip=The name of the /discoverspell command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /discoverspell you would type /magic instead.
|
||||
config.ebwizardry.ally_command_name.tooltip=The name of the /ally command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /ally you would type /magic instead.
|
||||
config.ebwizardry.allies_command_name.tooltip=The name of the /allies command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /allies you would type /magic instead.
|
||||
config.ebwizardry.mind_control_targets_blacklist.tooltip=List of names of entities which cannot be mind controlled, in addition to the defaults. Add creatures to this list if allowing them to be mind-controlled causes problems or could be exploited. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
config.ebwizardry.evil_wizard_dimensions.tooltip=List of dimension ids in which evil wizards can spawn.
|
||||
|
||||
config.ebwizardry.mobs_immune_to_fire.tooltip=List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry.wizard).
|
||||
config.ebwizardry.mobs_immune_to_ice.tooltip=List of names of entities that are immune to ice, in addition to the defaults. Add mod creatures to this list if you want them to be immune to ice magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry.wizard).
|
||||
config.ebwizardry.mobs_immune_to_lightning.tooltip=List of names of entities that are immune to lightning, in addition to the defaults. Add mod creatures to this list if you want them to be immune to lightning magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry.wizard).
|
||||
config.ebwizardry.mobs_immune_to_wither.tooltip=List of names of entities that are immune to wither effects, in addition to the defaults. Add mod creatures to this list if you want them to be immune to withering magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry.wizard).
|
||||
config.ebwizardry.mobs_immune_to_poison.tooltip=List of names of entities that are immune to poison, in addition to the defaults. Add mod creatures to this list if you want them to be immune to poison magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry.wizard).
|
||||
config.ebwizardry.mobs_immune_to_fire.tooltip=List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
config.ebwizardry.mobs_immune_to_ice.tooltip=List of names of entities that are immune to ice, in addition to the defaults. Add mod creatures to this list if you want them to be immune to ice magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
config.ebwizardry.mobs_immune_to_lightning.tooltip=List of names of entities that are immune to lightning, in addition to the defaults. Add mod creatures to this list if you want them to be immune to lightning magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
config.ebwizardry.mobs_immune_to_wither.tooltip=List of names of entities that are immune to wither effects, in addition to the defaults. Add mod creatures to this list if you want them to be immune to withering magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
config.ebwizardry.mobs_immune_to_poison.tooltip=List of names of entities that are immune to poison, in addition to the defaults. Add mod creatures to this list if you want them to be immune to poison magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. ebwizardry:wizard).
|
||||
|
||||
wizard.debug=%1$s, %2$s, %3$s
|
||||
|
||||
@@ -0,0 +1,741 @@
|
||||
tile.ebwizardry:arcane_workbench.name=奥术工作台
|
||||
tile.ebwizardry:crystal_ore.name=水晶矿
|
||||
tile.ebwizardry:petrified_stone.name=石化石像
|
||||
tile.ebwizardry:ice_statue.name=冰像
|
||||
tile.ebwizardry:crystal_flower.name=水晶花
|
||||
tile.ebwizardry:snare.name=陷阱
|
||||
tile.ebwizardry:transportation_stone.name=传送石
|
||||
tile.ebwizardry:spectral_block.name=幽冥块
|
||||
tile.ebwizardry:crystal_block.name=水晶块
|
||||
|
||||
item.ebwizardry:magic_crystal.name=魔法水晶
|
||||
item.ebwizardry:magic_wand.name=法杖
|
||||
item.ebwizardry:apprentice_wand.name=学徒法杖
|
||||
item.ebwizardry:advanced_wand.name=进阶法杖
|
||||
item.ebwizardry:master_wand.name=大师法杖
|
||||
item.ebwizardry:spell_book.name=法术书
|
||||
|
||||
item.ebwizardry:arcane_tome.name=奥法宝典
|
||||
item.ebwizardry:arcane_tome.desc1=升级需求 %1$s
|
||||
item.ebwizardry:arcane_tome.desc2=法杖升级至 %1$s 级别
|
||||
|
||||
item.ebwizardry:wizard_handbook.name=巫师手册
|
||||
item.ebwizardry:wizard_handbook.desc=编写于 %1$s
|
||||
|
||||
item.ebwizardry:wand.buff=+%1$s %2$s 能力
|
||||
item.ebwizardry:wand.spell=当前法术: %1$s
|
||||
item.ebwizardry:wand.mana=魔力: %1$s/%2$s
|
||||
|
||||
item.ebwizardry:wand.addally=%1$s 已添加到你的盟友名单
|
||||
item.ebwizardry:wand.removeally=%1$s 已移出你的盟友名单
|
||||
|
||||
item.ebwizardry:basic_fire_wand.name=余火法杖
|
||||
item.ebwizardry:basic_ice_wand.name=寒霜法杖
|
||||
item.ebwizardry:basic_lightning_wand.name=星火法杖
|
||||
item.ebwizardry:basic_necromancy_wand.name=暗影法杖
|
||||
item.ebwizardry:basic_earth_wand.name=森林法杖
|
||||
item.ebwizardry:basic_sorcery_wand.name=神秘法杖
|
||||
item.ebwizardry:basic_healing_wand.name=治愈法杖
|
||||
|
||||
item.ebwizardry:apprentice_fire_wand.name=学徒烈焰法杖
|
||||
item.ebwizardry:apprentice_ice_wand.name=学徒冰霜法杖
|
||||
item.ebwizardry:apprentice_lightning_wand.name=学徒风暴法杖
|
||||
item.ebwizardry:apprentice_necromancy_wand.name=学徒死灵法杖
|
||||
item.ebwizardry:apprentice_earth_wand.name=学徒大地法杖
|
||||
item.ebwizardry:apprentice_sorcery_wand.name=学徒妖术法杖
|
||||
item.ebwizardry:apprentice_healing_wand.name=学徒治愈法杖
|
||||
|
||||
item.ebwizardry:advanced_fire_wand.name=烈焰法杖
|
||||
item.ebwizardry:advanced_ice_wand.name=冰霜法杖
|
||||
item.ebwizardry:advanced_lightning_wand.name=风暴法杖
|
||||
item.ebwizardry:advanced_necromancy_wand.name=死灵法杖
|
||||
item.ebwizardry:advanced_earth_wand.name=大地法杖
|
||||
item.ebwizardry:advanced_sorcery_wand.name=妖术法杖
|
||||
item.ebwizardry:advanced_healing_wand.name=治愈法杖
|
||||
|
||||
item.ebwizardry:master_fire_wand.name=大师烈焰法杖
|
||||
item.ebwizardry:master_ice_wand.name=大师冰霜法杖
|
||||
item.ebwizardry:master_lightning_wand.name=大师风暴法杖
|
||||
item.ebwizardry:master_necromancy_wand.name=大师死灵法杖
|
||||
item.ebwizardry:master_earth_wand.name=大师大地法杖
|
||||
item.ebwizardry:master_sorcery_wand.name=大师妖术法杖
|
||||
item.ebwizardry:master_healing_wand.name=大师治愈法杖
|
||||
|
||||
item.ebwizardry:spectral_sword.name=幽冥剑
|
||||
item.ebwizardry:spectral_pickaxe.name=幽冥镐
|
||||
item.ebwizardry:spectral_bow.name=幽冥弓
|
||||
|
||||
item.ebwizardry:mana_flask.name=魔力瓶
|
||||
item.ebwizardry:storage_upgrade.name=法杖存储升级
|
||||
item.ebwizardry:siphon_upgrade.name=法杖汲取升级
|
||||
item.ebwizardry:condenser_upgrade.name=法杖聚光升级
|
||||
item.ebwizardry:range_upgrade.name=法杖范围升级
|
||||
item.ebwizardry:duration_upgrade.name=法杖时限升级
|
||||
item.ebwizardry:cooldown_upgrade.name=法杖冷却升级
|
||||
item.ebwizardry:blast_upgrade.name=法杖爆破升级
|
||||
item.ebwizardry:attunement_upgrade.name=法杖协调升级
|
||||
|
||||
item.ebwizardry:flaming_axe.name=炽烈之斧
|
||||
item.ebwizardry:frost_axe.name=冰霜之斧
|
||||
|
||||
item.ebwizardry:firebomb.name=燃烧弹
|
||||
item.ebwizardry:poison_bomb.name=毒液弹
|
||||
item.ebwizardry:smoke_bomb.name=烟雾弹
|
||||
|
||||
item.ebwizardry:blank_scroll.name=空白卷轴
|
||||
item.ebwizardry:scroll.name=卷轴 %1$s
|
||||
item.ebwizardry:scroll.undiscovered.name=卷轴 "%1$s"
|
||||
item.ebwizardry:identification_scroll.name=鉴定卷轴
|
||||
item.ebwizardry:identification_scroll.desc1=%1$s 鉴定未知的
|
||||
item.ebwizardry:identification_scroll.desc2=%1$s 法术书或卷轴
|
||||
item.ebwizardry:identification_scroll.nothing_to_identify=没有可以鉴定的东西!
|
||||
|
||||
item.ebwizardry:armour_upgrade.name=奥术戳记:保护
|
||||
item.ebwizardry:armour_upgrade.desc1=%1$s升级任何巫师护甲
|
||||
item.ebwizardry:armour_upgrade.desc2=%1$s使其达到 %2$s传奇
|
||||
|
||||
item.ebwizardry:magic_silk.name=魔法丝绸
|
||||
|
||||
item.ebwizardry:wizard_armour.legendary=传奇
|
||||
item.ebwizardry:wizard_armour.buff=-%1$s %2$s 消耗
|
||||
item.ebwizardry:wizard_armour.mana=魔力: %1$s/%2$s
|
||||
|
||||
item.ebwizardry:wizard_hat.name=巫师帽
|
||||
item.ebwizardry:wizard_robe.name=巫师法袍
|
||||
item.ebwizardry:wizard_leggings.name=巫师护腿
|
||||
item.ebwizardry:wizard_boots.name=巫师靴子
|
||||
|
||||
item.ebwizardry:wizard_hat_fire.name=烈焰法师帽子
|
||||
item.ebwizardry:wizard_robe_fire.name=烈焰法师法袍
|
||||
item.ebwizardry:wizard_leggings_fire.name=烈焰法师护腿
|
||||
item.ebwizardry:wizard_boots_fire.name=烈焰法师靴子
|
||||
|
||||
item.ebwizardry:wizard_hat_ice.name=冰霜法师帽子
|
||||
item.ebwizardry:wizard_robe_ice.name=冰霜法师法袍
|
||||
item.ebwizardry:wizard_leggings_ice.name=冰霜法师护腿
|
||||
item.ebwizardry:wizard_boots_ice.name=冰霜法师靴子
|
||||
|
||||
item.ebwizardry:wizard_hat_lightning.name=风暴法师帽子
|
||||
item.ebwizardry:wizard_robe_lightning.name=风暴法师法袍
|
||||
item.ebwizardry:wizard_leggings_lightning.name=风暴法师护腿
|
||||
item.ebwizardry:wizard_boots_lightning.name=风暴法师靴子
|
||||
|
||||
item.ebwizardry:wizard_hat_necromancy.name=死灵法师帽子
|
||||
item.ebwizardry:wizard_robe_necromancy.name=死灵法师法袍
|
||||
item.ebwizardry:wizard_leggings_necromancy.name=死灵法师护腿
|
||||
item.ebwizardry:wizard_boots_necromancy.name=死灵法师靴子
|
||||
|
||||
item.ebwizardry:wizard_hat_earth.name=大地法师帽子
|
||||
item.ebwizardry:wizard_robe_earth.name=大地法师法袍
|
||||
item.ebwizardry:wizard_leggings_earth.name=大地法师护腿
|
||||
item.ebwizardry:wizard_boots_earth.name=大地法师靴子
|
||||
|
||||
item.ebwizardry:wizard_hat_sorcery.name=妖术法师帽子
|
||||
item.ebwizardry:wizard_robe_sorcery.name=妖术法师法袍
|
||||
item.ebwizardry:wizard_leggings_sorcery.name=妖术法师护腿
|
||||
item.ebwizardry:wizard_boots_sorcery.name=妖术法师靴子
|
||||
|
||||
item.ebwizardry:wizard_hat_healing.name=治愈法师帽子
|
||||
item.ebwizardry:wizard_robe_healing.name=治愈法师法袍
|
||||
item.ebwizardry:wizard_leggings_healing.name=治愈法师护腿
|
||||
item.ebwizardry:wizard_boots_healing.name=治愈法师靴子
|
||||
|
||||
item.ebwizardry:spawn_wizard.name=生成巫师
|
||||
item.ebwizardry:spawn_evil_wizard.name=生成邪恶巫师
|
||||
|
||||
item.ebwizardry:spectral_helmet.name=幽冥头盔
|
||||
item.ebwizardry:spectral_chestplate.name=幽冥胸甲
|
||||
item.ebwizardry:spectral_leggings.name=幽冥护腿
|
||||
item.ebwizardry:spectral_boots.name=幽冥靴子
|
||||
|
||||
entity.ebwizardry:summonedcreature.nameplate=%1$s 的 %2$s
|
||||
entity.ebwizardry:summonedcreature.nameplate_fallback=某人的 %1$s
|
||||
|
||||
entity.ebwizardry:zombie_minion.name=僵尸
|
||||
entity.ebwizardry:skeleton_minion.name=骷髅
|
||||
entity.ebwizardry:spider_minion.name=蜘蛛
|
||||
entity.ebwizardry:blaze_minion.name=烈焰人
|
||||
entity.ebwizardry:wither_skeleton_minion.name=凋灵骷髅
|
||||
entity.ebwizardry:ice_wraith.name=冰封幽灵
|
||||
entity.ebwizardry:lightning_wraith.name=光明幽灵
|
||||
entity.ebwizardry:shadow_wraith.name=阴影幽灵
|
||||
entity.ebwizardry:spirit_wolf.name=精灵狼
|
||||
entity.ebwizardry:spirit_horse.name=精灵马
|
||||
entity.ebwizardry:ice_giant.name=冰封巨人
|
||||
entity.ebwizardry:phoenix.name=凤凰
|
||||
entity.ebwizardry:wizard.name=巫师
|
||||
entity.ebwizardry:magic_slime.name=魔法史莱姆
|
||||
entity.ebwizardry:silverfish_minion.name=蠹虫
|
||||
entity.ebwizardry:storm_elemental.name=风暴元素
|
||||
entity.ebwizardry:evil_wizard.name=巫师
|
||||
entity.ebwizardry:decoy.name=诱饵
|
||||
|
||||
entity.ebwizardry:magic_missile.name=魔法
|
||||
entity.ebwizardry:arc.name=魔法
|
||||
entity.ebwizardry:spark_bomb.name=魔法
|
||||
entity.ebwizardry:ice_shard.name=魔法
|
||||
entity.ebwizardry:firebomb.name=魔法
|
||||
entity.ebwizardry:poison_bomb.name=魔法
|
||||
entity.ebwizardry:force_orb.name=魔法
|
||||
entity.ebwizardry:spark.name=魔法
|
||||
entity.ebwizardry:darkness_orb.name=魔法
|
||||
entity.ebwizardry:fire_sigil.name=魔法
|
||||
entity.ebwizardry:frost_sigil.name=魔法
|
||||
entity.ebwizardry:lightning_sigil.name=魔法
|
||||
entity.ebwizardry:lightning_arrow.name=魔法
|
||||
entity.ebwizardry:firebolt.name=魔法
|
||||
entity.ebwizardry:ice_charge.name=魔法
|
||||
entity.ebwizardry:force_arrow.name=魔法
|
||||
entity.ebwizardry:dart.name=魔法
|
||||
entity.ebwizardry:lightning_disc.name=魔法
|
||||
entity.ebwizardry:thunderbolt.name=魔法
|
||||
entity.ebwizardry:decay.name=魔法
|
||||
entity.ebwizardry:ice_lance.name=魔法
|
||||
entity.ebwizardry:smoke_bomb.name=魔法
|
||||
entity.ebwizardry:ice_spike.name=魔法
|
||||
|
||||
entity.ebwizardry:black_hole.name=黑洞
|
||||
entity.ebwizardry:shield.name=盾
|
||||
entity.ebwizardry:meteor.name=陨星
|
||||
entity.ebwizardry:blizzard.name=暴风雪
|
||||
entity.ebwizardry:bubble.name=气泡
|
||||
entity.ebwizardry:tornado.name=飓风
|
||||
entity.ebwizardry:lightning_hammer.name=雷神之锤
|
||||
entity.ebwizardry:arrow_rain.name=箭雨
|
||||
entity.ebwizardry:healing_aura.name=治疗灵气
|
||||
entity.ebwizardry:forcefield.name=力场护盾
|
||||
entity.ebwizardry:ring_of_fire.name=火环
|
||||
entity.ebwizardry:earthquake.name=地震
|
||||
entity.ebwizardry:falling_grass.name=落草
|
||||
entity.ebwizardry:hailstorm.name=冰雹风暴
|
||||
entity.ebwizardry:lightning_pulse.name=闪电脉冲
|
||||
|
||||
itemGroup.ebwizardry=巫术学
|
||||
itemGroup.ebwizardryspells=卷轴
|
||||
|
||||
advancement.wizardry:root=新兴巫术
|
||||
advancement.wizardry:root.desc=一个巫师掌握奥术的旅程
|
||||
advancement.wizardry:crystal=一个奇异的水晶...
|
||||
advancement.wizardry:crystal.desc=挖掘一个魔法水晶
|
||||
advancement.wizardry:arcane_initiate=奥术启程
|
||||
advancement.wizardry:arcane_initiate.desc=利用金锭,木棍和魔法水晶制造一根法杖
|
||||
advancement.wizardry:apprentice=见习巫师
|
||||
advancement.wizardry:apprentice.desc=使用奥法宝典来升级你的法杖
|
||||
advancement.wizardry:master=大师级巫师
|
||||
advancement.wizardry:master.desc=获得大师级法杖
|
||||
advancement.wizardry:all_spells=巫师的自我修养
|
||||
advancement.wizardry:all_spells.desc=在游戏中施放所有法术
|
||||
advancement.wizardry:wizard_trade=魔法交易
|
||||
advancement.wizardry:wizard_trade.desc=向巫师购买物品
|
||||
advancement.wizardry:buy_master_spell=知识就是力量
|
||||
advancement.wizardry:buy_master_spell.desc=向巫师购买一个大师级卷轴
|
||||
advancement.wizardry:freeze_blaze=现在不太热了
|
||||
advancement.wizardry:freeze_blaze.desc=把烈焰人冻成傻子
|
||||
advancement.wizardry:charge_creep=它要炸了
|
||||
advancement.wizardry:charge_creeper.desc='意外' 捕获爬行者
|
||||
advancement.wizardry:frankenstein=弗兰肯斯坦
|
||||
advancement.wizardry:frankenstein.desc=用闪电法术将猪变成僵尸猪人
|
||||
advancement.wizardry:special_upgrade=奥术工匠
|
||||
advancement.wizardry:special_upgrade.desc=对法杖进行特殊升级
|
||||
advancement.wizardry:craft_flask=这是魔力,装瓶!
|
||||
advancement.wizardry:craft_flask.desc=制作一个魔力瓶
|
||||
advancement.wizardry:elemental=元素
|
||||
advancement.wizardry:elemental.desc=获得元素法杖
|
||||
advancement.wizardry:armour_set=现在你是一个正确的巫师
|
||||
advancement.wizardry:armour_set.desc=制作并装备全套巫师护具
|
||||
advancement.wizardry:legendary=传奇!
|
||||
advancement.wizardry:legendary.desc=获得一件传奇级装备
|
||||
advancement.wizardry:self_destruct=真是倒霉
|
||||
advancement.wizardry:self_destruct.desc=被自己的魔法杀死
|
||||
advancement.wizardry:pig_tornado=不会再次...
|
||||
advancement.wizardry:pig_tornado.desc=骑着猪卷进飓风
|
||||
advancement.wizardry:jam_wizard=扰乱会议
|
||||
advancement.wizardry:jam_wizard.desc=对一个巫师使用奥术干扰
|
||||
advancement.wizardry:slime_skeleton=棘手局面
|
||||
advancement.wizardry:slime_skeleton.desc=利用史莱姆吞噬骷髅
|
||||
advancement.wizardry:anger_wizard=你会后悔的
|
||||
advancement.wizardry:anger_wizard.desc=使一个巫师发怒
|
||||
advancement.wizardry:defeat_evil_wizard=正义降临
|
||||
advancement.wizardry:defeat_evil_wizard.desc=击败邪恶巫师
|
||||
advancement.wizardry:max_out_wand=整装上阵
|
||||
advancement.wizardry:max_out_wand.desc=将大师级法杖升级到最强
|
||||
advancement.wizardry:element_master=元素掌控
|
||||
advancement.wizardry:element_master.desc=施放任何元素的法术
|
||||
advancement.wizardry:identify_spell=奥术鉴定
|
||||
advancement.wizardry:identify_spell.desc=使用鉴定卷轴来鉴定法术书或卷轴
|
||||
|
||||
tile.ebwizardry:transportation_stone.confirm=施展法术时你将会回到这里 %1$s
|
||||
tile.ebwizardry:transportation_stone.invalid=你必须先将八个传送石围成圆圈!
|
||||
|
||||
container.ebwizardry:arcane_workbench=奥术工作台
|
||||
container.ebwizardry:arcane_workbench.apply=应用
|
||||
container.ebwizardry:arcane_workbench.mana=魔力:
|
||||
container.ebwizardry:arcane_workbench.upgrades=应用升级:
|
||||
|
||||
tier.basic=新手
|
||||
tier.apprentice=学徒
|
||||
tier.advanced=进阶
|
||||
tier.master=大师
|
||||
|
||||
element.simple=无
|
||||
element.fire=火
|
||||
element.ice=冰
|
||||
element.lightning=闪电
|
||||
element.necromancy=死灵
|
||||
element.earth=大地
|
||||
element.sorcery=妖术
|
||||
element.healing=治愈
|
||||
|
||||
element.simple.wizard=巫师
|
||||
element.fire.wizard=烈焰法师
|
||||
element.ice.wizard=冰霜法师
|
||||
element.lightning.wizard=风暴法师
|
||||
element.necromancy.wizard=死灵法师
|
||||
element.earth.wizard=大地法师
|
||||
element.sorcery.wizard=妖术法师
|
||||
element.healing.wizard=治愈法师
|
||||
|
||||
spelltype.attack=攻击
|
||||
spelltype.defence=防御
|
||||
spelltype.utility=实用
|
||||
spelltype.minion=仆从
|
||||
|
||||
spell.disabled=%1$s 已在配置文件中禁用
|
||||
spell.resist=%1$s 排斥 %2$s
|
||||
spell.discover=发现了这个法术 %1$s!
|
||||
|
||||
spell.ebwizardry:agility=敏捷
|
||||
spell.ebwizardry:arc=电弧
|
||||
spell.ebwizardry:arcane_jammer=奥术干扰
|
||||
spell.ebwizardry:arrow_rain=箭雨
|
||||
spell.ebwizardry:banish=驱逐
|
||||
spell.ebwizardry:black_hole=黑洞
|
||||
spell.ebwizardry:blink=闪现
|
||||
spell.ebwizardry:blizzard=暴雪
|
||||
spell.ebwizardry:bubble=气泡
|
||||
spell.ebwizardry:chain_lightning=闪电链条
|
||||
spell.ebwizardry:clairvoyance=千里眼
|
||||
spell.ebwizardry:cobwebs=结网
|
||||
spell.ebwizardry:conjure_armour=唤魔护甲
|
||||
spell.ebwizardry:conjure_bow=唤魔弓
|
||||
spell.ebwizardry:conjure_pickaxe=唤魔镐子
|
||||
spell.ebwizardry:conjure_sword=唤魔剑
|
||||
spell.ebwizardry:cure_effects=治愈效应
|
||||
spell.ebwizardry:curse_of_soulbinding=灵魂绑定
|
||||
spell.ebwizardry:darkness_orb=黑暗宝珠
|
||||
spell.ebwizardry:darkvision=黑暗视觉
|
||||
spell.ebwizardry:dart=飞镖
|
||||
spell.ebwizardry:decay=腐化
|
||||
spell.ebwizardry:decoy=诱饵
|
||||
spell.ebwizardry:detonate=引爆
|
||||
spell.ebwizardry:diamondflesh=金刚不坏
|
||||
spell.ebwizardry:earthquake=地震
|
||||
spell.ebwizardry:entrapment=诱捕
|
||||
spell.ebwizardry:fireball=火球
|
||||
spell.ebwizardry:firebolt=火箭
|
||||
spell.ebwizardry:firebomb=火焰弹
|
||||
spell.ebwizardry:fire_resistance=防火
|
||||
spell.ebwizardry:fire_sigil=火之印记
|
||||
spell.ebwizardry:fireskin=火焰之肤
|
||||
spell.ebwizardry:firestorm=火焰风暴
|
||||
spell.ebwizardry:flame_ray=火焰射线
|
||||
spell.ebwizardry:flaming_axe=赤炎之斧
|
||||
spell.ebwizardry:flaming_weapon=赤炎武器
|
||||
spell.ebwizardry:flight=飞行
|
||||
spell.ebwizardry:font_of_mana=魔力字符
|
||||
spell.ebwizardry:font_of_vitality=活力字符
|
||||
spell.ebwizardry:force_arrow=力量箭矢
|
||||
spell.ebwizardry:forcefield=力场护盾
|
||||
spell.ebwizardry:force_orb=力场宝珠
|
||||
spell.ebwizardry:forests_curse=森林诅咒
|
||||
spell.ebwizardry:freeze=冻结
|
||||
spell.ebwizardry:freezing_weapon=冻结武器
|
||||
spell.ebwizardry:frost_axe=寒霜斧
|
||||
spell.ebwizardry:frost_ray=寒霜射线
|
||||
spell.ebwizardry:frost_sigil=寒霜印记
|
||||
spell.ebwizardry:glide=滑翔
|
||||
spell.ebwizardry:greater_fireball=大型火球
|
||||
spell.ebwizardry:greater_heal=强效治疗
|
||||
spell.ebwizardry:group_heal=团体治疗
|
||||
spell.ebwizardry:growth_aura=生长光环
|
||||
spell.ebwizardry:hailstorm=冰雹风暴
|
||||
spell.ebwizardry:heal=治愈
|
||||
spell.ebwizardry:heal_ally=友军治愈
|
||||
spell.ebwizardry:healing_aura=治愈灵气
|
||||
spell.ebwizardry:homing_spark=跟踪闪电
|
||||
spell.ebwizardry:ice_age=冰霜纪元
|
||||
spell.ebwizardry:ice_charge=冰霜冲击
|
||||
spell.ebwizardry:ice_lance=冰霜刺枪
|
||||
spell.ebwizardry:ice_shard=冰霜碎片
|
||||
spell.ebwizardry:ice_shroud=冰霜护体
|
||||
spell.ebwizardry:ice_spikes=冰霜尖刺
|
||||
spell.ebwizardry:ice_statue=冰雕
|
||||
spell.ebwizardry:ignite=点燃
|
||||
spell.ebwizardry:imbue_weapon=武器同调
|
||||
spell.ebwizardry:intimidate=恐吓
|
||||
spell.ebwizardry:invigorating_presence=振奋
|
||||
spell.ebwizardry:invisibility=隐形
|
||||
spell.ebwizardry:invoke_weather=祈雨
|
||||
spell.ebwizardry:ironflesh=钢筋铁骨
|
||||
spell.ebwizardry:leap=跳跃
|
||||
spell.ebwizardry:levitation=漂浮
|
||||
spell.ebwizardry:life_drain=生命汲取
|
||||
spell.ebwizardry:light=光芒
|
||||
spell.ebwizardry:lightning_arrow=闪电箭矢
|
||||
spell.ebwizardry:lightning_bolt=闪电弩箭
|
||||
spell.ebwizardry:lightning_disc=闪电轮盘
|
||||
spell.ebwizardry:lightning_hammer=雷神之锤
|
||||
spell.ebwizardry:lightning_pulse=闪电脉冲
|
||||
spell.ebwizardry:lightning_ray=闪电射线
|
||||
spell.ebwizardry:lightning_sigil=闪电印记
|
||||
spell.ebwizardry:lightning_web=电网
|
||||
spell.ebwizardry:magic_missile=魔法飞弹
|
||||
spell.ebwizardry:metamorphosis=拟态
|
||||
spell.ebwizardry:meteor=陨星
|
||||
spell.ebwizardry:mind_control=心灵控制
|
||||
spell.ebwizardry:mind_trick=心灵欺诈
|
||||
spell.ebwizardry:none=[空槽]
|
||||
spell.ebwizardry:oakflesh=苍劲如松
|
||||
spell.ebwizardry:petrify=石化
|
||||
spell.ebwizardry:phase_step=相位跳跃
|
||||
spell.ebwizardry:plague_of_darkness=黑暗瘟疫
|
||||
spell.ebwizardry:pocket_furnace=口袋熔炉
|
||||
spell.ebwizardry:pocket_workbench=口袋工作台
|
||||
spell.ebwizardry:poison=毒液
|
||||
spell.ebwizardry:poison_bomb=毒液弹
|
||||
spell.ebwizardry:replenish_hunger=回复饥饿
|
||||
spell.ebwizardry:ring_of_fire=火环
|
||||
spell.ebwizardry:shadow_ward=阴影护盾
|
||||
spell.ebwizardry:shield=护盾
|
||||
spell.ebwizardry:shockwave=冲击波
|
||||
spell.ebwizardry:silverfish_swarm=蠹虫群
|
||||
spell.ebwizardry:sixth_sense=第六感
|
||||
spell.ebwizardry:slime=史莱姆
|
||||
spell.ebwizardry:smoke_bomb=烟雾弹
|
||||
spell.ebwizardry:snare=陷阱
|
||||
spell.ebwizardry:snowball=雪球
|
||||
spell.ebwizardry:spark_bomb=电击弹
|
||||
spell.ebwizardry:spectral_pathway=幽径
|
||||
spell.ebwizardry:spider_swarm=蜘蛛群
|
||||
spell.ebwizardry:static_aura=静态灵气
|
||||
spell.ebwizardry:summon_blaze=召唤烈焰人
|
||||
spell.ebwizardry:summon_ice_giant=召唤冰封巨人
|
||||
spell.ebwizardry:summon_ice_wraith=召唤冰封幽灵
|
||||
spell.ebwizardry:summon_iron_golem=召唤铁傀儡
|
||||
spell.ebwizardry:summon_lightning_wraith=召唤闪电幽灵
|
||||
spell.ebwizardry:summon_phoenix=召唤凤凰
|
||||
spell.ebwizardry:summon_shadow_wraith=召唤阴影幽灵
|
||||
spell.ebwizardry:summon_skeleton=召唤骷髅
|
||||
spell.ebwizardry:summon_skeleton_legion=召唤骷髅军团
|
||||
spell.ebwizardry:summon_snow_golem=召唤雪傀儡
|
||||
spell.ebwizardry:summon_spirit_horse=召唤幽灵马
|
||||
spell.ebwizardry:summon_spirit_wolf=召唤幽灵狼
|
||||
spell.ebwizardry:summon_storm_elemental=召唤风暴元素
|
||||
spell.ebwizardry:summon_wither_skeleton=召唤凋灵骷髅
|
||||
spell.ebwizardry:summon_zombie=召唤僵尸
|
||||
spell.ebwizardry:telekinesis=隔空取物
|
||||
spell.ebwizardry:thunderbolt=雷电
|
||||
spell.ebwizardry:thunderstorm=雷暴
|
||||
spell.ebwizardry:tornado=飓风
|
||||
spell.ebwizardry:transience=金身
|
||||
spell.ebwizardry:transportation=传送
|
||||
spell.ebwizardry:vanishing_box=幻灭之盒
|
||||
spell.ebwizardry:wall_of_frost=冰霜之墙
|
||||
spell.ebwizardry:water_breathing=水下呼吸
|
||||
spell.ebwizardry:whirlwind=旋风
|
||||
spell.ebwizardry:wither=凋零
|
||||
spell.ebwizardry:wither_skull=凋灵头颅
|
||||
|
||||
spell.ebwizardry:agility.desc=为施法者提供更快的移速和更高的跳跃高度,持续时间30秒。
|
||||
spell.ebwizardry:arc.desc=向目标发射闪电,
|
||||
spell.ebwizardry:arcane_jammer.desc=阻止目标15秒使用魔法。
|
||||
spell.ebwizardry:arrow_rain.desc=“弓箭手,射击!”
|
||||
spell.ebwizardry:banish.desc=强制目标传送到某一范围内的随机位置。
|
||||
spell.ebwizardry:black_hole.desc=撕裂现实。
|
||||
spell.ebwizardry:blink.desc=将施法者远距离传送至其指向的地方。
|
||||
spell.ebwizardry:blizzard.desc=创建一个旋转的冰封地带,减缓并持续伤害困在里面的任何东西。施法者免受伤害,但仍然受到减速影响。
|
||||
spell.ebwizardry:bubble.desc=射出一股气泡,击中的目标会无助地向上漂浮。目标将在一段时间后坠落并且受到伤害。
|
||||
spell.ebwizardry:chain_lightning.desc=向目标发射闪电,能够向额外目标跳跃至多两次。
|
||||
spell.ebwizardry:clairvoyance.desc=创建一条通向被记录的的坐标的道路。选择此法术后,潜行右键来点击一个方块设置坐标,通常施展此法术来创建道路。该道路将在90秒后消失。
|
||||
spell.ebwizardry:cobwebs.desc=在你指向的地方生成蜘蛛网,极大减慢被困住的生物的移动速度,如果未被破坏,蛛网将在20秒后消失。
|
||||
spell.ebwizardry:conjure_armour.desc=在施法者身上制造幽冥护甲,与铁护甲等效。护甲持续60秒,施法者必须要有一个空装备槽。
|
||||
spell.ebwizardry:conjure_bow.desc=创建一个无限箭矢的幽冥弓,持续时间30秒。
|
||||
spell.ebwizardry:conjure_pickaxe.desc=创建一个与铁镐等效的幽冥镐,持续时间30秒。
|
||||
spell.ebwizardry:conjure_sword.desc=创建一把与铁剑等效的幽冥剑,持续时间30秒。
|
||||
spell.ebwizardry:cure_effects.desc=移除施法者目前的任何药水效果,不论好坏。
|
||||
spell.ebwizardry:curse_of_soulbinding.desc=使目标的灵魂与施法者的灵魂绑定,意味施法者受到的伤害会转移给受害者,直到受害者或者施法者死亡。
|
||||
spell.ebwizardry:darkness_orb.desc=向你指的方向发射一到移动缓慢的黑暗能量,无论击中什么,其都会凋零。
|
||||
spell.ebwizardry:darkvision.desc=给予施法者夜视45秒。
|
||||
spell.ebwizardry:dart.desc=向你指的方向发射飞镖,伤害并削弱目标。
|
||||
spell.ebwizardry:decay.desc=在地表制造腐化,任何生物接触都会受到感染,随着时间流逝而持续造成伤害,并且受害者行走过的地面会蔓延更多的腐化。
|
||||
spell.ebwizardry:decoy.desc=创建一个虚假的施法者克隆体,用来吸引怪物仇恨,30秒后诱饵消失。
|
||||
spell.ebwizardry:detonate.desc=在你指向的地方发生爆炸,如果附近有生物或者施法者距离太近,也会受到伤害。
|
||||
spell.ebwizardry:diamondflesh.desc=“你的箭矢就是在挠痒痒!”
|
||||
spell.ebwizardry:earthquake.desc=一个真正的大地大法师可以令沧海化为桑田。
|
||||
spell.ebwizardry:entrapment.desc=将目标陷入黑暗,其将被无助地向上牵引而且不断地受到伤害。
|
||||
spell.ebwizardry:fireball.desc=朝你指的方向发射一个火球。
|
||||
spell.ebwizardry:firebolt.desc=向你面前一小段距离喷射火焰。
|
||||
spell.ebwizardry:firebomb.desc=在你指的方向投掷一个燃烧瓶,在撞击时爆炸并让目标着火。
|
||||
spell.ebwizardry:fire_resistance.desc=施法者防火30秒。
|
||||
spell.ebwizardry:fire_sigil.desc=在地上放置一个魔法火焰陷阱,它会伤害并点燃触发它的生物。
|
||||
spell.ebwizardry:fireskin.desc=将施法者笼罩在火焰中30秒,任何攻击都会使攻击者自燃。
|
||||
spell.ebwizardry:firestorm.desc=“吾乃巨龙。”
|
||||
spell.ebwizardry:flame_ray.desc=在你指的方向产生一股火焰,它会持续点燃并伤害目标。
|
||||
spell.ebwizardry:flaming_axe.desc=制造一把燃烧的斧头,击中敌人会使其着火,持续时间30秒。
|
||||
spell.ebwizardry:flaming_weapon.desc=暂时性地将火焰的力量附加在快捷栏的第一件武器上,武器能使受害者着火,法术在45秒后失效。
|
||||
spell.ebwizardry:flight.desc=像鹰一样翱翔。
|
||||
spell.ebwizardry:font_of_mana.desc=“我们充满了强大的魔法能量,它似乎是来自...”-摘自一位被遗忘的法师的日志中,该页面的其余部分已经被烧毁。
|
||||
spell.ebwizardry:font_of_vitality.desc=令人惊讶的感觉。
|
||||
spell.ebwizardry:force_arrow.desc=在你指向的地方射出一根强有力的箭矢。
|
||||
spell.ebwizardry:forcefield.desc=在你的周围生成一个能够排斥生物和偏移弹射物的力场。
|
||||
spell.ebwizardry:force_orb.desc=发射一个力场,在受到撞击时会伤害并排斥附近的生物。
|
||||
spell.ebwizardry:forests_curse.desc=“你胆敢进入我的森林!”
|
||||
spell.ebwizardry:freeze.desc=冰冻目标10秒,也能把水冻结和在地表造雪。
|
||||
spell.ebwizardry:freezing_weapon.desc=暂时性地将冰霜的力量附加在快捷栏的第一件武器上,武器能使受害者冻伤,法术在45秒后失效。
|
||||
spell.ebwizardry:frost_axe.desc=制造一把冰霜之斧,击中敌人时将其冻伤,持续时间30秒。
|
||||
spell.ebwizardry:frost_ray.desc=在你指向的地方制造一股霜冻流,可将目标减慢并持续伤害。
|
||||
spell.ebwizardry:frost_sigil.desc=在地表放置一个魔法冰封陷阱,触发陷阱的生物会被冻结并受到伤害。
|
||||
spell.ebwizardry:glide.desc=允许施法者在空中按住使用按钮向下滑行。
|
||||
spell.ebwizardry:greater_fireball.desc=在你指向的方向发射一个大火球,在受到碰撞时发生爆炸。
|
||||
spell.ebwizardry:greater_heal.desc=治疗施法者四颗心。
|
||||
spell.ebwizardry:group_heal.desc=治疗施法者、附近的盟友和召唤生物三颗心。
|
||||
spell.ebwizardry:growth_aura.desc=加速施法者附近作物的生长,还能在草地上长杂草和花朵。
|
||||
spell.ebwizardry:hailstorm.desc=正是在第三纪元的凛冬,冰霜法师发现了他们真正的力量。
|
||||
spell.ebwizardry:heal.desc=治疗施法者两颗心。
|
||||
spell.ebwizardry:heal_ally.desc=治疗目标两颗半心。
|
||||
spell.ebwizardry:healing_aura.desc=创建一个治疗能量力场,可以治疗内部的任何盟友。治疗力场内任何不死属性的生物都会受到伤害。
|
||||
spell.ebwizardry:homing_spark.desc=制造一个向敌人移动的浮游火花。
|
||||
spell.ebwizardry:ice_age.desc=“你将永远被冰封于此!”
|
||||
spell.ebwizardry:ice_charge.desc=发射一个冰块,撞击时发生爆裂并冻伤附近的生物并向各个方向发射碎片。
|
||||
spell.ebwizardry:ice_lance.desc=向你指的方向发射一支巨大能够穿透目标的冰矛,在此过程中能够伤害并且冻伤目标。
|
||||
spell.ebwizardry:ice_shard.desc=在你指向的方向发射一个冰碎片,在命中目标时会使目标受到伤害并减缓速度。
|
||||
spell.ebwizardry:ice_shroud.desc=在施法者身上产生一股寒气并持续三十秒,任何攻击者都会遭到冻伤。
|
||||
spell.ebwizardry:ice_spikes.desc=锋利的冰刺从你指向的地面升起,刺穿上面的任何生物。
|
||||
spell.ebwizardry:ice_statue.desc=将目标冻住20秒直到其打破束缚,目标被冻结时不能移动或者做任何事情,也不会受到伤害。
|
||||
spell.ebwizardry:ignite.desc=将目标点燃十秒,也能像打火石一样工作。
|
||||
spell.ebwizardry:imbue_weapon.desc=将魔力浸染在施法者快捷栏的第一个武器上,使其更加实用,法术在45秒后失效。
|
||||
spell.ebwizardry:intimidate.desc=发出可怕的咆哮声,附近的生物会在恐惧中逃离。惊恐的生物会在30秒后恢复正常。
|
||||
spell.ebwizardry:invigorating_presence.desc=使施法者和附近的盟友增加攻击力,持续45秒。
|
||||
spell.ebwizardry:invisibility.desc=使施法者隐形30秒。
|
||||
spell.ebwizardry:invoke_weather.desc=改变天气。
|
||||
spell.ebwizardry:ironflesh.desc=极大地提升施法者的抗性,持续30秒。
|
||||
spell.ebwizardry:leap.desc=使施法者向上跳跃几个方块并稍微向前移动。
|
||||
spell.ebwizardry:levitation.desc=按住使用物品按键可以向上飘起。在落地前使用可以免除掉落伤害。
|
||||
spell.ebwizardry:life_drain.desc=在你指向的方向发射一股凋零的能量,它能吸收目标的生命来补充你的生命。
|
||||
spell.ebwizardry:light.desc=创造一簇魔法光芒照亮附近的区域,持续时间30秒。
|
||||
spell.ebwizardry:lightning_arrow.desc=在你指向的方向发射一道闪电。
|
||||
spell.ebwizardry:lightning_bolt.desc=使闪电击中你指向的地方。
|
||||
spell.ebwizardry:lightning_disc.desc=在你指向的方向发射一个闪电轮,并搜寻目标。
|
||||
spell.ebwizardry:lightning_hammer.desc=“以神之愤怒惩戒你!”
|
||||
spell.ebwizardry:lightning_pulse.desc=使施法者附近的地面充能,伤害和排斥附近的生物。
|
||||
spell.ebwizardry:lightning_ray.desc=在你指向的方向制造一股闪电,可以不断地伤害目标。
|
||||
spell.ebwizardry:lightning_sigil.desc=在地上放置一个魔法闪电陷阱,它会对触发它的生物造成伤害并产生闪电链打击附近的生物。
|
||||
spell.ebwizardry:lightning_web.desc=“专注,将你脑海中的风暴通过法杖引导出来,释放它的愤怒。”
|
||||
spell.ebwizardry:magic_missile.desc=在你指向的方向发射一道魔法飞弹。
|
||||
spell.ebwizardry:metamorphosis.desc=将目标变成另一种形态,只适用与某些生物。
|
||||
spell.ebwizardry:meteor.desc=一些巫师只是想看到世界在燃烧...
|
||||
spell.ebwizardry:mind_control.desc=心灵控制目标持续30秒,被控制方会为施法者而战。对于意志强大的生物无效。(心灵终结仪了解下)
|
||||
spell.ebwizardry:mind_trick.desc=使目标迷惑15秒,其无法进行攻击。如果目标受到伤害,效果会被消除。
|
||||
spell.ebwizardry:none.desc=要使用/give命令获取法术书,请使用元数据 /give [player] ebwizardry:spell_book 1 [spell id](如果你发现这本书出现在箱子里,那么说明某些mod将其打乱了)
|
||||
spell.ebwizardry:oakflesh.desc=施法者抗性提升30秒。
|
||||
spell.ebwizardry:petrify.desc=将目标变成石头,直到其打破束缚,束缚在黑暗中有几率会被打破。目标被石化后不能移动或者做任何事情,但也不会受到伤害。
|
||||
spell.ebwizardry:phase_step.desc=传送施法者通过一个方块厚的墙面。范围升级会增加你的传送厚度。
|
||||
spell.ebwizardry:plague_of_darkness.desc=黑暗将把他们全部消灭...
|
||||
spell.ebwizardry:pocket_furnace.desc=在施法者的背包里熔炼多达五个物品。快捷栏的物品会被优先熔炼。
|
||||
spell.ebwizardry:pocket_workbench.desc=允许施法者制作物品,就像在工作台上制作一样。
|
||||
spell.ebwizardry:poison.desc=在你指向的方向发射毒液。
|
||||
spell.ebwizardry:poison_bomb.desc=在你指向的方向发射一枚毒液弹,撞击后爆炸并且毒害附近的生物。
|
||||
spell.ebwizardry:replenish_hunger.desc=补充施法者六格饥饿值。
|
||||
spell.ebwizardry:ring_of_fire.desc=在施法者周围制造一个火圈,对周围的敌人造成伤害并将其点燃。
|
||||
spell.ebwizardry:shadow_ward.desc=在施法者面前制造一堵暗黑墙,所受到伤害的一半都会返回到攻击者身上。
|
||||
spell.ebwizardry:shield.desc=制造一个能够阻挡弹射物和魔法的力场屏障。同时也会使施法者得到虚弱的效果。
|
||||
spell.ebwizardry:shockwave.desc=Boom.
|
||||
spell.ebwizardry:silverfish_swarm.desc="Ahhhh! 他们正在增加!"
|
||||
spell.ebwizardry:sixth_sense.desc=使施法者能够感知到附近的生物的位置,甚至能够透过墙壁,持续20秒。
|
||||
spell.ebwizardry:slime.desc=用史莱姆吞噬目标,减缓目标速度并对其造成伤害。史莱姆在10秒后破裂。
|
||||
spell.ebwizardry:smoke_bomb.desc=在你指向的方向发射一个烟雾弹,能够在短时间内释放出烟雾并且使附近的生物致盲。
|
||||
spell.ebwizardry:snare.desc=在地面放置一个陷阱,触发陷阱的生物会被减缓速度并且受到伤害。
|
||||
spell.ebwizardry:snowball.desc=在你指向的方向发射一个雪球。
|
||||
spell.ebwizardry:spark_bomb.desc=在你指向的方向发射一个电击弹,附近的敌人会受到电击。
|
||||
spell.ebwizardry:spectral_pathway.desc=在你面前制造一个不可破坏的魔法桥梁,能够延伸15个方块,桥会在60秒后消失。
|
||||
spell.ebwizardry:spider_swarm.desc=召唤一群毒蜘蛛为你战斗,如果毒蜘蛛没有被杀死会在30秒后消失。
|
||||
spell.ebwizardry:static_aura.desc=用闪电将施法者包围,持续30秒,任何攻击都会使攻击者遭到电击。
|
||||
spell.ebwizardry:summon_blaze.desc=召唤一个烈焰人为你战斗,如果烈焰人没有被杀死会在30秒后消失。
|
||||
spell.ebwizardry:summon_ice_giant.desc=“粉碎他们!”
|
||||
spell.ebwizardry:summon_ice_wraith.desc=召唤一个冰封幽灵为你战斗,如果冰封幽灵没有被杀死会在30秒后消失。
|
||||
spell.ebwizardry:summon_iron_golem.desc=Automatic automated autonomous automaton.
|
||||
spell.ebwizardry:summon_lightning_wraith.desc=召唤一个闪电幽灵为你战斗,如果闪电幽灵没有被杀死会在30秒后消失。
|
||||
spell.ebwizardry:summon_phoenix.desc=自灰烬中重生...
|
||||
spell.ebwizardry:summon_shadow_wraith.desc=召唤一个阴影幽灵为你战斗。
|
||||
spell.ebwizardry:summon_skeleton.desc=召唤一个骷髅为你战斗,如果骷髅没有被杀死会在30秒后消失。
|
||||
spell.ebwizardry:summon_skeleton_legion.desc=“复活吧,不死军!”
|
||||
spell.ebwizardry:summon_snow_golem.desc=召唤一个雪傀儡为你战斗。一直持续到雪傀儡死亡为止。
|
||||
spell.ebwizardry:summon_spirit_horse.desc=召唤一匹幽灵马让你乘骑。在下马后幽灵马会消失,你可以用法杖右键来遣散它。
|
||||
spell.ebwizardry:summon_spirit_wolf.desc=召唤一匹幽灵狼为你战斗。幽灵狼只有在被杀死的时候会消失,你可以用法杖右键来遣散它。
|
||||
spell.ebwizardry:summon_storm_elemental.desc=“风暴元素:古老的元素的显现,它难以抑制其中的原始力量。” -巫师手册奥术生物章,卷 I_i
|
||||
spell.ebwizardry:summon_wither_skeleton.desc=召唤一个凋灵骷髅为你战斗,凋灵骷髅会在消亡后消失。
|
||||
spell.ebwizardry:summon_zombie.desc=召唤一个僵尸为你战斗,如果僵尸没有被杀死会在30秒后消失。
|
||||
spell.ebwizardry:telekinesis.desc=移动一个掉落物或其他小物体到你面前,或者远程打开你指向的方块(相当于右击),也可以用来取下玩家的装备。
|
||||
spell.ebwizardry:thunderbolt.desc=发射一道雷击震退目标
|
||||
spell.ebwizardry:thunderstorm.desc="Mwahahahahahaha!"
|
||||
spell.ebwizardry:tornado.desc=在你指向的方向释放一个飓风,在飓风路径上的任何东西都会被抛上天。
|
||||
spell.ebwizardry:transience.desc=使施法者金身20秒,施法者可以免疫所有伤害,但是不能破坏或者放置方块也不能造成任何伤害。
|
||||
spell.ebwizardry:transportation.desc=将施法者传送到已记录的石圈。想要使用此法术,需要制造一个传送石圈,然后用法杖右击。
|
||||
spell.ebwizardry:vanishing_box.desc=允许施法者访问末影箱子。
|
||||
spell.ebwizardry:wall_of_frost.desc=寒冬萦绕于指尖。
|
||||
spell.ebwizardry:water_breathing.desc=允许施法者水下呼吸60秒。
|
||||
spell.ebwizardry:whirlwind.desc=使目标被吹起并快速远离你。
|
||||
spell.ebwizardry:wither.desc=发射一股暗黑射线,任何与其接触的东西都将凋零。
|
||||
spell.ebwizardry:wither_skull.desc=在你指向的方向发射一个凋灵头颅。
|
||||
|
||||
spell.ebwizardry:invoke_weather.sun=雨渐渐停止...
|
||||
spell.ebwizardry:invoke_weather.rain=天堂开启了...
|
||||
spell.ebwizardry:transportation.missing=你的记录石圈遗失或是被阻挡...
|
||||
spell.ebwizardry:transportation.undefined=你必须先记录一个石圈的位置!
|
||||
spell.ebwizardry:transportation.wrongdimension=你的记录石圈在另一个维度里....
|
||||
spell.ebwizardry:clairvoyance.searching=搜寻中...
|
||||
spell.ebwizardry:clairvoyance.confirm=投掷在路径 %1$s 现在返回到这一个点
|
||||
spell.ebwizardry:clairvoyance.outofrange=你记录坐标太远或者无法访问
|
||||
spell.ebwizardry:clairvoyance.undefined=你必须首先记录一个坐标!
|
||||
spell.ebwizardry:clairvoyance.wrongdimension=你的记录坐标在另一个维度里....
|
||||
|
||||
potion.ebwizardry:frost=冻伤
|
||||
potion.ebwizardry:fireskin=火焰之肤
|
||||
potion.ebwizardry:ice_shroud=冰霜护体
|
||||
potion.ebwizardry:static_aura=静态灵气
|
||||
potion.ebwizardry:transience=金身
|
||||
potion.ebwizardry:decay=腐化
|
||||
potion.ebwizardry:sixth_sense=第六感
|
||||
potion.ebwizardry:arcane_jammer=奥术干扰
|
||||
potion.ebwizardry:mind_trick=心灵欺诈
|
||||
potion.ebwizardry:mind_control=心灵控制
|
||||
potion.ebwizardry:font_of_mana=魔力字符
|
||||
potion.ebwizardry:fear=恐惧
|
||||
|
||||
enchantment.ebwizardry:magic_sword=灌注
|
||||
enchantment.ebwizardry:magic_bow=灌注
|
||||
enchantment.ebwizardry:flaming_weapon=火焰灌注
|
||||
enchantment.ebwizardry:freezing_weapon=冰霜灌注
|
||||
|
||||
key.categories.ebwizardry=巫术学
|
||||
|
||||
key.ebwizardry.next_spell=下一个法术
|
||||
key.ebwizardry.previous_spell=上一个法术
|
||||
|
||||
death.attack.wizardry_magic=%1$s 被 %2$s 使用魔法杀死
|
||||
death.attack.indirect_wizardry_magic=%1$s 被 %2$s 使用魔法杀死
|
||||
|
||||
commands.ebwizardry:cast.usage=/%1$s <法术> [玩家] [伤害倍数] [范围倍数] [时限倍数] [爆炸倍数]
|
||||
commands.ebwizardry:cast.success=成功发动 %1$s
|
||||
commands.ebwizardry:cast.success_continuous=成功发动 %1$s ;重复该条指令停止
|
||||
commands.ebwizardry:cast.success_remote=成功发动 %1$s 至 %2$s
|
||||
commands.ebwizardry:cast.success_remote_continuous=成功发动 %1$s 至 %2$s ;重复该条指令停止
|
||||
commands.ebwizardry:cast.fail=无法 %1$s
|
||||
commands.ebwizardry:cast.not_found==没有 %1$s 这种法术ID
|
||||
commands.ebwizardry:cast.tag_error=数据标签解析错误: %s
|
||||
|
||||
commands.ebwizardry:ally.usage=/%1$s <玩家> [玩家]
|
||||
commands.ebwizardry:ally.addally=%1$s 已添加到 %2$s 的盟友列表
|
||||
commands.ebwizardry:ally.removeally=%1$s 已经从 %2$s 的盟友列表中移除
|
||||
commands.ebwizardry:ally.self=玩家不能成为自己的盟友!
|
||||
commands.ebwizardry:ally.permission=你没有权限改变其它玩家的盟友
|
||||
|
||||
commands.ebwizardry:allies.usage=/%1$s [玩家]
|
||||
commands.ebwizardry:allies.list=与你结盟的玩家 %1$s
|
||||
commands.ebwizardry:allies.list_other=玩家结盟 %1$s: %2$s
|
||||
commands.ebwizardry:allies.permission=你没有权限查看其它玩家的盟友
|
||||
commands.ebwizardry:allies.none=无
|
||||
|
||||
commands.ebwizardry:discoverspell.usage=/%1$s <法术/所有/清除> [玩家]
|
||||
commands.ebwizardry:discoverspell.not_found=没有 %1$s 这种法术ID
|
||||
commands.ebwizardry:discoverspell.clear=从 %1$s 中清除所有法术探索数据
|
||||
commands.ebwizardry:discoverspell.all=添加所有的法术到 %1$s 的法术探索数据中
|
||||
commands.ebwizardry:discoverspell.addspell=将 %1$s 添加 %2$s 的法术探索数据中
|
||||
commands.ebwizardry:discoverspell.removespell=将 %1$s 从 %2$s 的法术探索数据中移除
|
||||
|
||||
config.ebwizardry.title.general=Mod 配置
|
||||
|
||||
config.ebwizardry.category.spells=配置法术
|
||||
config.ebwizardry.category.spells.tooltip=选择以启用法术
|
||||
config.ebwizardry.title.spells=法术配置
|
||||
config.ebwizardry.subtitle.spells=将一个法术设置为false以禁用。
|
||||
|
||||
config.ebwizardry.category.resistances=配置抗性
|
||||
config.ebwizardry.category.resistances.tooltip=配置某些怪物对不同属性魔法的抗性
|
||||
config.ebwizardry.title.resistances=抗性配置
|
||||
config.ebwizardry.subtitle.resistances=详情请参考个别选项说明。
|
||||
|
||||
config.ebwizardry.category.ids=配置 IDs
|
||||
config.ebwizardry.category.ids.tooltip=改变巫师的ID
|
||||
config.ebwizardry.title.ids=ID 配置
|
||||
config.ebwizardry.subtitle.ids=如果这些ID与另一个Mod发生冲突,请更改这些ID
|
||||
|
||||
config.ebwizardry.tower_rarity=巫师塔稀有程度
|
||||
config.ebwizardry.ore_dimensions=水晶矿生成维度
|
||||
config.ebwizardry.flower_dimensions=水晶花生成维度
|
||||
config.ebwizardry.tower_dimensions=巫师塔生成维度
|
||||
config.ebwizardry.spell_book_drop_chance=法术书掉落几率
|
||||
config.ebwizardry.generate_loot=生成战利品
|
||||
config.ebwizardry.firebomb_is_craftable=火焰弹制作
|
||||
config.ebwizardry.poison_bomb_is_craftable=毒液弹制作
|
||||
config.ebwizardry.smoke_bomb_is_craftable=烟雾弹制作
|
||||
config.ebwizardry.use_alternate_scroll_recipe=使用替代卷轴合成
|
||||
config.ebwizardry.teleport_through_unbreakable_blocks=传送穿过不可破坏的方块
|
||||
config.ebwizardry.show_summoned_creature_names=显示召唤生物名称
|
||||
config.ebwizardry.friendly_fire=友军伤害
|
||||
config.ebwizardry.telekinetic_disarmament=隔空取物解除装备
|
||||
config.ebwizardry.discovery_mode=探索模式
|
||||
config.ebwizardry.enable_shift_scrolling=启用 Shift-_滚轮
|
||||
config.ebwizardry.minion_revenge_targeting=仆从反击目标
|
||||
config.ebwizardry.player_damage_scaling=玩家伤害比例因数
|
||||
config.ebwizardry.npc_damage_scaling=NPC伤害比例因数
|
||||
config.ebwizardry.cast_command_multiplier_limit=Cast指令倍数限制
|
||||
config.ebwizardry.summoned_creature_targets_whitelist=召唤生物的目标白名单
|
||||
config.ebwizardry.summoned_creature_targets_blacklist=召唤生物的目标黑名单
|
||||
config.ebwizardry.spell_hud_position=法术HUD位置
|
||||
config.ebwizardry.cast_command_name=Cast Spell指令名字
|
||||
config.ebwizardry.discoverspell_command_name=Discover Spell指令名字
|
||||
config.ebwizardry.ally_command_name=设置Ally指令名字
|
||||
config.ebwizardry.allies_command_name=查看Allies指令名字
|
||||
|
||||
config.ebwizardry.mobs_immune_to_fire=免疫火焰的怪物
|
||||
config.ebwizardry.mobs_immune_to_ice=免疫冰冻的怪物
|
||||
config.ebwizardry.mobs_immune_to_lightning=免疫闪电的怪物
|
||||
config.ebwizardry.mobs_immune_to_wither=免疫凋零的怪物
|
||||
config.ebwizardry.mobs_immune_to_poison=免疫毒液的怪物
|
||||
|
||||
config.ebwizardry.tower_rarity.tooltip=巫师塔的稀有度,数字越高越罕见。设置为0完全禁用巫师塔。
|
||||
config.ebwizardry.ore_dimensions.tooltip=水晶矿石生成的维度ID。请注意,从这个列表中删除主世界(id 0)这将使得这个mod非常难玩。
|
||||
config.ebwizardry.flower_dimensions.tooltip=水晶花会自动生成的维度ID。
|
||||
config.ebwizardry.tower_dimensions.tooltip=巫师塔生成维度ID的列表。
|
||||
config.ebwizardry.spell_book_drop_chance.tooltip=怪物死亡时掉落法术书的几率,数字越大,掉的越多。设置为0可以关闭法术书的掉落,设置200保证掉落。
|
||||
config.ebwizardry.generate_loot.tooltip=是否在地牢箱子中生成战利品。
|
||||
config.ebwizardry.firebomb_is_craftable.tooltip=是否可以制造火焰弹。
|
||||
config.ebwizardry.poison_bomb_is_craftable.tooltip=是否可以制造毒液弹。
|
||||
config.ebwizardry.smoke_bomb_is_craftable.tooltip=是否可以制造烟雾弹。
|
||||
config.ebwizardry.use_alternate_scroll_recipe.tooltip=是否需要魔法水晶在空白卷轴中无序合成中,如果另一个mod添加配方冲突,则设置为true。
|
||||
config.ebwizardry.teleport_through_unbreakable_blocks.tooltip=是否允许玩家使用相位来穿过不可破坏的方块(如 基岩)。
|
||||
config.ebwizardry.show_summoned_creature_names.tooltip=是否将召唤的生物名字和所有者显示在头顶。
|
||||
config.ebwizardry.friendly_fire.tooltip=是否允许玩家使用魔法伤害他们的盟友。
|
||||
config.ebwizardry.telekinetic_disarmament.tooltip=是否允许玩家使用隔空取物来解除其他玩家的装备。ebwizardry:设置为false防止物品被盗。
|
||||
config.ebwizardry.discovery_mode.tooltip=对于那些喜欢神秘的人!当设置为true时,你还没施放的法术不可读,知道施放后(基于这个世界)。在创造模式下无效,如果这是false,在生存模式下无法获得待鉴定卷轴。
|
||||
config.ebwizardry.enable_shift_scrolling.tooltip=是否可以在滑翔的时候使用鼠标滚轮切换法杖上的法术。请注意,这只会影响到你,同一个服务器的其他玩家只会按照他们自己的设置。
|
||||
config.ebwizardry.minion_revenge_targeting.tooltip=如果被召唤生物的主人攻击它们,它们是否可以反击它们的主人。
|
||||
config.ebwizardry.player_damage_scaling.tooltip=玩家施放法术造成伤害的比例因数, relative to 1.
|
||||
config.ebwizardry.npc_damage_scaling.tooltip=NPC施放法术造成伤害的比例因数,relative to 1。
|
||||
config.ebwizardry.cast_command_multiplier_limit.tooltip=输入/cast命令的最大倍数的上限,这是为了阻止玩家意外毁坏存档/服务器。大倍数爆炸会造成极大的延迟-你已经被警告过了!
|
||||
config.ebwizardry.summoned_creature_targets_whitelist.tooltip=除了默认外,允许召唤生物和巫师攻击实体名单。如果想让召唤的生物攻击它们。请把这个mod的生物添加到这个列表中。实体名称不区分大小写。对于mod实体,以mod ID作为前缀(例如 ebwizardry.wizard)。
|
||||
config.ebwizardry.summoned_creature_targets_blacklist.tooltip=不允许召唤生物和巫师进行攻击的默认设置和白名单。如果允许它们进行攻击会导致问题或是太具破坏性(将爬行者移除这个名单后果自负!)。把这个mod的生物添加到这个列表中。实体名称不区分大小写。对于mod实体,以mod ID作为前缀(例如 ebwizardry.wizard)。
|
||||
config.ebwizardry.spell_hud_position.tooltip=法术HUD的位置
|
||||
config.ebwizardry.cast_command_name.tooltip=/cast的命令名称。这是你直接输入/后的应该输入的内容。如果这个设置为“magic”,那么不需要输入/cast,而是输入/magic。
|
||||
config.ebwizardry.discoverspell_command_name.tooltip=/discoverspell的命令名称。这是你直接输入/后的应该输入的内容。如果这个设置为“magic”,那么不需要输入/discoverspell,而是输入/magic。
|
||||
config.ebwizardry.ally_command_name.tooltip=/ally的命令名称。这是你直接输入/后的应该输入的内容。如果这个设置为“magic”,那么不需要输入/ally,而是输入/magic。
|
||||
config.ebwizardry.allies_command_name.tooltip=/allies的命令名称。这是你直接输入/后的应该输入的内容。如果这个设置为“magic”,那么不需要输入/allies,而是输入/magic。
|
||||
|
||||
config.ebwizardry.mobs_immune_to_fire.tooltip=除了默认外,不受火焰影响的实体名称列表。如果你想让他们不受火焰魔法影响,请把这个mod的生物添加到这个列表中。实体名称不区分大小写。对于mod实体,以mod ID作为前缀(例如 ebwizardry.wizard)。
|
||||
config.ebwizardry.mobs_immune_to_ice.tooltip=除了默认外,不受冰冻影响的实体名称列表。如果你想让他们不受冰冻魔法影响,请把这个mod的生物添加到这个列表中。实体名称不区分大小写。对于mod实体,以mod ID作为前缀(例如 ebwizardry.wizard)。
|
||||
config.ebwizardry.mobs_immune_to_lightning.tooltip=除了默认外,不受闪电影响的实体名称列表。如果你想让他们不受闪电魔法影响,请把这个mod的生物添加到这个列表中。实体名称不区分大小写。对于mod实体,以mod ID作为前缀(例如 ebwizardry.wizard)。
|
||||
config.ebwizardry.mobs_immune_to_wither.tooltip=除了默认外,不受凋零影响的实体名称列表。如果你想让他们不受凋零魔法影响,请把这个mod的生物添加到这个列表中。实体名称不区分大小写。对于mod实体,以mod ID作为前缀(例如 ebwizardry.wizard)。
|
||||
config.ebwizardry.mobs_immune_to_poison.tooltip=除了默认外,不受毒液影响的实体名称列表。如果你想让他们不受毒液魔法影响,请把这个mod的生物添加到这个列表中。实体名称不区分大小写。对于mod实体,以mod ID作为前缀(例如 ebwizardry.wizard)。
|
||||
|
||||
wizard.debug=%1$s, %2$s, %3$s
|
||||
@@ -7,7 +7,8 @@
|
||||
],
|
||||
"key": {
|
||||
"v": {
|
||||
"item": "minecraft:gold_nugget"
|
||||
"type": "forge:ore_dict",
|
||||
"ore": "nuggetGold"
|
||||
},
|
||||
"w": {
|
||||
"item": "minecraft:carpet",
|
||||
@@ -17,7 +18,8 @@
|
||||
"item": "ebwizardry:magic_crystal"
|
||||
},
|
||||
"y": {
|
||||
"item": "minecraft:lapis_block"
|
||||
"type": "forge:ore_dict",
|
||||
"ore": "blockLapis"
|
||||
},
|
||||
"z": {
|
||||
"type": "forge:ore_dict",
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:paper"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:string"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"item": "ebwizardry:blank_scroll"
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"group": "magic_crystal",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "ebwizardry:crystal_block"
|
||||
@@ -7,6 +8,6 @@
|
||||
],
|
||||
"result": {
|
||||
"item": "ebwizardry:magic_crystal",
|
||||
"amount": 9
|
||||
"count": 9
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"group": "magic_crystal",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "ebwizardry:crystal_flower"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"item": "ebwizardry:magic_crystal",
|
||||
"count": 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:blaze_powder"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:blaze_powder"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:glass_bottle"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:gunpowder"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"item": "ebwizardry:firebomb",
|
||||
"count": 3
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
" x ",
|
||||
"xyx",
|
||||
" x "
|
||||
],
|
||||
"key": {
|
||||
"x": {
|
||||
"item": "ebwizardry:magic_crystal"
|
||||
},
|
||||
"y": {
|
||||
"item": "minecraft:book"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "ebwizardry:spell_book",
|
||||
"data": 1
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"type": "forge:ore_shaped",
|
||||
"pattern": [
|
||||
" z",
|
||||
" y ",
|
||||
"x "
|
||||
],
|
||||
"key": {
|
||||
"x": {
|
||||
"type": "forge:ore_dict",
|
||||
"ore": "nuggetGold"
|
||||
},
|
||||
"y": {
|
||||
"type": "forge:ore_dict",
|
||||
"ore": "stickWood"
|
||||
},
|
||||
"z": {
|
||||
"item": "ebwizardry:magic_crystal"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "ebwizardry:magic_wand"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
{
|
||||
"item": "minecraft:spider_eye"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:spider_eye"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:glass_bottle"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:gunpowder"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"item": "ebwizardry:poison_bomb",
|
||||
"count": 3
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"type": "minecraft:crafting_shapeless",
|
||||
"ingredients": [
|
||||
[
|
||||
{
|
||||
"item": "minecraft:coal",
|
||||
"data": 0
|
||||
},
|
||||
{
|
||||
"item": "minecraft:coal",
|
||||
"data": 1
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"item": "minecraft:coal",
|
||||
"data": 0
|
||||
},
|
||||
{
|
||||
"item": "minecraft:coal",
|
||||
"data": 1
|
||||
}
|
||||
],
|
||||
{
|
||||
"item": "minecraft:glass_bottle"
|
||||
},
|
||||
{
|
||||
"item": "minecraft:gunpowder"
|
||||
}
|
||||
],
|
||||
"result": {
|
||||
"item": "ebwizardry:smoke_bomb",
|
||||
"count": 3
|
||||
}
|
||||
}
|
||||
@@ -209,9 +209,17 @@ Thanks also to the Minecraft modding community, which always has an answer to my
|
||||
|
||||
In addition, I'd like to thank the following individuals for their contributions to the mod:
|
||||
|
||||
Code:
|
||||
|
||||
- Corail31
|
||||
- 12foo
|
||||
- Shadows-of-Fire
|
||||
- HellFirePvP
|
||||
|
||||
Translations:
|
||||
|
||||
- Russian: VilagVil
|
||||
- Spanish and Mexican Spanish: MadWrist
|
||||
- Chinese: ZHENGLOC and dragon-evol
|
||||
|
||||
Lightning ray sound effect from OhhWowProductions
|
||||
|
||||
@@ -209,9 +209,17 @@ Thanks also to the Minecraft modding community, which always has an answer to my
|
||||
|
||||
In addition, I'd like to thank the following individuals for their contributions to the mod:
|
||||
|
||||
Code:
|
||||
|
||||
- Corail31
|
||||
- 12foo
|
||||
- Shadows-of-Fire
|
||||
- HellFirePvP
|
||||
|
||||
Translations:
|
||||
|
||||
- Russian: VilagVil
|
||||
- Spanish and Mexican Spanish: MadWrist
|
||||
- Chinese: ZHENGLOC and dragon-evol
|
||||
|
||||
Lightning ray sound effect from OhhWowProductions
|
||||
|
||||
@@ -303,9 +303,17 @@ Gracias tambien a la comunidad de Minecraft que crea mods, la cual siempre tiene
|
||||
|
||||
In addition, I'd like to thank the following individuals for their contributions to the mod:
|
||||
|
||||
Code:
|
||||
|
||||
- Corail31
|
||||
- 12foo
|
||||
- Shadows-of-Fire
|
||||
- HellFirePvP
|
||||
|
||||
Translations:
|
||||
|
||||
- Russian: VilagVil
|
||||
- Spanish and Mexican Spanish: MadWrist
|
||||
- Chinese: ZHENGLOC and dragon-evol
|
||||
|
||||
Lightning ray sound effect from OhhWowProductions
|
||||
|
||||
@@ -303,9 +303,17 @@ Gracias tambien a la comunidad de Minecraft que crea mods, la cual siempre tiene
|
||||
|
||||
In addition, I'd like to thank the following individuals for their contributions to the mod:
|
||||
|
||||
Code:
|
||||
|
||||
- Corail31
|
||||
- 12foo
|
||||
- Shadows-of-Fire
|
||||
- HellFirePvP
|
||||
|
||||
Translations:
|
||||
|
||||
- Russian: VilagVil
|
||||
- Spanish and Mexican Spanish: MadWrist
|
||||
- Chinese: ZHENGLOC and dragon-evol
|
||||
|
||||
Lightning ray sound effect from OhhWowProductions
|
||||
|
||||
@@ -214,9 +214,17 @@ Thanks also to the Minecraft modding community, which always has an answer to my
|
||||
|
||||
In addition, I'd like to thank the following individuals for their contributions to the mod:
|
||||
|
||||
Code:
|
||||
|
||||
- Corail31
|
||||
- 12foo
|
||||
- Shadows-of-Fire
|
||||
- HellFirePvP
|
||||
|
||||
Translations:
|
||||
|
||||
- Russian: VilagVil
|
||||
- Spanish and Mexican Spanish: MadWrist
|
||||
- Chinese: ZHENGLOC and dragon-evol
|
||||
|
||||
Lightning ray sound effect from OhhWowProductions
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
PAGEBREAK
|
||||
LINEBREAK
|
||||
|
||||
|
||||
|
||||
|
||||
巫师手册
|
||||
|
||||
|
||||
|
||||
作者 Electroblob
|
||||
PAGEBREAK
|
||||
简介
|
||||
--------------------
|
||||
|
||||
欢迎您,伟大的巫师!本书将会向您阐释奥术的工作原理以及使用它们的方法。
|
||||
|
||||
如果您不慎遗失了本书,您可以在工作台上用书和魔法水晶制作一本新的。
|
||||
PAGEBREAK
|
||||
内容
|
||||
--------------------
|
||||
PAGEBREAK
|
||||
SECTION 准备工作
|
||||
准备工作
|
||||
--------------------
|
||||
要打开通向巫术的大门,您将会需要以下几样东西:
|
||||
|
||||
- 一根法杖,由一粒金粒,一根木棍和一块魔法水晶合成。
|
||||
|
||||
- 一个奥术工作台,由三块石头,一块青金石块,两块魔法水晶,两粒金粒和一块紫色地毯合成。
|
||||
|
||||
- 一本法术书,它们可以在箱子中找到,由怪物掉落或向巫师们购买。当然您也可以用一本书和四块魔法水晶制作一个初学者的法术“魔法飞弹”。
|
||||
|
||||
此外,您将会需要更多的魔法水晶来为您的法杖提供魔力。
|
||||
PAGEBREAK
|
||||
SECTION 魔力
|
||||
魔力
|
||||
--------------------
|
||||
魔力是给予巫师们力量的奥术能量。它在自然界中以水晶的形式存在,这些水晶嵌在石缝中,可以在地下被找到。法杖中可以储存魔力,而这些魔力将被塑造为您施展的法术。不同的法术会消耗不同数量的魔力,这取决于它们有多么强大以及它们会持续多久。
|
||||
|
||||
将鼠标悬停在法杖上就可以看到其中的魔力储量。
|
||||
IMAGE CRYSTAL
|
||||
LINEBREAK
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
魔法
|
||||
水晶矿 水晶
|
||||
PAGEBREAK
|
||||
SECTION 法杖
|
||||
法杖
|
||||
--------------------
|
||||
法杖是一个巫师的实用之选。有了法杖,您就可以施展任何法术,只要法杖能够承受它的力量(更深入的解释在“等级”一节中)。
|
||||
法杖有许多不同的种类,但您将从最基本的法杖开始。
|
||||
|
||||
拿着法杖时,屏幕的角落会出现一个小小的提示,它会显示当前选择的法术及其图标。此外,如果一个法术被施展了,会有一个冷却条显示还有多久才能再次施展这个法术。
|
||||
PAGEBREAK
|
||||
SECTION 法术
|
||||
法术
|
||||
--------------------
|
||||
一根没有法术可施展的法杖是毫无用处的。法术可以通过两种方式被记录下来:永久地记录在书上,或者暂时地记录在卷轴上。
|
||||
|
||||
法术书本身没有什么用处,它们是用来将其中记录的法术绑定到法杖上的。法术书可以在世界各处被发现,而且您肯定很快就会找到一本。当您发现了一本法术书时,您可以将鼠标悬停在上面来看一下法术的基本信息,您也可以拿着法术书按下右键来阅读法术的详细信息。
|
||||
|
||||
与之相反,卷轴的使用方式是不一样的:拿着卷轴右击将会施展其中绑定的法术,而在这个过程中卷轴将会被摧毁。像法术书一样,卷轴可以在世界各处被发现,但您也可以自己制作它们。首先拿一张纸和一些线合成空白卷轴,然后您可以在奥术工作台上将法术绑定到卷轴上,前提是您拥有关于这个法术的知识。这么做将会消耗与法术的魔力消耗相对应数量的魔法水晶(消耗的魔法水晶个数是向上取整的)。
|
||||
|
||||
对于未经训练的人来说,用于书写法术的魔法符文是无法辨识的。为了鉴定一个法术,您当然可以施展它然后看看发生了什么 - 但这么做可能会产生您不想看到的副作用,而且许多法术需要在特定的条件下才能起作用。一种更安全可靠的选择是使用鉴定卷轴,它可以在箱子里找到或向巫师购买。拿着它右击将会鉴定您热键栏中第一个未知的法术书或卷轴,并消耗鉴定卷轴。
|
||||
|
||||
如果您需要在一次探险中使用某个法术一两次但又不希望它占用您法杖的一个槽,那卷轴是十分有用的。但值得注意的是卷轴是一种相当没有效率的施法方式。
|
||||
PAGEBREAK
|
||||
SECTION 奥术工作台
|
||||
奥术工作台
|
||||
--------------------
|
||||
奥术工作台的外观和附魔台很像,您可以在其中给法杖充能、升级或绑定法术。只要放下它并右击,您就会看到一个界面出现,就像右边展示的一样。
|
||||
PAGEBREAK
|
||||
IMAGE WORKBENCH
|
||||
LINEBREAK
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
奥术工作台
|
||||
PAGEBREAK
|
||||
SECTION 绑定法术
|
||||
绑定法术
|
||||
--------------------
|
||||
要把一个法术绑定到法杖上,只要把法杖放在奥术工作台中央的格子里,然后把法术书放在周围的任意一个格子里并按下“应用”。您至多可以在一根法杖上绑定五个法术,当然这一数量可以通过法杖协调升级来增加。拿着法杖时,您可以通过 NEXT_SPELL_KEY 键和 PREVIOUS_SPELL_KEY 键在不同的法术间切换(按键可以在选项 -> 控制里调整)。您也可以在潜行时上下滚动鼠标滚轮来切换法术。
|
||||
|
||||
SECTION 法杖充能
|
||||
法杖充能
|
||||
--------------------
|
||||
要给法杖充能,只要把法杖放在奥术工作台中央的格子里,然后在左侧两个格子靠上的那个放一些魔法水晶并按下“应用”。每个水晶等同于 MANA_PER_CRYSTAL 魔力,而法杖只会吸收它所需要的数量,所以您可以在奥术工作台中储备一些魔力水晶以便随时使用。然而,谨记法杖只能整块地吸收魔法水晶。所以如果法杖仅仅还需要 30 魔力,那么 MANA_PER_CRYSTAL_MINUS_30 魔力就会在充能过程中流失。在内部没有魔力时,所有的法杖都会吸收确定数量的魔法水晶来充能,除非它们拥有法杖存储升级。
|
||||
|
||||
SECTION 升级法杖
|
||||
升级法杖
|
||||
--------------------
|
||||
要升级法杖,您需要一本对应等级的(参见“等级”)奥法宝典或者某种法杖升级。这两种东西都可以作为战利品得到或者向巫师购买。要升级法杖,只要把法杖放在奥术工作台中央的格子里,然后在左侧两个格子靠下的那个放上法杖升级并按下“应用”。
|
||||
|
||||
法杖升级会提升法杖某一方面的性能。每种法杖升级可以叠加至多三次,而法杖能升级的总次数取决于其等级。升级是不可逆的,无法被重新移除。
|
||||
PAGEBREAK
|
||||
SECTION 鲜花与烧瓶
|
||||
鲜花与烧瓶
|
||||
--------------------
|
||||
您很可能时不时在野外见到一些神秘的闪着光芒的花。这些是水晶花,是一种自然产生的魔力来源。它们可以被采集,其中的魔力可以像魔力水晶一样被提取出来。
|
||||
|
||||
需要在路上给您的法杖充能?没问题!魔力现在可以被装瓶了。用一个玻璃瓶和八个魔力水晶制作一个魔力瓶并带在身上,当您需要使用它时,将它和您的法杖放在一起合成,法杖就会回复一些魔力,而魔力瓶会被消耗掉。在装瓶过程中魔力会有耗损。
|
||||
PAGEBREAK
|
||||
SECTION 等级
|
||||
等级
|
||||
--------------------
|
||||
法杖和法术有四个等级:BASIC_COLOUR新手RESET_COLOUR,APPRENTICE_COLOUR学徒RESET_COLOUR,ADVANCED_COLOUR进阶RESET_COLOUR和MASTER_COLOUR大师RESET_COLOUR。每一个等级都比上一个等级更加强大。
|
||||
|
||||
BASIC_COLOUR新手RESET_COLOUR法杖是可以被合成出来的法杖。它们至多储存 BASIC_MAX_CHARGE 魔力,并且只能施展新手级的法术。新手法术非常简单,可以被任何人施展并且一般不消耗很多魔力。然而这并不一定意味着等级很高时他们就毫无用处,它们的低消耗使得一些新手法术在您达到大师级之后仍十分有用。
|
||||
|
||||
APPRENTICE_COLOUR学徒RESET_COLOUR法杖是新手法杖的下一等级。它们至多储存 APPRENTICE_MAX_CHARGE 魔力,并且可以施展新手和学徒级的法术。学徒法术比起新手法术更令人印象深刻,但通常消耗更高。
|
||||
|
||||
ADVANCED_COLOUR进阶RESET_COLOUR法杖十分稀有且比前两级强大得多。它们可以施展除了大师级之外的所有法术,并储存 ADVANCED_MAX_CHARGE 魔力。进阶法术可以赋予巫师超人的力量,例如隐身,并在敌人头上倾泻毁灭。
|
||||
|
||||
MASTER_COLOUR大师RESET_COLOUR法杖是现存最强大的法杖。他们至多储存 MASTER_MAX_CHARGE 魔力,并且可以施展任何法术。大师级法术书非常稀有,而大师级法术可以给敌人带来完全的湮灭,甚至可以摧毁世界本身。慎重使用。
|
||||
PAGEBREAK
|
||||
SECTION 元素
|
||||
元素
|
||||
--------------------
|
||||
法术分属不同的元素,元素表现了法术的本质,并且在被特定的法杖使用时会有额外的效果。
|
||||
|
||||
FIRE_COLOUR火
|
||||
这也许是最具毁灭性的元素。火元素掌控燃烧、熔岩和爆炸。一位强大的烈焰法师能够在敌人头顶打开地狱之门,并能在这个过程中点燃世界。绝大多数火属性攻击法术会点燃其目标,造成持续伤害。但是,注意火属性法术也许对下界生物毫无效果。
|
||||
|
||||
ICE_COLOUR冰
|
||||
冰元素是一切寒冷之物的集合。冰属性法术通常会减速敌人或完全冻住他们,并且对火属性生物极为有效。冰属性魔法在战斗外同样有用,例如冻结水面来顺利过河。
|
||||
|
||||
LIGHTNING_COLOUR闪电
|
||||
这一元素掌控闪电、风暴和天气。一位强大的风暴法师是一股不可忽视的力量,而且他们中的某些人拥有随意降下闪电的能力。闪电法术通常会同时伤害多个敌人并且自动寻找目标,这使它们成为攻击任何生物的有效手段...但小心爬行者。
|
||||
|
||||
NECROMANCY_COLOUR死灵
|
||||
死灵是属于黑暗、混沌和不死生物的元素。死灵法师十分神秘并且常常被认为是邪恶的,虽然一般不是这回事。死灵法术通常被用来召唤为您而战的生物,甚至可以扭曲敌人的意志。
|
||||
|
||||
EARTH_COLOUR大地
|
||||
大地元素专注于自然界:动物,植物,风,凡此种种。大地魔法差异巨大且呈现形式多种多样,从让敌人中毒到释放大气的怒火。大地法术是攻击、防御和实用的综合。
|
||||
|
||||
SORCERY_COLOUR妖术
|
||||
妖术是操纵力和变化的元素。妖术法师操纵光、重力甚至是现实本身来迎合他们的需要。妖术也可以用在别的领域,例如赋予施法者魔法力量或者用意念移动物体。
|
||||
|
||||
HEALING_COLOUR治愈
|
||||
治愈元素掌控防御和再生。治愈法师尽可能地保护他们自己以及他们的盟友,因此可能是非常难缠的对手。尽管一般不用来攻击,某些治愈法术的净化光芒会对不死生物造成可观的伤害。治愈法术在战斗中是不可或缺的。
|
||||
|
||||
不同元素之间并不总是泾渭分明的,并且有些法术展现出除自身外的其他元素的特点。
|
||||
|
||||
如果您很幸运,您可能会邂逅一根元素法杖。这些法杖会让您在施展正确元素的法术时比平时拥有更强的能力。
|
||||
PAGEBREAK
|
||||
SECTION 巫师护甲
|
||||
巫师护甲
|
||||
--------------------
|
||||
作为一名巫师,您需要一些东西来保护您免受与您作战的生物的伤害。普通的护甲无法做到这一点。为了最大化利用您的法术,您将会需要巫师护甲:帽子,法袍,护腿和靴子。不像普通的护甲,这些护甲不会损坏。作为替代,它们使用奥术能量来保护穿戴者。这当然意味着它们需要像法杖一样用魔法水晶充能。幸运的是,这些服装并不会消耗很多魔力。像法杖一样用奥术工作台或魔力瓶充能它们,但小心了 - 如果它们没有了魔力,您将发现自己毫无防御力。
|
||||
|
||||
您可以用魔法丝绸来制作巫师护甲,魔法丝绸可以用线和一块魔法水晶合成。
|
||||
|
||||
那些完全专注于一种元素的巫师有时会穿上特殊的服装来让这一元素获得额外的增强。整套的此类服装十分受某些巫师的追捧而且不容易找到。
|
||||
|
||||
传说中最强大的巫师用一种奥术戳记来极大地强化他们的护甲。
|
||||
PAGEBREAK
|
||||
SECTION 巫师和巫师塔
|
||||
巫师和巫师塔
|
||||
--------------------
|
||||
别害怕 - 您不是这个世界里唯一的魔法使用者。在您的旅途中,您可能会遇到拥有标志性尖顶的高塔。这些是您巫师同僚的居所。孤独的生活有时可能会让巫师们变得有些性情乖戾,但他们通常是友好的人,并且乐意与您分享他们的知识 - 尽管要付出些代价。交给他们一些珍贵的金属和宝石,您将收获数不尽的奥术奇迹作为回报。但如果您要寻找的是大师级的法术,您需要与专家谈谈才行。
|
||||
|
||||
不幸的是,少数巫师并不欢迎访客。这些巫师通常是被放逐的人,并且对任何挡路者都怀有敌意。小心地接近他们,并准备好在强大的魔法洗礼下防卫自己。然而,如果您击败了他们,您就可以将他们的知识全部收入囊中。
|
||||
PAGEBREAK
|
||||
SECTION 合成配方
|
||||
合成配方
|
||||
--------------------
|
||||
PAGEBREAK
|
||||
PAGEBREAK
|
||||
合成配方
|
||||
--------------------
|
||||
PAGEBREAK
|
||||
PAGEBREAK
|
||||
合成配方
|
||||
--------------------
|
||||
PAGEBREAK
|
||||
PAGEBREAK
|
||||
合成配方
|
||||
--------------------
|
||||
PAGEBREAK
|
||||
PAGEBREAK
|
||||
鸣谢
|
||||
--------------------
|
||||
Electroblob's Wizardry
|
||||
Version VERSION
|
||||
For Minecraft MCVERSION
|
||||
|
||||
Designed, coded and textured by Electroblob
|
||||
|
||||
Thanks to Minecraft Forge and MCP, without which this mod would not have been possible.
|
||||
|
||||
Thanks also to the Minecraft modding community, which always has an answer to my modding problems!
|
||||
|
||||
In addition, I'd like to thank the following individuals for their contributions to the mod:
|
||||
|
||||
Code:
|
||||
|
||||
- Corail31
|
||||
- 12foo
|
||||
- Shadows-of-Fire
|
||||
- HellFirePvP
|
||||
|
||||
Translations:
|
||||
|
||||
- Russian: VilagVil
|
||||
- Spanish and Mexican Spanish: MadWrist
|
||||
- Chinese: ZHENGLOC and dragon-evol
|
||||
|
||||
Lightning ray sound effect from OhhWowProductions
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -2,14 +2,14 @@
|
||||
{
|
||||
"modid" : "ebwizardry",
|
||||
"name" : "Electroblob's Wizardry",
|
||||
"version" : "4.1.0",
|
||||
"version" : "4.1.4",
|
||||
"url" : "https://minecraft.curseforge.com/projects/electroblobs-wizardry",
|
||||
"credits" : "Made by Electroblob",
|
||||
"credits" : "Designed, coded and textured by Electroblob. Code contributed by: Corail31, 12foo, Shadows-of-Fire, HellFirePvP. Translators: MadWrist (Spanish, Mexican Spanish), VilagVil (Russian), ZHENGLOC/dragon-evol (Chinese).",
|
||||
"authors" : [
|
||||
"Electroblob"
|
||||
],
|
||||
"description" : "Electroblob's Wizardry adds an rpg-style system of magic spells to Minecraft with the aim of being as playable as possible. No crazy constructs, no perk trees, no complex recipes - simply find spell books, cast spells, and master the arcane!",
|
||||
"logoFile" : "assets/wizardry/textures/gui/logo.png",
|
||||
"logoFile" : "assets/ebwizardry/textures/gui/logo.png",
|
||||
"updateUrl" : "",
|
||||
"parent" : "",
|
||||
"screenshots": [
|
||||
|
||||
Reference in New Issue
Block a user