Compare commits
124 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c030629bab | |||
| 165d079251 | |||
| 7cc9200adf | |||
| 01a9d8c075 | |||
| 0a0a08d220 | |||
| 410768e6f3 | |||
| bbbe024bb3 | |||
| 93112d5192 | |||
| 112a562b2d | |||
| 85ca4fd100 | |||
| 136b1cc924 | |||
| e4b7d528f5 | |||
| 2903ebfbac | |||
| 931ca1b2c0 | |||
| 85e724d88a | |||
| e41f83a2dd | |||
| 69b52cfe88 | |||
| 7591821e57 | |||
| 0ce0dcf2e9 | |||
| 73811c3a6b | |||
| 2a887b7794 | |||
| ad9f482e76 | |||
| 6eaef94459 | |||
| 4f5c616240 | |||
| f5947dded9 | |||
| 77e0acc16b | |||
| e48646c5ff | |||
| 5e48fe51ea | |||
| 6b30dbef65 | |||
| d6508a2be4 | |||
| dfcadfb3bd | |||
| 7888b92129 | |||
| 5b48dffa77 | |||
| 5bf4650da1 | |||
| 8e9c270b77 | |||
| 00080331df | |||
| 27e40e2069 | |||
| 3a93877de3 | |||
| 7f70784cd3 | |||
| ed6e3df66e | |||
| eb5becbbd4 | |||
| 9599316fbc | |||
| cc1c951ef8 | |||
| d23c4cba18 | |||
| 3d30b0b96f | |||
| ad1e5d555a | |||
| 14ea5f1c72 | |||
| 709d44e4d9 | |||
| 8df00e9c41 | |||
| 8dbb0ec058 | |||
| b8310eedae | |||
| c04754afe1 | |||
| 3155aa6815 | |||
| ea27b1a081 | |||
| 4d078f9597 | |||
| 67459cbbbd | |||
| 932de4e969 | |||
| 41e28291ad | |||
| 6ae6324368 | |||
| 4858716f05 | |||
| 24fb4cfe4a | |||
| 186138d0c0 | |||
| 6690564017 | |||
| 89a0a900cc | |||
| 391a24db3f | |||
| 4b546af642 | |||
| ee8aabbf97 | |||
| 45994e2b94 | |||
| 13bdc69da8 | |||
| c0184fde8e | |||
| cbd297e59d | |||
| c6cf7c950e | |||
| fe5d80e017 | |||
| e985a8f15b | |||
| 615767f758 | |||
| 65a24b2295 | |||
| 94c2afe67a | |||
| 9bbca37ecd | |||
| 58241a0f5c | |||
| a960a01ca1 | |||
| 67d8ee773c | |||
| c6f2675278 | |||
| 2380be230e | |||
| 833276b7b3 | |||
| 9b32835720 | |||
| 61634a9cc3 | |||
| 408a35db8d | |||
| 9695a85131 | |||
| d027cf4f2a | |||
| c2f8bfc5b4 | |||
| 486425a62c | |||
| f9681d4c66 | |||
| cd0671dc59 | |||
| 7ebca16948 | |||
| e8cbdde518 | |||
| 7ca6f05151 | |||
| f4f17e90e5 | |||
| 3ea48efb1d | |||
| ffc3533688 | |||
| bd309855a2 | |||
| 1473c7e9b7 | |||
| 15cc7b6d18 | |||
| 1c89c5f779 | |||
| ca7f1cc8ca | |||
| 8fd1de84e4 | |||
| 95d9168b6b | |||
| c1db827132 | |||
| d10b78ab46 | |||
| 2d70523f43 | |||
| 42fb7ad3df | |||
| e90d0950d4 | |||
| 888d4190d1 | |||
| 57696b2538 | |||
| 1440537f6b | |||
| a16ff88c8d | |||
| 041de12ea7 | |||
| 5e36f66c4e | |||
| a6a5a6104d | |||
| 6f7b225ce8 | |||
| 81a85883d2 | |||
| 3f06d2fea4 | |||
| 26b390268a | |||
| 486d55f349 | |||
| 5948090d63 |
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"homepage": "https://www.curseforge.com/minecraft/mc-mods/electroblobs-wizardry",
|
||||
"promos": {
|
||||
"1.12.2-latest": "4.3.12",
|
||||
"1.12.2-recommended": "4.3.12"
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Report a crash or something that isn't working as it should
|
||||
title: "[Give a brief, relevant title here]"
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting.
|
||||
|
||||
Minecraft version: 1.12.2 [change as necessary]
|
||||
Wizardry version: 4.3.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.]
|
||||
|
||||
Other mods involved: [only list mods that are relevant to the problem]
|
||||
|
||||
Link to crash report (if applicable): [give a link to the crash report on gist, pastebin, etc.]
|
||||
@@ -0,0 +1,85 @@
|
||||
name: 🐛 Bug Report
|
||||
description: Something is not working as expected
|
||||
title: "[Bug] <write the title here>"
|
||||
labels: [ "bug", "Needs Triage" ]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting. You may also find the [troubleshooting page](https://github.com/Electroblob77/Wizardry/wiki/Troubleshooting) helpful.
|
||||
Please try the latest version of the mod and check if the issue persist before submitting a report.
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Is there an existing issue for this?
|
||||
description: Please search to see if an issue already exists for the bug you encountered.
|
||||
options:
|
||||
- label: I have searched the existing issues
|
||||
required: true
|
||||
- type: textarea
|
||||
id: observed
|
||||
attributes:
|
||||
label: Observed behaviour
|
||||
description: Describe what happened and when this happened
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected behaviour
|
||||
description: Describe what you expected to happen
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Step by step instructions on how to reproduce the observed behaviour
|
||||
placeholder: |
|
||||
1. Join a server
|
||||
2. Cast the [spell]
|
||||
3. ...
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: crashlog
|
||||
attributes:
|
||||
label: Crashlog
|
||||
description: If this was a crash, grab [minecraft instance]/logs/debug.log, upload it as a [gist](https://gist.github.com/) and paste the link here. Alternatively, give a link to the crash report on gist, pastebin if you already have one there.
|
||||
placeholder: https://gist.github.com/<your-user>/abcdef124
|
||||
- type: dropdown
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment (Singleplayer/Server, etc.)
|
||||
options:
|
||||
- Singleplayer
|
||||
- LAN game/Server
|
||||
- Issue present on both sides
|
||||
- Not sure
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: mod-version
|
||||
attributes:
|
||||
label: Mod version
|
||||
placeholder: 1.0.0
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: minecraft-version
|
||||
attributes:
|
||||
label: Minecraft version
|
||||
placeholder: 12.2.2
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: forge-version
|
||||
attributes:
|
||||
label: Forge version
|
||||
placeholder: 1.12.2 - 14.23.5.2860
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: other-mods
|
||||
attributes:
|
||||
label: Other mods
|
||||
description: List any other mods present when the bug was encountered, include the mod versions. You only have to fill this if no crash log was attached
|
||||
@@ -0,0 +1,14 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 📖 Mod Wiki Page
|
||||
url: https://github.com/Electroblob77/Wizardry/wiki
|
||||
about: Most features are documented in the mod's wiki page --- Link --->
|
||||
- name: 💬 Electroblob's Wizardry discord
|
||||
url: https://discord.gg/hs8yJP2
|
||||
about: Ask for help or get more info on Discord. --- Discord Server link --->
|
||||
- name: 💡 Feature requests / suggestions
|
||||
url: https://discord.gg/hs8yJP2
|
||||
about: Please use the discord server to suggest stuff. --- Discord Server link --->
|
||||
- name: ❓ Question
|
||||
url: https://discord.gg/hs8yJP2
|
||||
about: Ask a question about the mod or the code. --- Discord Server link --->
|
||||
@@ -1,16 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Make a suggestion for improving the mod
|
||||
title: "[Give a brief, relevant title here]"
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting.
|
||||
|
||||
Minecraft versions: [if this suggestion only applies to some versions, list them here]
|
||||
|
||||
Suggestion details: [describe what you would like to see added to the mod and why]
|
||||
|
||||
Other mods involved: [if this suggestion involves integration with other mods, list them here]
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
name: Question
|
||||
about: Ask a question about the mod or the code
|
||||
title: "[Give a brief, relevant title here]"
|
||||
labels: question
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/CONTRIBUTING.md) before posting.
|
||||
|
||||
Minecraft version: 1.12.2 [change as necessary]
|
||||
Wizardry version: 4.3.4 [change as necessary]
|
||||
|
||||
Question details: [explain your question here]
|
||||
|
||||
Other mods involved: [if this question involves other mods, list them here]
|
||||
@@ -0,0 +1,38 @@
|
||||
name: Potential Duplicates
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: bubkoo/potential-duplicates@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
label: potential duplicate
|
||||
exclude: |
|
||||
adding
|
||||
add
|
||||
creating
|
||||
create
|
||||
icons
|
||||
icon
|
||||
logos
|
||||
logo
|
||||
missing
|
||||
miss
|
||||
needing
|
||||
need
|
||||
please
|
||||
requesting
|
||||
request
|
||||
1.12.2
|
||||
wizardry
|
||||
state: all
|
||||
threshold: 0.7
|
||||
comment: |
|
||||
This issue is potentially a duplicate of one of the following issues:
|
||||
{{#issues}}
|
||||
- [#{{ number }}] {{ title }} ({{ accuracy }}% match)
|
||||
{{/issues}}
|
||||
+8
-2
@@ -1,7 +1,7 @@
|
||||
# Credits
|
||||
|
||||
Electroblob's Wizardry
|
||||
Version 4.3.4
|
||||
Version 4.3.7
|
||||
For Minecraft 1.12.2
|
||||
|
||||
Designed, coded and textured by Electroblob
|
||||
@@ -12,6 +12,11 @@ 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:
|
||||
|
||||
#### Discord Moderators (and all-round awesome people)
|
||||
|
||||
- FavouriteDragon
|
||||
- WinDanesz
|
||||
|
||||
#### Code
|
||||
|
||||
- Corail31
|
||||
@@ -27,13 +32,14 @@ In addition, I'd like to thank the following individuals for their contributions
|
||||
- rafasoares
|
||||
- xinyuan-liu
|
||||
- SettingDust
|
||||
- Aralu115
|
||||
|
||||
#### Translations
|
||||
|
||||
- Spanish: MadWrist, Alsentar
|
||||
- Mexican Spanish: MadWrist
|
||||
- Russian: VilagVil, kellixon, bigenergy, MugGod2, DrHesperus
|
||||
- French: Hahdrim
|
||||
- French: Hahdrim, Crowller
|
||||
- Brazilian Portuguese: lorrampi
|
||||
- Chinese (Simplified): ZHENGLOC, dragon-evol, Hokorizero, TUsama, Determancer
|
||||
- Korean: shejery, rewi_wire, 방통, red1854th
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting.
|
||||
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting. You may also find the [troubleshooting page](https://github.com/Electroblob77/Wizardry/wiki/Troubleshooting) helpful.
|
||||
|
||||
Minecraft version: 1.12.2 [change as necessary]
|
||||
Wizardry version: 4.3.4 [change as necessary]
|
||||
Wizardry version: [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.]
|
||||
|
||||
+112
-50
@@ -1,64 +1,127 @@
|
||||
import groovy.json.JsonOutput
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
jcenter()
|
||||
maven { url = "http://files.minecraftforge.net/maven" }
|
||||
gradlePluginPortal()
|
||||
maven {
|
||||
name 'MinecraftForge'
|
||||
url 'https://maven.minecraftforge.net/'
|
||||
}
|
||||
maven {
|
||||
name 'Garden of Fancy'
|
||||
url 'https://maven.gofancy.wtf/releases'
|
||||
}
|
||||
//fallback for fancygradle maven
|
||||
//mavenLocal()
|
||||
maven {
|
||||
name 'Sponge'
|
||||
url 'https://repo.spongepowered.org/repository/maven-public/'
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
|
||||
classpath 'net.minecraftforge.gradle:ForgeGradle:5.+'
|
||||
classpath 'org.ajoberstar.grgit:grgit-gradle:3.1.1'
|
||||
classpath group: 'wtf.gofancy.fancygradle', name: 'wtf.gofancy.fancygradle.gradle.plugin', version: '1.1.+'
|
||||
}
|
||||
|
||||
repositories.each {
|
||||
if (it instanceof MavenArtifactRepository && it.url.toString() == "https://files.minecraftforge.net/maven") {
|
||||
it.url = "https://maven.minecraftforge.net"
|
||||
}
|
||||
}
|
||||
}
|
||||
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.
|
||||
|
||||
apply plugin: 'net.minecraftforge.gradle'
|
||||
apply plugin: 'idea'
|
||||
apply plugin: 'maven-publish'
|
||||
apply plugin: org.ajoberstar.grgit.gradle.GrgitPlugin
|
||||
apply plugin: 'wtf.gofancy.fancygradle'
|
||||
|
||||
|
||||
version = "4.3.4" // There, it matches semver, happy now?
|
||||
version = "4.3.12"
|
||||
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
archivesBaseName = "ElectroblobsWizardry"
|
||||
|
||||
sourceCompatibility = targetCompatibility = "1.8" // Need this here so eclipse task generates correctly.
|
||||
compileJava {
|
||||
sourceCompatibility = targetCompatibility = "1.8"
|
||||
sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
|
||||
|
||||
|
||||
minecraft {
|
||||
// The mappings can be changed at any time, and must be in the following format.
|
||||
// snapshot_YYYYMMDD Snapshot are built nightly.
|
||||
// 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 channel: 'snapshot', version: '20171003-1.12'
|
||||
mappings channel: "stable", version: "39-1.12"
|
||||
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
|
||||
|
||||
// accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||
|
||||
// Default run configurations.
|
||||
// These can be tweaked, removed, or duplicated as needed.
|
||||
runs {
|
||||
client {
|
||||
workingDirectory project.file('run')
|
||||
|
||||
// Recommended logging data for a userdev environment
|
||||
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
|
||||
|
||||
// Recommended logging level for the console
|
||||
property 'forge.logging.console.level', 'info'
|
||||
}
|
||||
|
||||
server {
|
||||
|
||||
// Recommended logging data for a userdev environment
|
||||
property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
|
||||
|
||||
// Recommended logging level for the console
|
||||
property 'forge.logging.console.level', 'info'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven {
|
||||
// location of the maven that hosts JEI files
|
||||
name = "Progwml6 maven"
|
||||
url = "http://dvs1.progwml6.com/files/maven"
|
||||
url = uri('https://www.cursemaven.com')
|
||||
content {
|
||||
includeGroup 'curse.maven'
|
||||
}
|
||||
}
|
||||
maven {
|
||||
// location of a maven mirror for JEI files, as a fallback
|
||||
name = "ModMaven"
|
||||
url = "modmaven.k-4u.nl"
|
||||
name = 'Modrinth'
|
||||
url = uri('https://api.modrinth.com/maven')
|
||||
content {
|
||||
includeGroup 'maven.modrinth'
|
||||
}
|
||||
}
|
||||
maven {
|
||||
name = "Curseforge Maven"
|
||||
url = "https://minecraft.curseforge.com/api/maven/"
|
||||
name = 'Sponge'
|
||||
url = uri('https://repo.spongepowered.org/maven')
|
||||
}
|
||||
maven {
|
||||
url = uri('https://maven.blamejared.com')
|
||||
}
|
||||
maven {
|
||||
url = uri('https://m2.dv8tion.net/releases')
|
||||
}
|
||||
maven {
|
||||
url = uri('https://jitpack.io')
|
||||
}
|
||||
}
|
||||
|
||||
minecraft {
|
||||
version = "1.12.2-14.23.5.2847"
|
||||
runDir = "run"
|
||||
|
||||
// the mappings can be changed at any time, and must be in the following format.
|
||||
// snapshot_YYYYMMDD snapshot are built nightly.
|
||||
// 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 = "stable_39"
|
||||
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
// Compile against the JEI API but do not include it at runtime
|
||||
deobfProvided "mezz.jei:jei_${mc_version}:${jei_version}:api"
|
||||
// At runtime, use the full JEI jar
|
||||
runtime "mezz.jei:jei_${mc_version}:${jei_version}"
|
||||
|
||||
deobfCompile "baubles:Baubles:${mc_version_short}:${baubles_version}"
|
||||
deobfCompile "antique-atlas:antiqueatlas:${mc_version}:${antique_atlas_version}"
|
||||
//// MC version ////
|
||||
// Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed
|
||||
// that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied.
|
||||
// The userdev artifact is a special name and will get all sorts of transformations applied to it.
|
||||
minecraft "net.minecraftforge:forge:${project.mc_version}-${project.forge_version}"
|
||||
//// MC version ////
|
||||
implementation fg.deobf("curse.maven:baubles-${baubles_projectid}:${baubles_fileid}")
|
||||
implementation fg.deobf("mezz.jei:jei_${mc_version}:${jei_version}")
|
||||
implementation fg.deobf("curse.maven:antique-atlas-${antiqueatlas_projectid}:${antiqueatlas_fileid}")
|
||||
|
||||
}
|
||||
|
||||
@@ -68,20 +131,19 @@ task deobfJar(type: Jar) {
|
||||
}
|
||||
|
||||
processResources {
|
||||
// this will ensure that this task is redone when the versions change.
|
||||
inputs.property "version", project.version
|
||||
inputs.property "mcversion", project.minecraft.version
|
||||
|
||||
// replace stuff in mcmod.info, nothing else
|
||||
// replace tokens in mcmod.info, and pack.mcmeta
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
include 'pack.mcmeta'
|
||||
include 'mcmod.info'
|
||||
|
||||
// replace version and mcversion
|
||||
expand 'version':project.version, 'mcversion':project.minecraft.version
|
||||
}
|
||||
|
||||
// copy everything else except the mcmod.info
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude 'mcmod.info'
|
||||
|
||||
duplicatesStrategy = 'include'
|
||||
}
|
||||
|
||||
fancyGradle {
|
||||
patches {
|
||||
resources
|
||||
coremods
|
||||
asm
|
||||
}
|
||||
}
|
||||
|
||||
+15
-1
@@ -1,8 +1,22 @@
|
||||
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
|
||||
# This is required to provide enough memory for the Minecraft decompilation process.
|
||||
org.gradle.jvmargs=-Xmx3G
|
||||
mod_id=ebwizardry
|
||||
mc_version=1.12.2
|
||||
mc_version_short=1.12
|
||||
jei_version=4.15.0.291
|
||||
baubles_version=1.5.2
|
||||
antique_atlas_version=4.6.3
|
||||
antique_atlas_version=4.6.3
|
||||
forge_version=14.23.5.2860
|
||||
mappings_version=39
|
||||
mappings_channel=stable
|
||||
mappings_mc_version=1.12
|
||||
baubles_projectid=227083
|
||||
baubles_fileid=2518667
|
||||
jei_projectid=238222
|
||||
artemislib_projectid=313590
|
||||
artemislib_version=1.0.6
|
||||
artemislib_fileid=2741812
|
||||
antiqueatlas_projectid=227795
|
||||
antiqueatlas_fileid=2823030
|
||||
org.gradle.daemon=false
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+2
-3
@@ -1,6 +1,5 @@
|
||||
#Mon Sep 14 12:28:28 PDT 2015
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -1,164 +1,232 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
MAX_FD=maximum
|
||||
|
||||
warn ( ) {
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
} >&2
|
||||
|
||||
die ( ) {
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
locations of your Java installation."
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
locations of your Java installation."
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
Vendored
+29
-30
@@ -1,3 +1,19 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@@ -8,26 +24,29 @@
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo locations of your Java installation.
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
@@ -35,44 +54,24 @@ goto fail
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo locations of your Java installation.
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
@@ -87,4 +86,4 @@ exit /b 1
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
:omega
|
||||
@@ -156,6 +156,12 @@ public final class Settings {
|
||||
public Pair<ResourceLocation, Short>[] treeBlocks = parseItemMetaStrings(DEFAULT_TREE_BLOCKS);
|
||||
/** <b>[Server-only]</b> The chance for wizard towers to generate with an evil wizard and chest inside. */
|
||||
public double evilWizardChance = 0.2;
|
||||
public double cooldownReductionPerLevel = 0.15;
|
||||
public double potencyIncreasePerTier = 0.15;
|
||||
public double durationIncreasePerLevel = 0.25;
|
||||
public double rangeIncreasePerLevel = 0.25;
|
||||
public double blastIncreasePerLevel = 0.25;
|
||||
public double frostSlownessIncreasePerLevel = 0.5;
|
||||
/** <b>[Server-only]</b> List of dimension ids in which to generate crystal ore. */
|
||||
public int[] oreDimensions = {0};
|
||||
/** <b>[Server-only]</b> List of dimension ids in which to generate crystal flowers. */
|
||||
@@ -192,12 +198,23 @@ public final class Settings {
|
||||
public boolean playerBlockDamage = true;
|
||||
/** <b>[Server-only]</b> Whether spells cast by dispensers can destroy blocks in the world. */
|
||||
public boolean dispenserBlockDamage = true;
|
||||
/** <b>[Server-only]</b> Whether damage should be registered with the old system (wizardry_magic/indirect_wizardry_magic) prefixed damage with the elements like
|
||||
* necromancy_indirect_wizardry_magic, necromancy_wizardry_magic*/
|
||||
public boolean damageTypePerElement = false;
|
||||
/** <b>[Server-only]</b> Whether spell books are consumed when they are bound to a wand.*/
|
||||
public boolean singleUseSpellBooks = false;
|
||||
/** <b>[Server-only]</b> Whether to prevent binding the same spell to a wand multiple times*/
|
||||
public boolean preventBindingSameSpellTwiceToWands = false;
|
||||
/** <b>[Server-only]</b> Whether to revert to the old wand upgrade system, which only requires tomes of arcana. */
|
||||
public boolean legacyWandLevelling = false;
|
||||
/** <b>[Server-only]</b> Whether to tweak the blindness effect to reduce follow distance when used on non-players. */
|
||||
public boolean blindnessTweak = true;
|
||||
/** <b>[Server-only]</b> Whether using bonemeal on grass blocks has a chance to grow crystal flowers. */
|
||||
public boolean bonemealGrowsCrystalFlowers = true;
|
||||
/** <b>[Server-only]</b> Whether wands only decrement their cooldowns if a player holds them. */
|
||||
public boolean wandsMustBeHeldToDecrementCooldown = false;
|
||||
/** <b>[Server-only]</b> Whether to enable Wizardry mob loot injection. Allows an easier switch instead of blacklisting all entities. */
|
||||
public boolean injectMobDrops = true;
|
||||
/**
|
||||
* <b>[Server-only]</b> List of registry names of entities which summoned creatures are allowed to attack, in addition
|
||||
* to the defaults.
|
||||
@@ -377,6 +394,9 @@ public final class Settings {
|
||||
public boolean showSpellHUD = true;
|
||||
/** <b>[Client-only]</b> Whether to show the charge meter when charging up a spell. */
|
||||
public boolean showChargeMeter = true;
|
||||
/** <b>[Client-only]</b> Whether to initialise the handbook's data. Setting this to false will break the in-game handbook, but might help with some
|
||||
* startup crashes */
|
||||
public boolean loadHandbook = true;
|
||||
/** <b>[Client-only]</b> The position of the spell HUD. */
|
||||
public GuiPosition spellHUDPosition = GuiPosition.BOTTOM_LEFT;
|
||||
|
||||
@@ -612,6 +632,29 @@ public final class Settings {
|
||||
dispenserBlockDamage = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "damageTypePerElement", false,
|
||||
"Whether damage should be registered with the old system (wizardry_magic/indirect_wizardry_magic) prefixed damage with the elements like "
|
||||
+ "necromancy_indirect_wizardry_magic, necromancy_wizardry_magic. This is disabled by default to not break existing modpacks."
|
||||
+ "The intention of this setting is to allow differentiating various damage types for e.g. the Distinct Damage Descriptions mod");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".damage_type_per_element");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
damageTypePerElement = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "singleUseSpellBooks", false,
|
||||
"Whether spell books are consumed when they are bound to a wand.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".single_use_spell_books");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
singleUseSpellBooks = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "preventBindingSameSpellTwiceToWands", false,
|
||||
"Whether to prevent binding the same spell to a wand multiple times");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".prevent_binding_same_spell_twice_to_wands");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
preventBindingSameSpellTwiceToWands = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "playersMoveEachOther", true,
|
||||
"Whether to allow players to move other players around using magic.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".players_move_each_other");
|
||||
@@ -663,6 +706,13 @@ public final class Settings {
|
||||
bonemealGrowsCrystalFlowers = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(GAMEPLAY_CATEGORY, "wandsMustBeHeldToDecrementCooldown", false,
|
||||
"Whether wands only decrement their cooldowns if a player holds them.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".wands_must_be_held_to_decrement_cooldown");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
wandsMustBeHeldToDecrementCooldown = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
checkForRedundantOptions(GAMEPLAY_CATEGORY, propOrder); // Must be before the order is set!
|
||||
config.setCategoryPropertyOrder(GAMEPLAY_CATEGORY, propOrder);
|
||||
|
||||
@@ -807,6 +857,13 @@ public final class Settings {
|
||||
blindnessTweak = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "injectMobDrops", true,
|
||||
"Whether to inject Wizardry loot to mobs, based on the loot table 'Mob Loot Table Whitelist' / 'Mob Loot Table Blacklist' settings. If disabled, the lists won't have any effect!");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".inject_mob_drops");
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
injectMobDrops = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "mobLootTableWhitelist", new String[0], "Whitelist for loot tables to inject additional mob drops (as specified in loot_tables/entities/mob_additions.json) into. Wizardry makes a best guess as to which loot tables belong to hostile mobs, but this may not always be correct or appropriate; add loot table locations (not entity IDs) to this list to manually include them.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".mob_loot_table_whitelist");
|
||||
property.setRequiresMcRestart(true);
|
||||
@@ -914,6 +971,50 @@ public final class Settings {
|
||||
}
|
||||
}
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "cooldown_reduction_per_level", 0.15,
|
||||
"The fraction by which cooldowns are reduced for each level of cooldown upgrade.",
|
||||
0.05, Integer.MAX_VALUE); // Sure, I mean you COULD set it to 2^31-1... what could possibly go wrong?
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".cast_command_multiplier_limit");
|
||||
cooldownReductionPerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "potency_increase_per_tier", 0.15,
|
||||
"The fraction by which potency is increased for each tier of matching wand. May cause extreme lag with high values!",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".potency_increase_per_tier");
|
||||
potencyIncreasePerTier = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "duration_increase_per_level", 0.25,
|
||||
"The fraction by which spell duration is increased for each level of duration upgrade.",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".duration_increase_per_level");
|
||||
durationIncreasePerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "range_increase_per_level", 0.25,
|
||||
"The fraction by which spell range is increased for each level of range upgrade. May cause extreme lag with high values!",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".range_increase_per_level");
|
||||
rangeIncreasePerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "blast_increase_per_level", 0.25,
|
||||
"The fraction by which spell blast is increased for each level of blast upgrade. May cause extreme lag with high values!",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".blast_increase_per_level");
|
||||
blastIncreasePerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
|
||||
property = config.get(TWEAKS_CATEGORY, "frost_slowness_increase_per_level", 0.5,
|
||||
"The fraction by which movement speed is reduced per level of frost effect.",
|
||||
0.05, Integer.MAX_VALUE);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".frost_slowness_increase_per_level");
|
||||
frostSlownessIncreasePerLevel = property.getDouble();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
|
||||
checkForRedundantOptions(TWEAKS_CATEGORY, propOrder); // Must be before the order is set!
|
||||
config.setCategoryPropertyOrder(TWEAKS_CATEGORY, propOrder);
|
||||
|
||||
@@ -1103,6 +1204,13 @@ public final class Settings {
|
||||
showChargeMeter = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(CLIENT_CATEGORY, "loadHandbook", true, "Whether to initialise the in-game handbook. Setting this to false will brick the in-game handbook, but it might help if you have startup crashes.");
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".load_handbook");
|
||||
property.setRequiresWorldRestart(false);
|
||||
Wizardry.proxy.setToNamedBooleanEntry(property);
|
||||
loadHandbook = property.getBoolean();
|
||||
propOrder.add(property.getName());
|
||||
|
||||
property = config.get(CLIENT_CATEGORY, "spellHUDPosition", GuiPosition.BOTTOM_LEFT.name, "The position of the spell HUD.", GuiPosition.names);
|
||||
property.setLanguageKey("config." + Wizardry.MODID + ".spell_hud_position");
|
||||
spellHUDPosition = GuiPosition.fromName(property.getString());
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package electroblob.wizardry;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import electroblob.wizardry.block.BlockBookshelf;
|
||||
import electroblob.wizardry.command.CommandCastSpell;
|
||||
import electroblob.wizardry.command.CommandDiscoverSpell;
|
||||
@@ -16,11 +13,23 @@ import electroblob.wizardry.inventory.ContainerBookshelf;
|
||||
import electroblob.wizardry.misc.DonationPerksHandler;
|
||||
import electroblob.wizardry.misc.Forfeit;
|
||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import electroblob.wizardry.registry.*;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.registry.WizardryAdvancementTriggers;
|
||||
import electroblob.wizardry.registry.WizardryBlocks;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.registry.WizardryLoot;
|
||||
import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.SpellNetworkIDSorter;
|
||||
import electroblob.wizardry.util.SpellProperties;
|
||||
import electroblob.wizardry.util.WandHelper;
|
||||
import electroblob.wizardry.worldgen.*;
|
||||
import electroblob.wizardry.worldgen.WorldGenCrystalFlower;
|
||||
import electroblob.wizardry.worldgen.WorldGenCrystalOre;
|
||||
import electroblob.wizardry.worldgen.WorldGenLibraryRuins;
|
||||
import electroblob.wizardry.worldgen.WorldGenObelisk;
|
||||
import electroblob.wizardry.worldgen.WorldGenShrine;
|
||||
import electroblob.wizardry.worldgen.WorldGenUndergroundLibraryRuins;
|
||||
import electroblob.wizardry.worldgen.WorldGenWizardTower;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
@@ -39,8 +48,6 @@ import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
@@ -56,6 +63,7 @@ import java.util.Calendar;
|
||||
|
||||
@Mod(modid = Wizardry.MODID, name = Wizardry.NAME, version = Wizardry.VERSION, acceptedMinecraftVersions = "[1.12.2]",
|
||||
guiFactory = "electroblob.wizardry.WizardryGuiFactory",
|
||||
updateJSON = Wizardry.updateJSON,
|
||||
dependencies = "required-after:forge@[14.23.5.2847,);after:jei@[4.15.0,);after:baubles@[1.5.2,);after:antiqueatlas@[4.6,)")
|
||||
|
||||
public class Wizardry {
|
||||
@@ -74,7 +82,13 @@ public class Wizardry {
|
||||
* 1.x.x represents Minecraft 1.7.x versions, 2.x.x represents Minecraft 1.10.x versions, 3.x.x represents Minecraft
|
||||
* 1.11.x versions, and so on.
|
||||
*/
|
||||
public static final String VERSION = "4.3.4";
|
||||
public static final String VERSION = "4.3.12";
|
||||
|
||||
/**
|
||||
* Json file used by Forge's built-in <a href="https://mcforge.readthedocs.io/en/1.12.x/gettingstarted/autoupdate/">update checker</a>.
|
||||
* Used by the in-game mod menu to show that green icon whenever a newer version is available of the mod.
|
||||
*/
|
||||
public static final String updateJSON = "https://github.com/Electroblob77/Wizardry/blob/1.12.2/.forge/update.json";
|
||||
|
||||
// IDEA: Triggering of inbuilt Forge events in relevant places?
|
||||
// IDEA: Abstract the vanilla particles behind the particle builder
|
||||
@@ -113,8 +127,6 @@ public class Wizardry {
|
||||
public void preInit(FMLPreInitializationEvent event){
|
||||
|
||||
logger = event.getModLog();
|
||||
|
||||
proxy.registerResourceReloadListeners();
|
||||
|
||||
configDirectory = new File(event.getModConfigurationDirectory(), Wizardry.MODID);
|
||||
settings.initConfig(event);
|
||||
@@ -148,6 +160,7 @@ public class Wizardry {
|
||||
|
||||
@EventHandler
|
||||
public void init(FMLInitializationEvent event){
|
||||
proxy.registerResourceReloadListeners();
|
||||
|
||||
settings.initConfigExtras();
|
||||
|
||||
@@ -189,6 +202,8 @@ public class Wizardry {
|
||||
public void postInit(FMLPostInitializationEvent event){
|
||||
proxy.initialiseLayers();
|
||||
proxy.initialiseAnimations();
|
||||
|
||||
SpellNetworkIDSorter.init();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
||||
@@ -203,7 +203,6 @@ public final class WizardryEventHandler {
|
||||
// Find the angle between the direction the mob is looking and the direction the player is in
|
||||
// Angle between a and b = acos((a.b) / (|a|*|b|))
|
||||
double angle = Math.acos(vec.dotProduct(event.getEntity().getLookVec()) / vec.length());
|
||||
System.out.println(angle);
|
||||
// If the player is not within the 144-degree arc in front of the mob, it won't detect them
|
||||
if(angle > 0.4 * Math.PI){
|
||||
((EntityLiving)event.getEntityLiving()).setAttackTarget(null);
|
||||
@@ -269,7 +268,7 @@ public final class WizardryEventHandler {
|
||||
// Fireskin
|
||||
if(event.getEntityLiving().isPotionActive(WizardryPotions.fireskin)
|
||||
&& !MagicDamage.isEntityImmune(DamageType.FIRE, event.getEntityLiving()))
|
||||
attacker.setFire(Spells.fire_breath.getProperty(Spell.BURN_DURATION).intValue());
|
||||
attacker.setFire(Spells.fire_breath.getProperty(Spell.BURN_DURATION).intValue() * 20);
|
||||
|
||||
// Ice Shroud
|
||||
if(event.getEntityLiving().isPotionActive(WizardryPotions.ice_shroud)
|
||||
@@ -307,7 +306,7 @@ public final class WizardryEventHandler {
|
||||
PotionEffect effect = event.getEntityLiving().getActivePotionEffect(WizardryPotions.ward);
|
||||
|
||||
if(effect != null && event.getSource().isMagicDamage()){
|
||||
event.setAmount(event.getAmount() * Math.max(0, 1 - 0.4f * effect.getAmplifier())); // Resistance is 20%
|
||||
event.setAmount(event.getAmount() * Math.max(0, 1 - 0.2f * (1 + effect.getAmplifier()))); // Resistance is 20%
|
||||
}
|
||||
|
||||
// Flaming and freezing swords
|
||||
@@ -491,4 +490,4 @@ public final class WizardryEventHandler {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package electroblob.wizardry.client;
|
||||
|
||||
import electroblob.wizardry.CommonProxy;
|
||||
import electroblob.wizardry.Settings;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.block.BlockBookshelf;
|
||||
import electroblob.wizardry.client.animation.ActionAnimation;
|
||||
@@ -19,6 +20,7 @@ import electroblob.wizardry.client.model.ModelSageArmour;
|
||||
import electroblob.wizardry.client.model.ModelWizardArmour;
|
||||
import electroblob.wizardry.client.particle.*;
|
||||
import electroblob.wizardry.client.particle.ParticleWizardry.IWizardryParticleFactory;
|
||||
import electroblob.wizardry.client.renderer.RenderSpectralGolem;
|
||||
import electroblob.wizardry.client.renderer.entity.*;
|
||||
import electroblob.wizardry.client.renderer.entity.layers.*;
|
||||
import electroblob.wizardry.client.renderer.overlay.RenderBlinkEffect;
|
||||
@@ -164,7 +166,8 @@ public class ClientProxy extends CommonProxy {
|
||||
IResourceManager manager = Minecraft.getMinecraft().getResourceManager();
|
||||
if(manager instanceof IReloadableResourceManager){
|
||||
((IReloadableResourceManager)manager).registerReloadListener(GuiSpellDisplay::loadSkins);
|
||||
((IReloadableResourceManager)manager).registerReloadListener(GuiWizardHandbook::loadHandbookFile);
|
||||
if (Wizardry.settings.loadHandbook)
|
||||
((IReloadableResourceManager)manager).registerReloadListener(GuiWizardHandbook::loadHandbookFile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -728,6 +731,9 @@ public class ClientProxy extends CommonProxy {
|
||||
LayerTiledOverlay.initialiseLayers(LayerMindControl::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerSummonAnimation::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerDisintegrateAnimation::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerOak::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerIron::new);
|
||||
LayerTiledOverlay.initialiseLayers(LayerDiamond::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -766,6 +772,7 @@ public class ClientProxy extends CommonProxy {
|
||||
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityIceGiant.class, RenderIceGiant::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityPhoenix.class, RenderPhoenix::new);
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntitySpectralGolem.class, RenderSpectralGolem::new);
|
||||
|
||||
// Projectiles
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityMagicMissile.class, manager -> new RenderMagicArrow(manager,
|
||||
@@ -780,6 +787,7 @@ public class ClientProxy extends CommonProxy {
|
||||
new ResourceLocation(Wizardry.MODID, "textures/entity/ice_lance.png"), false, 16.0, 3.0, 22, 5, false));
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityFlamecatcherArrow.class, manager -> new RenderMagicArrow(manager,
|
||||
new ResourceLocation(Wizardry.MODID, "textures/entity/flamecatcher_arrow.png"), false, 8, 2.0, 16, 5, true));
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityConjuredArrow.class, RenderConjuredArrow::new);
|
||||
|
||||
RenderingRegistry.registerEntityRenderingHandler(EntityForceArrow.class, RenderForceArrow::new);
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
private ContainerArcaneWorkbench arcaneWorkbenchContainer;
|
||||
|
||||
private GuiButton applyBtn;
|
||||
private GuiButton clearBtn;
|
||||
private GuiButton[] sortButtons = new GuiButton[3];
|
||||
|
||||
private GuiTextField searchField;
|
||||
@@ -126,6 +127,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
|
||||
this.buttonList.clear();
|
||||
this.buttonList.add(this.applyBtn = new GuiButtonApply(0, this.width / 2 + 64, this.height / 2 + 3));
|
||||
this.buttonList.add(this.clearBtn = new GuiButtonClear(0, this.width / 2 + 64, this.height / 2 - 16));
|
||||
this.buttonList.add(sortButtons[0] = new GuiButtonSpellSort(1, this.guiLeft - 44, this.guiTop + 8, ISpellSortable.SortType.TIER, arcaneWorkbenchContainer, this));
|
||||
this.buttonList.add(sortButtons[1] = new GuiButtonSpellSort(2, this.guiLeft - 31, this.guiTop + 8, ISpellSortable.SortType.ELEMENT, arcaneWorkbenchContainer, this));
|
||||
this.buttonList.add(sortButtons[2] = new GuiButtonSpellSort(3, this.guiLeft - 18, this.guiTop + 8, ISpellSortable.SortType.ALPHABETICAL, arcaneWorkbenchContainer, this));
|
||||
@@ -205,6 +207,7 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
|
||||
// Show/hide the relevant gui elements
|
||||
this.applyBtn.enabled = centreSlot.getHasStack();
|
||||
this.clearBtn.enabled = centreSlot.getHasStack() && centreSlot.getStack().getItem() instanceof IWorkbenchItem && ((IWorkbenchItem) centreSlot.getStack().getItem()).isClearable();
|
||||
for(GuiButton button : this.sortButtons) button.visible = arcaneWorkbenchContainer.hasBookshelves();
|
||||
this.searchField.setVisible(arcaneWorkbenchContainer.hasBookshelves());
|
||||
|
||||
@@ -444,6 +447,17 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
animationTimer = 20;
|
||||
}
|
||||
|
||||
if(button == clearBtn){
|
||||
// Packet building
|
||||
IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.CLEAR_BUTTON);
|
||||
WizardryPacketHandler.net.sendToServer(msg);
|
||||
// Sound
|
||||
Minecraft.getMinecraft().getSoundHandler().playSound(PositionedSoundRecord.getMasterRecord(
|
||||
WizardrySounds.BLOCK_ARCANE_WORKBENCH_SPELLBIND, 0.8f));
|
||||
// Animation
|
||||
animationTimer = 20;
|
||||
}
|
||||
|
||||
if(button instanceof GuiButtonSpellSort) this.arcaneWorkbenchContainer.setSortType(((GuiButtonSpellSort)button).sortType);
|
||||
}
|
||||
}
|
||||
@@ -1006,4 +1020,36 @@ public class GuiArcaneWorkbench extends GuiContainer {
|
||||
}
|
||||
}
|
||||
|
||||
private static class GuiButtonClear extends GuiButton {
|
||||
|
||||
public GuiButtonClear(int id, int x, int y){
|
||||
super(id, x, y, 16, 16, I18n.format("container." + Wizardry.MODID + ":arcane_workbench.clear"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
|
||||
|
||||
// Whether the button is highlighted
|
||||
this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
|
||||
|
||||
int k = 72;
|
||||
int l = 236;
|
||||
//int colour = 14737632;
|
||||
|
||||
if(this.enabled){
|
||||
if(this.hovered){
|
||||
k += this.width * 2;
|
||||
//colour = 16777120;
|
||||
}
|
||||
}else{
|
||||
k += this.width;
|
||||
//colour = 10526880;
|
||||
}
|
||||
|
||||
DrawingUtils.drawTexturedRect(this.x, this.y, k, l, this.width, this.height, TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
||||
//this.drawCenteredString(minecraft.fontRenderer, this.displayString, this.x + this.width / 2,
|
||||
// this.y + (this.height - 8) / 2, colour);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -151,7 +151,7 @@ class Contents {
|
||||
int x = GuiWizardHandbook.isRightPage(startPage) ? left + GuiWizardHandbook.GUI_WIDTH - GuiWizardHandbook.TEXT_INSET_X - GuiWizardHandbook.PAGE_WIDTH : left + GuiWizardHandbook.TEXT_INSET_X;
|
||||
int y = top + GuiWizardHandbook.TEXT_INSET_Y + startLine * font.FONT_HEIGHT;
|
||||
|
||||
list.add(new GuiButtonHyperlink.Internal(0, x, y, font, entry.title, entry, 0, "", maxLineNumber-startLine, GuiWizardHandbook.isRightPage(startPage)));
|
||||
list.add(new GuiButtonHyperlink.Internal(0, x, y, font, entry.title, entry, 0, "", maxLineNumber-startLine, GuiWizardHandbook.isRightPage(startPage), false));
|
||||
|
||||
startLine++;
|
||||
|
||||
|
||||
@@ -28,15 +28,17 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
final List<String> lines;
|
||||
final int linesLeft;
|
||||
|
||||
GuiButtonHyperlink(int id, int x, int y, FontRenderer font, String text, int indent, String suffix, int linesLeft, boolean rightPage){
|
||||
GuiButtonHyperlink(int id, int x, int y, FontRenderer font, String text, int indent, String suffix, int linesLeft, boolean rightPage, boolean spaceless){
|
||||
|
||||
super(id, x, y, font.getStringWidth(text), font.FONT_HEIGHT, text);
|
||||
|
||||
// Sometimes a link has punctuation or something after it that causes it to wrap onto a new line
|
||||
String linkWithSuffix = text + suffix;
|
||||
|
||||
// If the string won't fit any words at the end of the current line, treat it as if we started a new line
|
||||
if(font.getStringWidth(linkWithSuffix.split("\\s")[0]) > GuiWizardHandbook.PAGE_WIDTH - indent){
|
||||
// If the string won't fit any words (or characters in a spaceless language) at the end of the current line,
|
||||
// treat it as if we started a new line
|
||||
String firstWord = spaceless ? linkWithSuffix.substring(0, 1) : linkWithSuffix.split("\\s")[0];
|
||||
if(font.getStringWidth(firstWord) > GuiWizardHandbook.PAGE_WIDTH - indent){
|
||||
indent = 0;
|
||||
this.y += font.FONT_HEIGHT;
|
||||
}
|
||||
@@ -149,7 +151,7 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
* @throws IllegalArgumentException if the given argument array is empty or contains more than 2 arguments
|
||||
* @throws JsonSyntaxException if the specified link target is not a URL or a valid section ID
|
||||
*/
|
||||
public static GuiButtonHyperlink create(int x, int y, FontRenderer font, List<String> upToLink, String[] arguments, String suffix, int linesLeft, boolean rightPage){
|
||||
public static GuiButtonHyperlink create(int x, int y, FontRenderer font, List<String> upToLink, String[] arguments, String suffix, int linesLeft, boolean rightPage, boolean spaceless){
|
||||
|
||||
if(arguments.length == 0 || arguments.length > 2) throw new IllegalArgumentException("Incorrect array length!");
|
||||
|
||||
@@ -158,7 +160,7 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
if(arguments[0].matches(URL_REGEX)){
|
||||
|
||||
button = new GuiButtonHyperlink.External(0, x, y, font, arguments[arguments.length - 1], arguments[0],
|
||||
font.getStringWidth(upToLink.get(upToLink.size() - 1)), suffix, linesLeft, rightPage);
|
||||
font.getStringWidth(upToLink.get(upToLink.size() - 1)), suffix, linesLeft, rightPage, spaceless);
|
||||
|
||||
}else{
|
||||
|
||||
@@ -167,7 +169,7 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
if(target == null) throw new JsonSyntaxException("Hyperlink points to nonexistent section id " + arguments[0]);
|
||||
|
||||
button = new GuiButtonHyperlink.Internal(0, x, y, font, arguments[arguments.length - 1],
|
||||
target, font.getStringWidth(upToLink.get(upToLink.size() - 1)), suffix, linesLeft, rightPage);
|
||||
target, font.getStringWidth(upToLink.get(upToLink.size() - 1)), suffix, linesLeft, rightPage, spaceless);
|
||||
}
|
||||
|
||||
return button;
|
||||
@@ -177,8 +179,8 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
|
||||
final Section target;
|
||||
|
||||
Internal(int id, int x, int y, FontRenderer font, String text, Section target, int indent, String suffix, int linesLeft, boolean rightPage){
|
||||
super(id, x, y, font, text, indent, suffix, linesLeft, rightPage);
|
||||
Internal(int id, int x, int y, FontRenderer font, String text, Section target, int indent, String suffix, int linesLeft, boolean rightPage, boolean spaceless){
|
||||
super(id, x, y, font, text, indent, suffix, linesLeft, rightPage, spaceless);
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@@ -216,8 +218,8 @@ public abstract class GuiButtonHyperlink extends GuiButton {
|
||||
|
||||
final ITextComponent link;
|
||||
|
||||
External(int id, int x, int y, FontRenderer font, String text, String url, int indent, String suffix, int linesLeft, boolean rightPage){
|
||||
super(id, x, y, font, text, indent, suffix, linesLeft, rightPage);
|
||||
External(int id, int x, int y, FontRenderer font, String text, String url, int indent, String suffix, int linesLeft, boolean rightPage, boolean spaceless){
|
||||
super(id, x, y, font, text, indent, suffix, linesLeft, rightPage, spaceless);
|
||||
this.link = new TextComponentString(text);
|
||||
link.getStyle().setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, url)).setColor(TextFormatting.DARK_BLUE);
|
||||
}
|
||||
|
||||
@@ -33,9 +33,13 @@ import java.awt.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* GUI class for the wizard's handbook. Like any GUI class, this is instantiated each time the book is opened. As of
|
||||
@@ -55,6 +59,8 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
|
||||
private static final ResourceLocation DEFAULT = new ResourceLocation(Wizardry.MODID, "texts/handbook_en_us.json");
|
||||
|
||||
private static List<String> ADDONS = new ArrayList<>();
|
||||
|
||||
static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/gui/handbook/handbook.png");
|
||||
|
||||
/** Global Gson instance for the handbook. */
|
||||
@@ -406,9 +412,10 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
return;
|
||||
}
|
||||
|
||||
IResource handbookFile = getHandbookResource(manager);
|
||||
// IResource handbookFile = getHandbookResource(manager);
|
||||
List<IResource> handbookFiles = getHandbookResource(manager);
|
||||
|
||||
if(handbookFile != null){
|
||||
if(!handbookFiles.isEmpty()){
|
||||
|
||||
// Wipes all the maps before repopulating them
|
||||
images.clear();
|
||||
@@ -418,28 +425,31 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
|
||||
bookmarkSection = null; // Also need to wipe the reference to the old bookmarked section
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(handbookFile.getInputStream(), StandardCharsets.UTF_8));
|
||||
for (IResource handbookFile : handbookFiles) {
|
||||
|
||||
JsonElement je = gson.fromJson(reader, JsonElement.class);
|
||||
JsonObject json = je.getAsJsonObject();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(handbookFile.getInputStream(), StandardCharsets.UTF_8));
|
||||
|
||||
JsonUtils.getJsonObject(json, "colours").entrySet().forEach(e -> colours.put(e.getKey(),
|
||||
Color.decode(e.getValue().getAsString()).getRGB()));
|
||||
JsonElement je = gson.fromJson(reader, JsonElement.class);
|
||||
JsonObject json = je.getAsJsonObject();
|
||||
|
||||
// Repopulates the remaining maps
|
||||
Image.populate(images, json);
|
||||
CraftingRecipe.populate(recipes, json);
|
||||
Section.populate(sections, json);
|
||||
JsonUtils.getJsonObject(json, "colours").entrySet().forEach(e -> colours.put(e.getKey(),
|
||||
Color.decode(e.getValue().getAsString()).getRGB()));
|
||||
|
||||
sectionList = Collections.unmodifiableList(new ArrayList<>(sections.values()));
|
||||
// Repopulates the remaining maps
|
||||
Image.populate(images, json);
|
||||
CraftingRecipe.populate(recipes, json);
|
||||
Section.populate(sections, json);
|
||||
|
||||
if(sections.isEmpty()){
|
||||
Wizardry.logger.warn("Handbook has no sections! Aborting loading...");
|
||||
return;
|
||||
sectionList = Collections.unmodifiableList(new ArrayList<>(sections.values()));
|
||||
|
||||
if(sections.isEmpty()){
|
||||
Wizardry.logger.warn("Handbook has no sections! Aborting loading...");
|
||||
return;
|
||||
}
|
||||
|
||||
bookmarkSection = JsonUtils.getString(json, "bookmark_start_section");
|
||||
if(!sections.containsKey(bookmarkSection)) throw new JsonSyntaxException("Section with id " + bookmarkSection + " is undefined");
|
||||
}
|
||||
|
||||
bookmarkSection = JsonUtils.getString(json, "bookmark_start_section");
|
||||
if(!sections.containsKey(bookmarkSection)) throw new JsonSyntaxException("Section with id " + bookmarkSection + " is undefined");
|
||||
}
|
||||
|
||||
// The first resource load on startup is done before the packet handler is loaded
|
||||
@@ -455,16 +465,17 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
* @param manager The resource manager instance to use.
|
||||
* @return The handbook JSON file, as an IResource, or null if it was not found.
|
||||
*/
|
||||
private static IResource getHandbookResource(IResourceManager manager){
|
||||
private static List<IResource> getHandbookResource(IResourceManager manager){
|
||||
|
||||
// TODO: Implement resource pack stacking to allow addon mods and texture packs to add/overwrite content
|
||||
|
||||
IResource handbookFile = null;
|
||||
List<IResource> handbookFiles = new ArrayList<>();
|
||||
|
||||
try{
|
||||
handbookFile = manager.getResource(new ResourceLocation(Wizardry.MODID, "texts/handbook_"
|
||||
+ Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage().getLanguageCode() + ".json"));
|
||||
}catch(IOException e){
|
||||
}catch(Exception e){
|
||||
|
||||
Wizardry.logger.info("Wizard handbook JSON file missing for the current language (" + Minecraft.getMinecraft()
|
||||
.getLanguageManager().getCurrentLanguage() + "). Using default (English-US) instead.");
|
||||
@@ -476,7 +487,29 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
}
|
||||
}
|
||||
|
||||
return handbookFile;
|
||||
handbookFiles.add(handbookFile);
|
||||
|
||||
for (String modid : ADDONS) {
|
||||
// Addons
|
||||
Wizardry.logger.info("Registering addon Wizard's Handbook contents for " + modid);
|
||||
try{
|
||||
handbookFile = manager.getResource(new ResourceLocation(modid, "texts/handbook_"
|
||||
+ Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage().getLanguageCode() + ".json"));
|
||||
}catch(Exception e){
|
||||
|
||||
Wizardry.logger.info("Wizard handbook JSON file missing for the current language (" + Minecraft.getMinecraft()
|
||||
.getLanguageManager().getCurrentLanguage() + "). Using default (English-US) instead.");
|
||||
|
||||
try{
|
||||
handbookFile = manager.getResource(new ResourceLocation(modid, "texts/handbook_en_us.json"));
|
||||
}catch(IOException x){
|
||||
Wizardry.logger.error("Couldn't find file: " + DEFAULT + ". The file may be missing; please try re-downloading and reinstalling Wizardry.", x);
|
||||
}
|
||||
}
|
||||
handbookFiles.add(handbookFile);
|
||||
}
|
||||
|
||||
return handbookFiles;
|
||||
}
|
||||
|
||||
// Controls
|
||||
@@ -496,24 +529,30 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
|
||||
Section currentSection = null;
|
||||
|
||||
for(Section section : sections.values()){
|
||||
// We always want this button to do something, and taking the right-hand page means it always does
|
||||
if(section.containsPage(doubleToSinglePage(currentPage, true))){
|
||||
currentSection = section;
|
||||
break;
|
||||
if(currentPage < singleToDoublePage(pageCount)){
|
||||
// Find current section
|
||||
for(Section section : sections.values()){
|
||||
// Take the right-hand page if going to the next section, and the left-hand page otherwise
|
||||
if(section.containsPage(doubleToSinglePage(currentPage, button == nextSection))){
|
||||
currentSection = section;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(currentSection != null){
|
||||
List<Section> visibleSections = new ArrayList<>(sectionList);
|
||||
visibleSections.removeIf(s -> !s.isUnlocked());
|
||||
|
||||
List<Section> visibleSections = new ArrayList<>(sectionList);
|
||||
visibleSections.removeIf(s -> !s.isUnlocked());
|
||||
int index = currentSection == null ? visibleSections.size() : visibleSections.indexOf(currentSection);
|
||||
|
||||
int index = visibleSections.indexOf(currentSection);
|
||||
|
||||
if(button == nextSection && index + 1 < visibleSections.size()){
|
||||
if(button == nextSection){
|
||||
if(index + 1 < visibleSections.size()){
|
||||
currentPage = singleToDoublePage(visibleSections.get(index + 1).startPage);
|
||||
}else if(index > 0){
|
||||
}else{
|
||||
currentPage = singleToDoublePage(pageCount);
|
||||
}
|
||||
}else{
|
||||
if(index > 0){
|
||||
currentPage = singleToDoublePage(visibleSections.get(index - 1).startPage);
|
||||
}
|
||||
}
|
||||
@@ -570,4 +609,9 @@ public class GuiWizardHandbook extends GuiScreen {
|
||||
sections.values().forEach(s -> s.updateUnlockStatus(showToasts, completedAdvancements));
|
||||
}
|
||||
|
||||
public static void registerAddonHandbookContent(String modid) {
|
||||
if (!ADDONS.contains(modid)) {
|
||||
ADDONS.add(modid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package electroblob.wizardry.client.gui.handbook;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
@@ -35,6 +36,8 @@ import java.util.*;
|
||||
// be a non-static inner class
|
||||
class Section {
|
||||
|
||||
private static final Set<String> SPACELESS_LANGUAGES = ImmutableSet.of("zh_cn", "zh_tw");
|
||||
|
||||
// Final fields are mandatory (none here though), the rest are optional
|
||||
String title;
|
||||
private String[] rawText;
|
||||
@@ -293,7 +296,11 @@ class Section {
|
||||
|
||||
String linkRaw = paragraph.substring(linkStart, linkEnd + 1);
|
||||
String[] arguments = paragraph.substring(linkStart + 1, linkEnd).split("\\s", 2);
|
||||
String suffix = paragraph.substring(linkEnd).split("\\s", 2)[0].substring(1); // substring(1) to remove the @
|
||||
String suffix = "";
|
||||
|
||||
// Account for trailing punctuation, except in languages that don't use spaces such as Chinese
|
||||
boolean spaceless = SPACELESS_LANGUAGES.contains(Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage() == null ? "en_us" : Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage().getLanguageCode());
|
||||
if(!spaceless) paragraph.substring(linkEnd).split("\\s", 2)[0].substring(1); // substring(1) to remove the @
|
||||
|
||||
// The index of the single page currently being formatted, relative to the section
|
||||
int pageRelative = (lines.size() + upToLink.size() - 1) / maxLineNumber;
|
||||
@@ -311,7 +318,7 @@ class Section {
|
||||
}
|
||||
|
||||
// The button id only does what you use it for, so we're just not using it at all.
|
||||
this.buttons.get(pageRelative).add(GuiButtonHyperlink.create(x, y, font, upToLink, arguments, suffix, maxLineNumber - lineNumber - 1, GuiWizardHandbook.isRightPage(page)));
|
||||
this.buttons.get(pageRelative).add(GuiButtonHyperlink.create(x, y, font, upToLink, arguments, suffix, maxLineNumber - lineNumber - 1, GuiWizardHandbook.isRightPage(page), spaceless));
|
||||
|
||||
// The link button should exactly overlay the display text in the main string
|
||||
// If the link has no display text specified, it displays the unformatted target string
|
||||
|
||||
@@ -13,17 +13,17 @@ import net.minecraftforge.client.model.IModel;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ModelBookshelf implements IModel {
|
||||
|
||||
private static final ResourceLocation DEFAULT_BOOK_TEXTURE = new ResourceLocation(Wizardry.MODID, "blocks/books");
|
||||
//private static final ResourceLocation DEFAULT_BOOK_TEXTURE = new ResourceLocation(Wizardry.MODID, "blocks/books");
|
||||
|
||||
private static final List<ResourceLocation> bookModelLocations = new ArrayList<>();
|
||||
|
||||
private static final Map<String, IBakedModel[][]> bakedBookModels = new HashMap<>();
|
||||
|
||||
private final ModelResourceLocation bookshelfModelLocation;
|
||||
private final String variant;
|
||||
|
||||
@@ -49,19 +49,7 @@ public class ModelBookshelf implements IModel {
|
||||
// I don't know why default state works here (surely it ought to be the state param?), but it works so who cares
|
||||
IBakedModel bookshelf = bookshelfModel.bake(bookshelfModel.getDefaultState(), format, bakedTextureGetter);
|
||||
|
||||
ImmutableList<ResourceLocation> textures = BlockBookshelf.getBookTextures();
|
||||
|
||||
IBakedModel[][] books = new IBakedModel[textures.size()][BlockBookshelf.SLOT_COUNT];
|
||||
|
||||
for(int i = 0; i < textures.size(); i++){
|
||||
|
||||
ImmutableMap<String, String> retexturer = ImmutableMap.of("books", textures.get(i).toString());
|
||||
|
||||
for(int j = 0; j < BlockBookshelf.SLOT_COUNT; j++){
|
||||
IModel bookModel = ModelLoaderRegistry.getModel(new ModelResourceLocation(bookModelLocations.get(j), variant)).retexture(retexturer);
|
||||
books[i][j] = bookModel.bake(bookModel.getDefaultState(), format, bakedTextureGetter); // Same here!
|
||||
}
|
||||
}
|
||||
IBakedModel[][] books = getBakedBookModels(format, bakedTextureGetter);
|
||||
|
||||
// To clarify: the whole point of doing this was to avoid having to bake 4 * 2^12 models per bookshelf type
|
||||
// Therefore we have to have a baked bookshelf model that's kind of dynamic
|
||||
@@ -74,6 +62,29 @@ public class ModelBookshelf implements IModel {
|
||||
|
||||
}
|
||||
|
||||
/** Retrieves the baked book models, or bakes them if they haven't been created yet. */
|
||||
protected IBakedModel[][] getBakedBookModels(VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) throws Exception{
|
||||
|
||||
if(bakedBookModels.get(variant) == null){
|
||||
|
||||
ImmutableList<ResourceLocation> textures = BlockBookshelf.getBookTextures();
|
||||
|
||||
bakedBookModels.put(variant, new IBakedModel[textures.size()][BlockBookshelf.SLOT_COUNT]);
|
||||
|
||||
for(int i = 0; i < textures.size(); i++){
|
||||
|
||||
ImmutableMap<String, String> retexturer = ImmutableMap.of("books", textures.get(i).toString());
|
||||
|
||||
for(int j = 0; j < BlockBookshelf.SLOT_COUNT; j++){
|
||||
IModel bookModel = ModelLoaderRegistry.getModel(new ModelResourceLocation(bookModelLocations.get(j), variant)).retexture(retexturer);
|
||||
bakedBookModels.get(variant)[i][j] = bookModel.bake(bookModel.getDefaultState(), format, bakedTextureGetter); // Same here!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bakedBookModels.get(variant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getDependencies(){
|
||||
return bookModelLocations;
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package electroblob.wizardry.client.renderer;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import net.minecraft.client.model.ModelIronGolem;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.entity.RenderLiving;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.entity.monster.EntityIronGolem;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderSpectralGolem extends RenderLiving<EntityIronGolem>
|
||||
{
|
||||
private static final ResourceLocation SPECTRAL_GOLEM_TEXTURES = new ResourceLocation(Wizardry.MODID, "textures/entity/spectral_golem.png");
|
||||
|
||||
public RenderSpectralGolem(RenderManager renderManagerIn)
|
||||
{
|
||||
super(renderManagerIn, new ModelIronGolem(), 0.5F);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location of an entity's texture. Doesn't seem to be called unless you call Render.bindEntityTexture.
|
||||
*/
|
||||
protected ResourceLocation getEntityTexture(EntityIronGolem entity)
|
||||
{
|
||||
return SPECTRAL_GOLEM_TEXTURES;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void preRenderCallback(EntityIronGolem entity, float partialTickTime){
|
||||
super.preRenderCallback(entity, partialTickTime);
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GlStateManager.color(1, 1, 1, 0.7f);
|
||||
}
|
||||
|
||||
protected void applyRotations(EntityIronGolem entityLiving, float ageInTicks, float rotationYaw, float partialTicks)
|
||||
{
|
||||
super.applyRotations(entityLiving, ageInTicks, rotationYaw, partialTicks);
|
||||
|
||||
if ((double)entityLiving.limbSwingAmount >= 0.01D)
|
||||
{
|
||||
float f = 13.0F;
|
||||
float f1 = entityLiving.limbSwing - entityLiving.limbSwingAmount * (1.0F - partialTicks) + 6.0F;
|
||||
float f2 = (Math.abs(f1 % 13.0F - 6.5F) - 3.25F) / 3.25F;
|
||||
GlStateManager.rotate(6.5F * f2, 0.0F, 0.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package electroblob.wizardry.client.renderer.entity;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.entity.projectile.EntityConjuredArrow;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.entity.RenderArrow;
|
||||
import net.minecraft.client.renderer.entity.RenderManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class RenderConjuredArrow extends RenderArrow<EntityConjuredArrow> {
|
||||
|
||||
public static final ResourceLocation CONJURED_ARROW_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/conjured_arrow.png");
|
||||
|
||||
public RenderConjuredArrow(RenderManager manager) {
|
||||
super(manager);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceLocation getEntityTexture(EntityConjuredArrow entity) {
|
||||
return CONJURED_ARROW_TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRender(EntityConjuredArrow entity, double x, double y, double z, float entityYaw, float partialTicks) {
|
||||
GlStateManager.pushMatrix();
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
GlStateManager.color(1, 1, 1, 0.4f);
|
||||
super.doRender(entity, x, y, z, entityYaw, partialTicks);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package electroblob.wizardry.client.renderer.entity.layers;
|
||||
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.GlStateManager.DestFactor;
|
||||
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.entity.RenderLivingBase;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Layer used to render the diamondflesh texture on creatures with the diamondflesh effect.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.7
|
||||
*/
|
||||
public class LayerDiamond extends LayerTiledOverlay<EntityLivingBase> {
|
||||
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/blocks/diamond_block.png");
|
||||
|
||||
public LayerDiamond(RenderLivingBase<?> renderer){
|
||||
super(renderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender(EntityLivingBase entity, float partialTicks){
|
||||
return !entity.isInvisible() && entity.isPotionActive(WizardryPotions.diamondflesh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTexture(EntityLivingBase entity, float partialTicks){
|
||||
return TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
|
||||
float ageInTicks, float netHeadYaw, float headPitch, float scale){
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
int j = entity.getBrightnessForRender();
|
||||
int k = j % 65536;
|
||||
int l = j / 65536;
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) k, (float) l);
|
||||
|
||||
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
|
||||
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package electroblob.wizardry.client.renderer.entity.layers;
|
||||
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.GlStateManager.DestFactor;
|
||||
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.entity.RenderLivingBase;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Layer used to render the ironflesh texture on creatures with the ironflesh effect.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.7
|
||||
*/
|
||||
public class LayerIron extends LayerTiledOverlay<EntityLivingBase> {
|
||||
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/blocks/iron_block.png");
|
||||
|
||||
public LayerIron(RenderLivingBase<?> renderer){
|
||||
super(renderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender(EntityLivingBase entity, float partialTicks){
|
||||
return !entity.isInvisible() && entity.isPotionActive(WizardryPotions.ironflesh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTexture(EntityLivingBase entity, float partialTicks){
|
||||
return TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
|
||||
float ageInTicks, float netHeadYaw, float headPitch, float scale){
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
int j = entity.getBrightnessForRender();
|
||||
int k = j % 65536;
|
||||
int l = j / 65536;
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) k, (float) l);
|
||||
|
||||
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
|
||||
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package electroblob.wizardry.client.renderer.entity.layers;
|
||||
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.GlStateManager.DestFactor;
|
||||
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.entity.RenderLivingBase;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
/**
|
||||
* Layer used to render the oakflesh texture on creatures with the oakflesh effect.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.7
|
||||
*/
|
||||
public class LayerOak extends LayerTiledOverlay<EntityLivingBase> {
|
||||
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/blocks/log_oak.png");
|
||||
|
||||
public LayerOak(RenderLivingBase<?> renderer){
|
||||
super(renderer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRender(EntityLivingBase entity, float partialTicks){
|
||||
return !entity.isInvisible() && entity.isPotionActive(WizardryPotions.oakflesh);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTexture(EntityLivingBase entity, float partialTicks){
|
||||
return TEXTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
|
||||
float ageInTicks, float netHeadYaw, float headPitch, float scale){
|
||||
|
||||
GlStateManager.enableBlend();
|
||||
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
int j = entity.getBrightnessForRender();
|
||||
int k = j % 65536;
|
||||
int l = j / 65536;
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float) k, (float) l);
|
||||
|
||||
super.doRenderLayer(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
|
||||
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package electroblob.wizardry.constants;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.WizardryEventHandler;
|
||||
|
||||
/** Stores various global constants used in Wizardry. */
|
||||
@@ -17,17 +18,17 @@ public final class Constants {
|
||||
/** The bonus amount of wand upgrades that can be applied to a non-elemental wand. */
|
||||
public static final int NON_ELEMENTAL_UPGRADE_BONUS = 3;
|
||||
/** The fraction by which cooldowns are reduced for each level of cooldown upgrade. */
|
||||
public static final float COOLDOWN_REDUCTION_PER_LEVEL = 0.15f;
|
||||
public static float COOLDOWN_REDUCTION_PER_LEVEL = 0.15f;
|
||||
/** The fraction by which maximum charge is increased for each level of storage upgrade. */
|
||||
public static final float STORAGE_INCREASE_PER_LEVEL = 0.15f;
|
||||
/** The fraction by which potency is increased for each tier of matching wand. */
|
||||
public static final float POTENCY_INCREASE_PER_TIER = 0.15f;
|
||||
public static float POTENCY_INCREASE_PER_TIER = 0.15f;
|
||||
/** The fraction by which spell duration is increased for each level of duration upgrade. */
|
||||
public static final float DURATION_INCREASE_PER_LEVEL = 0.25f;
|
||||
public static float DURATION_INCREASE_PER_LEVEL = 0.25f;
|
||||
/** The fraction by which spell range is increased for each level of range upgrade. */
|
||||
public static final float RANGE_INCREASE_PER_LEVEL = 0.25f;
|
||||
public static float RANGE_INCREASE_PER_LEVEL = 0.25f;
|
||||
/** The fraction by which spell blast radius is increased for each level of range upgrade. */
|
||||
public static final float BLAST_RADIUS_INCREASE_PER_LEVEL = 0.25f;
|
||||
public static float BLAST_RADIUS_INCREASE_PER_LEVEL = 0.25f;
|
||||
/** The fraction by which movement speed is reduced per level of frost effect. */
|
||||
public static final double FROST_SLOWNESS_PER_LEVEL = 0.5;
|
||||
/** The fraction by which movement speed is reduced per level of decay effect. */
|
||||
@@ -46,7 +47,15 @@ public final class Constants {
|
||||
* won't spawn again if something is already standing in it.
|
||||
*/
|
||||
public static final int DECAY_SPREAD_INTERVAL = 8;
|
||||
/** The fraction by which potency is increased per level of the empowerment effect. */
|
||||
public static final float EMPOWERMENT_POTENCY_PER_LEVEL = 0.25f;
|
||||
|
||||
|
||||
// making this as an update to the existing values to not break addons directly relying on the fields
|
||||
static {
|
||||
POTENCY_INCREASE_PER_TIER = (float) Wizardry.settings.potencyIncreasePerTier;
|
||||
COOLDOWN_REDUCTION_PER_LEVEL = (float) Wizardry.settings.cooldownReductionPerLevel;
|
||||
DURATION_INCREASE_PER_LEVEL = (float) Wizardry.settings.durationIncreasePerLevel;
|
||||
RANGE_INCREASE_PER_LEVEL = (float) Wizardry.settings.rangeIncreasePerLevel;
|
||||
BLAST_RADIUS_INCREASE_PER_LEVEL = (float) Wizardry.settings.blastIncreasePerLevel;
|
||||
RANGE_INCREASE_PER_LEVEL = (float) Wizardry.settings.frostSlownessIncreasePerLevel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,6 +382,7 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
|
||||
activeImbuements.add((Imbuement)enchantment);
|
||||
}else{
|
||||
// Otherwise, removes the enchantment from the item
|
||||
((Imbuement) enchantment).onImbuementRemoval(stack);
|
||||
iterator.remove(); // FIXME: Apparently this can cause a CME
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import java.util.Iterator;
|
||||
* than having to deal with each of them separately, which would be inefficient and cumbersome (the former of those
|
||||
* classes cannot extend the latter because they both need to extend different subclasses of
|
||||
* {@link net.minecraft.enchantment.Enchantment}).
|
||||
*
|
||||
*
|
||||
* @since Wizardry 1.2
|
||||
*/
|
||||
@Mod.EventBusSubscriber
|
||||
@@ -69,12 +69,16 @@ public interface Imbuement {
|
||||
Enchantment enchantment = Enchantment.getEnchantmentByID(enchantmentTag.getShort("id"));
|
||||
// If the item contains a magic weapon enchantment, remove it from the item
|
||||
if(enchantment instanceof Imbuement){
|
||||
((Imbuement) enchantment).onImbuementRemoval(stack);
|
||||
enchantmentIt.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Allows executing some custom logic before this imbuement is being removed from the stack. Called when the imbuement is about to be removed. */
|
||||
default void onImbuementRemoval(ItemStack stack){}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onPlayerOpenContainerEvent(PlayerContainerEvent event){
|
||||
// Brute-force fix to stop enchanted books in dungeon chests from having imbuements on them.
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package electroblob.wizardry.entity.construct;
|
||||
|
||||
import electroblob.wizardry.entity.projectile.EntityConjuredArrow;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import net.minecraft.entity.projectile.EntityTippedArrow;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -30,7 +28,7 @@ public class EntityArrowRain extends EntityScaledConstruct {
|
||||
double y = posY + world.rand.nextDouble() * (double)height;
|
||||
double z = posZ + (world.rand.nextDouble() - 0.5D) * (double)width;
|
||||
|
||||
EntityTippedArrow arrow = new EntityTippedArrow(world, x, y, z);
|
||||
EntityConjuredArrow arrow = new EntityConjuredArrow(world, x, y, z);
|
||||
|
||||
arrow.motionX = MathHelper.cos((float)Math.toRadians(this.rotationYaw + 90));
|
||||
arrow.motionY = -0.6;
|
||||
@@ -38,7 +36,6 @@ public class EntityArrowRain extends EntityScaledConstruct {
|
||||
|
||||
arrow.shootingEntity = this.getCaster();
|
||||
arrow.setDamage(7.0d * damageMultiplier);
|
||||
arrow.setPotionEffect(new ItemStack(Items.ARROW));
|
||||
|
||||
this.world.spawnEntity(arrow);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ public class EntityFireRing extends EntityScaledConstruct {
|
||||
|
||||
super.onUpdate();
|
||||
|
||||
if(!this.world.isRemote){
|
||||
if(this.ticksExisted % 5 == 0 && !this.world.isRemote){
|
||||
|
||||
List<EntityLivingBase> targets = EntityUtils.getLivingWithinRadius(width/2, this.posX, this.posY, this.posZ, this.world);
|
||||
|
||||
|
||||
@@ -168,6 +168,10 @@ public class EntityForcefield extends EntityMagicConstruct implements ICustomHit
|
||||
((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target));
|
||||
}
|
||||
|
||||
if (this.ticksExisted % 5 == 0) {
|
||||
this.lifetime = (int) (lifetime * 0.99);
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
Vec3d relativeImpactPos = targetRelativePos.normalize().scale(radius);
|
||||
|
||||
@@ -68,13 +68,15 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
/** Data parameter for the wizard's element. */
|
||||
private static final DataParameter<Integer> ELEMENT = EntityDataManager.createKey(EntityEvilWizard.class,
|
||||
DataSerializers.VARINT);
|
||||
/** Data parameters for the wizard's current continuous spell. */
|
||||
private static final DataParameter<String> CONTINUOUS_SPELL = EntityDataManager.createKey(EntityEvilWizard.class, DataSerializers.STRING);
|
||||
private static final DataParameter<Integer> SPELL_COUNTER = EntityDataManager.createKey(EntityEvilWizard.class, DataSerializers.VARINT);
|
||||
|
||||
/** The resource location for the evil wizard's loot table. */
|
||||
private static final ResourceLocation LOOT_TABLE = new ResourceLocation(Wizardry.MODID, "entities/evil_wizard");
|
||||
|
||||
// Field implementations
|
||||
private List<Spell> spells = new ArrayList<Spell>(4);
|
||||
private Spell continuousSpell;
|
||||
private int spellCounter;
|
||||
|
||||
public EntityEvilWizard(World world){
|
||||
|
||||
@@ -93,6 +95,8 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
super.entityInit();
|
||||
this.dataManager.register(HEAL_COOLDOWN, -1);
|
||||
this.dataManager.register(ELEMENT, -1);
|
||||
this.dataManager.register(CONTINUOUS_SPELL, "ebwizardry:none");
|
||||
this.dataManager.register(SPELL_COUNTER, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -168,23 +172,23 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContinuousSpell(Spell spell){
|
||||
this.continuousSpell = spell;
|
||||
public void setContinuousSpell(Spell spell) {
|
||||
this.dataManager.set(CONTINUOUS_SPELL, spell.getRegistryName().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell getContinuousSpell(){
|
||||
return this.continuousSpell;
|
||||
public Spell getContinuousSpell() {
|
||||
return Spell.get(this.dataManager.get(CONTINUOUS_SPELL));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpellCounter(int count){
|
||||
spellCounter = count;
|
||||
public void setSpellCounter(int count) {
|
||||
this.dataManager.set(SPELL_COUNTER, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpellCounter(){
|
||||
return spellCounter;
|
||||
public int getSpellCounter() {
|
||||
return this.dataManager.get(SPELL_COUNTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -52,7 +52,7 @@ public class EntityMagicSlime extends EntitySlime implements ISummonedCreature {
|
||||
super(world);
|
||||
this.setPosition(target.posX, target.posY, target.posZ);
|
||||
this.startRiding(target);
|
||||
this.setOwnerId(caster.getUniqueID());
|
||||
if (caster != null) this.setOwnerId(caster.getUniqueID());
|
||||
this.setSlimeSize(2, false); // Needs to be called before setting the experience value to 0
|
||||
this.experienceValue = 0;
|
||||
this.lifetime = lifetime;
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
package electroblob.wizardry.entity.living;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import net.minecraft.entity.EntityFlying;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.ai.EntityAIAttackMelee;
|
||||
import net.minecraft.entity.ai.EntityAIHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAILookAtVillager;
|
||||
import net.minecraft.entity.ai.EntityAILookIdle;
|
||||
import net.minecraft.entity.ai.EntityAIMoveThroughVillage;
|
||||
import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
|
||||
import net.minecraft.entity.ai.EntityAIMoveTowardsTarget;
|
||||
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
|
||||
import net.minecraft.entity.ai.EntityAIWanderAvoidWater;
|
||||
import net.minecraft.entity.ai.EntityAIWatchClosest;
|
||||
import net.minecraft.entity.monster.EntityIronGolem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.network.datasync.DataSerializers;
|
||||
import net.minecraft.network.datasync.EntityDataManager;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.EnumParticleTypes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.world.DifficultyInstance;
|
||||
import net.minecraft.world.EnumDifficulty;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class EntitySpectralGolem extends EntityIronGolem implements ISummonedCreature {
|
||||
|
||||
private static final DataParameter<Boolean> SPAWN_PARTICLES = EntityDataManager.createKey(EntitySpectralGolem.class, DataSerializers.BOOLEAN);
|
||||
|
||||
// Field implementations
|
||||
private int lifetime = -1;
|
||||
private UUID casterUUID;
|
||||
|
||||
// Setter + getter implementations
|
||||
@Override public int getLifetime(){ return lifetime; }
|
||||
@Override public void setLifetime(int lifetime){ this.lifetime = lifetime; }
|
||||
@Override public UUID getOwnerId(){ return casterUUID; }
|
||||
@Override public void setOwnerId(UUID uuid){ this.casterUUID = uuid; }
|
||||
|
||||
/** Creates a new golem minion in the given world. */
|
||||
public EntitySpectralGolem(World world){
|
||||
super(world);
|
||||
this.experienceValue = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void entityInit(){
|
||||
super.entityInit();
|
||||
this.dataManager.register(SPAWN_PARTICLES, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initEntityAI() {
|
||||
this.tasks.addTask(1, new EntityAIAttackMelee(this, 1.0D, true));
|
||||
this.tasks.addTask(2, new EntityAIMoveTowardsTarget(this, 0.9D, 32.0F));
|
||||
this.tasks.addTask(3, new EntityAIMoveThroughVillage(this, 0.6D, true));
|
||||
this.tasks.addTask(4, new EntityAIMoveTowardsRestriction(this, 1.0D));
|
||||
this.tasks.addTask(5, new EntityAILookAtVillager(this));
|
||||
this.tasks.addTask(6, new EntityAIWanderAvoidWater(this, 0.6D));
|
||||
this.tasks.addTask(7, new EntityAIWatchClosest(this, EntityPlayer.class, 6.0F));
|
||||
this.tasks.addTask(8, new EntityAILookIdle(this));
|
||||
this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, false));
|
||||
this.targetTasks.addTask(2, new EntityAINearestAttackableTarget<>(this, EntityLivingBase.class,
|
||||
0, false, true, this.getTargetSelector()));
|
||||
}
|
||||
|
||||
@Override protected void setEquipmentBasedOnDifficulty(DifficultyInstance difficulty){} // They don't have equipment!
|
||||
|
||||
// Implementations
|
||||
|
||||
@Override
|
||||
public void setRevengeTarget(EntityLivingBase entity){
|
||||
if(this.shouldRevengeTarget(entity)) super.setRevengeTarget(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(){
|
||||
super.onUpdate();
|
||||
this.updateDelegate();
|
||||
|
||||
// Adds a dust particle effect
|
||||
if(this.world.isRemote){
|
||||
double x = this.posX - this.width / 2 + this.rand.nextFloat() * width;
|
||||
double y = this.posY + this.height * this.rand.nextFloat() + 0.2f;
|
||||
double z = this.posZ - this.width / 2 + this.rand.nextFloat() * width;
|
||||
ParticleBuilder.create(ParticleBuilder.Type.DUST).pos(x, y, z).clr(0.7f, 0.9f, 1).shaded(true).spawn(world);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpawn(){
|
||||
if(this.dataManager.get(SPAWN_PARTICLES)) this.spawnParticleEffect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDespawn(){
|
||||
this.spawnParticleEffect();
|
||||
}
|
||||
|
||||
private void spawnParticleEffect(){
|
||||
if(this.world.isRemote){
|
||||
for(int i = 0; i < 15; i++){
|
||||
this.world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, this.posX + this.rand.nextFloat() - 0.5f,
|
||||
this.posY + this.rand.nextFloat() * 2, this.posZ + this.rand.nextFloat() - 0.5f, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParticleEffect(){
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnimation(){
|
||||
return this.dataManager.get(SPAWN_PARTICLES) || this.ticksExisted > 20;
|
||||
}
|
||||
|
||||
public void hideParticles(){
|
||||
this.dataManager.set(SPAWN_PARTICLES, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean processInteract(EntityPlayer player, EnumHand hand){
|
||||
// In this case, the delegate method determines whether super is called.
|
||||
// Rather handily, we can make use of Java's short-circuiting method of evaluating OR statements.
|
||||
return this.interactDelegate(player, hand) || super.processInteract(player, hand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound nbttagcompound){
|
||||
super.writeEntityToNBT(nbttagcompound);
|
||||
this.writeNBTDelegate(nbttagcompound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readEntityFromNBT(NBTTagCompound nbttagcompound){
|
||||
super.readEntityFromNBT(nbttagcompound);
|
||||
this.readNBTDelegate(nbttagcompound);
|
||||
}
|
||||
|
||||
// Recommended overrides
|
||||
|
||||
@Override protected int getExperiencePoints(EntityPlayer player){ return 0; }
|
||||
@Override protected boolean canDropLoot(){ return false; }
|
||||
@Override protected Item getDropItem(){ return null; }
|
||||
@Override protected ResourceLocation getLootTable(){ return null; }
|
||||
@Override public boolean canPickUpLoot(){ return false; }
|
||||
|
||||
// This vanilla method has nothing to do with the custom despawn() method.
|
||||
@Override protected boolean canDespawn(){
|
||||
return getCaster() == null && getOwnerId() == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCanSpawnHere(){
|
||||
return this.world.getDifficulty() != EnumDifficulty.PEACEFUL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canAttackClass(Class<? extends EntityLivingBase> entityType){
|
||||
// Returns true unless the given entity type is a flying entity.
|
||||
return !EntityFlying.class.isAssignableFrom(entityType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName(){
|
||||
if(getCaster() != null){
|
||||
return new TextComponentTranslation(NAMEPLATE_TRANSLATION_KEY, getCaster().getName(),
|
||||
new TextComponentTranslation("entity." + this.getEntityString() + ".name"));
|
||||
}else{
|
||||
return super.getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomName(){
|
||||
// If this returns true, the renderer will show the nameplate when looking directly at the entity
|
||||
return Wizardry.settings.summonedCreatureNames && getCaster() != null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,6 +47,7 @@ import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.registry.ForgeRegistries;
|
||||
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
@@ -81,11 +82,12 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
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);
|
||||
/** Data parameters for the wizard's current continuous spell. */
|
||||
private static final DataParameter<String> CONTINUOUS_SPELL = EntityDataManager.createKey(EntityWizard.class, DataSerializers.STRING);
|
||||
private static final DataParameter<Integer> SPELL_COUNTER = EntityDataManager.createKey(EntityWizard.class, DataSerializers.VARINT);
|
||||
|
||||
// Field implementations
|
||||
private List<Spell> spells = new ArrayList<Spell>(4);
|
||||
private Spell continuousSpell;
|
||||
private int spellCounter;
|
||||
|
||||
/** A set of the positions of the blocks that are part of this wizard's tower. */
|
||||
private Set<BlockPos> towerBlocks;
|
||||
@@ -102,6 +104,8 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
super.entityInit();
|
||||
this.dataManager.register(HEAL_COOLDOWN, -1);
|
||||
this.dataManager.register(ELEMENT, 0);
|
||||
this.dataManager.register(CONTINUOUS_SPELL, "ebwizardry:none");
|
||||
this.dataManager.register(SPELL_COUNTER, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -182,23 +186,23 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContinuousSpell(Spell spell){
|
||||
this.continuousSpell = spell;
|
||||
public void setContinuousSpell(Spell spell) {
|
||||
this.dataManager.set(CONTINUOUS_SPELL, spell.getRegistryName().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spell getContinuousSpell(){
|
||||
return this.continuousSpell;
|
||||
public Spell getContinuousSpell() {
|
||||
return Spell.get(this.dataManager.get(CONTINUOUS_SPELL));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpellCounter(int count){
|
||||
spellCounter = count;
|
||||
public void setSpellCounter(int count) {
|
||||
this.dataManager.set(SPELL_COUNTER, count);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpellCounter(){
|
||||
return spellCounter;
|
||||
public int getSpellCounter() {
|
||||
return this.dataManager.get(SPELL_COUNTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -634,10 +638,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
|
||||
// This means it is more likely for spell books sold to be of the same element as the wizard if the
|
||||
// wizard has an element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
}else{
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
|
||||
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
|
||||
}
|
||||
}else{
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -656,10 +659,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
|
||||
// This means it is more likely for spell books sold to be of the same element as the wizard if the
|
||||
// wizard has an element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
}else{
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
|
||||
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
|
||||
}
|
||||
}else if(randomiser < 6){
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -693,10 +695,9 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0 && !specialismSpells.isEmpty()){
|
||||
// This means it is more likely for spell books sold to be of the same element as the wizard if the
|
||||
// wizard has an element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
}else{
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spells.get(rand.nextInt(spells.size())).metadata());
|
||||
return getBookStackForSpell(spells.get(rand.nextInt(spells.size())));
|
||||
}
|
||||
}else if(randomiser < 6){
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -721,8 +722,7 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
|
||||
if(randomiser < 5 && this.getElement() != Element.MAGIC && !specialismSpells.isEmpty()){
|
||||
// Master spells can only be sold by a specialist in that element.
|
||||
return new ItemStack(WizardryItems.spell_book, 1,
|
||||
specialismSpells.get(rand.nextInt(specialismSpells.size())).metadata());
|
||||
return getBookStackForSpell(specialismSpells.get(rand.nextInt(specialismSpells.size())));
|
||||
|
||||
}else if(randomiser < 6){
|
||||
if(this.getElement() != Element.MAGIC && rand.nextInt(4) > 0){
|
||||
@@ -798,7 +798,6 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
Tier maxTier = Tier.NOVICE;
|
||||
|
||||
List<Spell> npcSpells = Spell.getSpells(s -> s.canBeCastBy(wizard, false));
|
||||
npcSpells.removeIf(s -> !s.applicableForItem(WizardryItems.spell_book));
|
||||
|
||||
for(int i = 0; i < n; i++){
|
||||
|
||||
@@ -846,6 +845,22 @@ public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISp
|
||||
return maxTier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to handle addon spell books.
|
||||
* @param spell the spell to look up.
|
||||
* @return Checks all items of the spell's namespace (modid) if they are applicable for the spell and returns the first match, or falls back to WizardryItems.spell_book if no match was found.
|
||||
*/
|
||||
public static ItemStack getBookStackForSpell(Spell spell) {
|
||||
String modid = spell.getRegistryName().getNamespace();
|
||||
if (modid.equals(Wizardry.MODID)) {
|
||||
return new ItemStack(WizardryItems.spell_book, 1, spell.metadata());
|
||||
}
|
||||
Optional<Item> firstMatch = ForgeRegistries.ITEMS.getValuesCollection().stream().filter(v -> v instanceof ItemSpellBook && spell.applicableForItem(v)
|
||||
&& v.getRegistryName().getNamespace().equals(modid)).findFirst();
|
||||
|
||||
return firstMatch.map(item -> new ItemStack(item, 1, spell.metadata())).orElseGet(() -> new ItemStack(WizardryItems.spell_book, 1, spell.metadata()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpawnData(ByteBuf data){
|
||||
data.writeInt(textureIndex);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package electroblob.wizardry.entity.projectile;
|
||||
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.projectile.EntityArrow;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class EntityConjuredArrow extends EntityArrow {
|
||||
|
||||
public EntityConjuredArrow(World worldIn) {
|
||||
super(worldIn);
|
||||
}
|
||||
|
||||
public EntityConjuredArrow(World worldIn, double x, double y, double z) {
|
||||
super(worldIn, x, y, z);
|
||||
}
|
||||
|
||||
public EntityConjuredArrow(World worldIn, EntityLivingBase shooter) {
|
||||
super(worldIn, shooter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate() {
|
||||
super.onUpdate();
|
||||
if (this.timeInGround > 400) {
|
||||
this.setDead();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ItemStack getArrowStack() {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package electroblob.wizardry.event;
|
||||
|
||||
import electroblob.wizardry.item.ItemArtefact;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
|
||||
/**
|
||||
* ArtefactCheckEvent is fired when a check happens for an ItemArtefact using {@link electroblob.wizardry.item.ItemArtefact#isArtefactActive(net.minecraft.entity.player.EntityPlayer, net.minecraft.item.Item)}
|
||||
* <i>Fired on both sides.</i><br>
|
||||
* <br>
|
||||
* This event is {@link Cancelable}. <br>
|
||||
* <br>
|
||||
* This event has a result. {@link HasResult}. Set the result to Result.ALLOW to consider an artefact "active"<br>
|
||||
* <br>
|
||||
* This event is fired on the {@link MinecraftForge#EVENT_BUS}.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.10
|
||||
*/
|
||||
@Cancelable
|
||||
@Event.HasResult
|
||||
public class ArtefactCheckEvent extends PlayerEvent {
|
||||
|
||||
ItemArtefact artefact;
|
||||
EntityPlayer player;
|
||||
|
||||
public ArtefactCheckEvent(EntityPlayer player, ItemArtefact artefact) {
|
||||
super(player);
|
||||
this.player = player;
|
||||
this.artefact = artefact;
|
||||
setResult(Result.DENY);
|
||||
}
|
||||
|
||||
public ItemArtefact getArtefact() {
|
||||
return artefact;
|
||||
}
|
||||
|
||||
public EntityPlayer getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package electroblob.wizardry.event;
|
||||
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.tileentity.TileEntityImbuementAltar;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
|
||||
/**
|
||||
* ImbuementActivateEvent is fired when {@link TileEntityImbuementAltar#getImbuementResult(net.minecraft.item.ItemStack, electroblob.wizardry.constants.Element[],
|
||||
* boolean, net.minecraft.world.World, net.minecraft.entity.player.EntityPlayer)} is called to allow adding in imbuement "recipes" dynamically, based on the
|
||||
* contents of the Imbuement altar's receptacles and the item placed on the altar.
|
||||
*
|
||||
* <i>Note that this event is only fired on the server side.</i><br>
|
||||
* <br>
|
||||
* To alter the result of the imbuement process, change the {@link electroblob.wizardry.event.ImbuementActivateEvent#result} result of the process.<br>
|
||||
* <br>
|
||||
* This event is {@link Cancelable}. If this event is canceled, no further processing takes place.<br>
|
||||
* <br>
|
||||
* This event does not have a result. {@link Event.HasResult}<br>
|
||||
* <br>
|
||||
* This event is fired on the {@link MinecraftForge#EVENT_BUS}.
|
||||
*
|
||||
* @author WinDanesz
|
||||
* @since Wizardry 4.3.5
|
||||
*/
|
||||
@Cancelable
|
||||
public class ImbuementActivateEvent extends Event {
|
||||
|
||||
/** The item stack being imbued */
|
||||
public ItemStack input;
|
||||
|
||||
/** The elements of the four receptacles */
|
||||
public Element[] receptacleElements;
|
||||
|
||||
/** A reference to the current world object (may be null if {@code fullLootGen} is false) */
|
||||
public World world;
|
||||
|
||||
/** The player that last interacted with the imbuement altar, or null if there isn't one (or if this is being queried for other reasons, e.g. JEI) */
|
||||
public EntityPlayer lastUser;
|
||||
|
||||
/** The resulting item stack of the imbuement process */
|
||||
public ItemStack result;
|
||||
|
||||
public ImbuementActivateEvent(ItemStack input, Element[] receptacleElements, World world, EntityPlayer lastUser, ItemStack result) {
|
||||
super();
|
||||
this.input = input;
|
||||
this.receptacleElements = receptacleElements;
|
||||
this.world = world;
|
||||
this.lastUser = lastUser;
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package electroblob.wizardry.event;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.Cancelable;
|
||||
|
||||
/**
|
||||
* ResurrectionEvent is fired when a player is about to be resurrected, after all other checks have been performed.
|
||||
* <i>Note that this event is only fired on the server side.</i><br>
|
||||
* <br>
|
||||
* This event is {@link Cancelable}. If this event is canceled, the player is not resurrected.<br>
|
||||
* <br>
|
||||
* This event does not have a result. {@link HasResult}<br>
|
||||
* <br>
|
||||
* This event is fired on the {@link MinecraftForge#EVENT_BUS}.
|
||||
*
|
||||
* @author Electroblob
|
||||
* @since Wizardry 2.1
|
||||
*/
|
||||
@Cancelable
|
||||
public class ResurrectionEvent extends PlayerEvent {
|
||||
|
||||
private final EntityPlayer caster;
|
||||
|
||||
public ResurrectionEvent(EntityPlayer player, EntityPlayer caster){
|
||||
super(player);
|
||||
this.caster = caster;
|
||||
}
|
||||
|
||||
/** Returns the player that cast the resurrection spell. If the player resurrected themselves, this will be the
|
||||
* same as {@link ResurrectionEvent#getEntityPlayer()}. */
|
||||
public EntityPlayer getCaster(){
|
||||
return caster;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -46,6 +46,10 @@ public final class WizardryBaublesIntegration {
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.RING, BaubleType.RING);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.AMULET, BaubleType.AMULET);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.CHARM, BaubleType.CHARM);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.BELT, BaubleType.BELT);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.BODY, BaubleType.BODY);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.HEAD, BaubleType.HEAD);
|
||||
ARTEFACT_TYPE_MAP.put(ItemArtefact.Type.TRINKET, BaubleType.TRINKET);
|
||||
}
|
||||
|
||||
public static boolean enabled(){
|
||||
|
||||
@@ -452,6 +452,24 @@ public class ContainerArcaneWorkbench extends Container implements ISpellSortabl
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called (via {@link electroblob.wizardry.packet.PacketControlInput PacketControlInput}) when the clear button in
|
||||
* the arcane workbench GUI is pressed.
|
||||
*/
|
||||
// As of 2.1, for the sake of events and neatness of code, this was moved here from TileEntityArcaneWorkbench.
|
||||
// As of 4.2, the spell binding/charging/upgrading code was delegated (via IWorkbenchItem) to the items themselves.
|
||||
public void onClearButtonPressed(EntityPlayer player){
|
||||
|
||||
Slot centre = this.getSlot(CENTRE_SLOT);
|
||||
|
||||
if(centre.getStack().getItem() instanceof IWorkbenchItem){ // Should always be true, but no harm in checking.
|
||||
|
||||
Slot[] spellBooks = this.inventorySlots.subList(0, 8).toArray(new Slot[8]);
|
||||
|
||||
((IWorkbenchItem) centre.getStack().getItem()).onClearButtonPressed(player, centre, this.getSlot(CRYSTAL_SLOT), this.getSlot(UPGRADE_SLOT), spellBooks);
|
||||
}
|
||||
}
|
||||
|
||||
/** Scrolls to the given row number. */
|
||||
public void scrollTo(int row){
|
||||
this.scroll = row;
|
||||
|
||||
@@ -55,6 +55,26 @@ public interface IWorkbenchItem {
|
||||
*/
|
||||
boolean onApplyButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks);
|
||||
|
||||
/**
|
||||
* Called when this item is in the central slot of an arcane workbench and the apply clear is pressed. Items must
|
||||
* implement this method to define what happens when the apply button is pressed.
|
||||
* @param player The player that pressed the apply button.
|
||||
* @param centre The central slot in the arcane workbench. This slot will always contain a stack of the implementing
|
||||
* item, or in other words, <i>it is guaranteed that</i> {@code this == centre.getStack().getItem()}.
|
||||
* @param crystals The magic crystal slot of the arcane workbench.
|
||||
* @param upgrade The upgrade slot of the arcane workbench.
|
||||
* @param spellBooks An array of the <i>active</i> (visible) spell book slots in the arcane workbench. The length of
|
||||
* the array will be equal to the value returned by {@link IWorkbenchItem#getSpellSlotCount(ItemStack)}.
|
||||
* */
|
||||
default void onClearButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks){};
|
||||
|
||||
/**
|
||||
* Must be overridden in the item class to make the clear button in the Arcane Workbench clickable.
|
||||
* */
|
||||
default boolean isClearable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the tooltip (dark grey box) should be drawn when this item is in an arcane workbench. Only
|
||||
* called client-side.
|
||||
|
||||
@@ -10,6 +10,7 @@ import electroblob.wizardry.entity.living.ISummonedCreature;
|
||||
import electroblob.wizardry.entity.projectile.EntityDart;
|
||||
import electroblob.wizardry.entity.projectile.EntityForceOrb;
|
||||
import electroblob.wizardry.entity.projectile.EntityIceShard;
|
||||
import electroblob.wizardry.event.ArtefactCheckEvent;
|
||||
import electroblob.wizardry.event.SpellCastEvent;
|
||||
import electroblob.wizardry.event.SpellCastEvent.Source;
|
||||
import electroblob.wizardry.integration.DamageSafetyChecker;
|
||||
@@ -37,6 +38,7 @@ import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraftforge.common.BiomeDictionary;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||
import net.minecraftforge.event.entity.living.LivingDeathEvent;
|
||||
import net.minecraftforge.event.entity.living.LivingEvent;
|
||||
@@ -88,7 +90,11 @@ public class ItemArtefact extends Item {
|
||||
|
||||
/** An artefact that improves attacking spells. Two of these can be active at any one time. */ RING(2),
|
||||
/** An artefact that improves defensive spells. One of these can be active at any one time. */ AMULET(1),
|
||||
/** An artefact that improves utility spells. One of these can be active at any one time. */ CHARM(1);
|
||||
/** An artefact that improves utility spells. One of these can be active at any one time. */ CHARM(1),
|
||||
/** Added for add-on artefacts. */ BELT(1),
|
||||
/** Added for add-on artefacts. */ BODY(1),
|
||||
/** Added for add-on artefacts. */ HEAD(1),
|
||||
/** Added for add-on artefacts. */ TRINKET(1);
|
||||
|
||||
public final int maxAtOnce;
|
||||
|
||||
@@ -123,6 +129,8 @@ public class ItemArtefact extends Item {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isEnabled() { return enabled; }
|
||||
|
||||
@Override
|
||||
public EnumRarity getRarity(ItemStack stack){
|
||||
return rarity;
|
||||
@@ -176,6 +184,13 @@ public class ItemArtefact extends Item {
|
||||
|
||||
if(!((ItemArtefact)artefact).enabled) return false; // Disabled in the config
|
||||
|
||||
ArtefactCheckEvent event = new ArtefactCheckEvent(player, (ItemArtefact) artefact);
|
||||
if(MinecraftForge.EVENT_BUS.post(event)) return false;
|
||||
|
||||
if (event.getResult() == Event.Result.ALLOW) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if(WizardryBaublesIntegration.enabled()){
|
||||
return WizardryBaublesIntegration.isBaubleEquipped(player, artefact);
|
||||
}else{
|
||||
@@ -344,6 +359,8 @@ public class ItemArtefact extends Item {
|
||||
|
||||
findMatchingWandAndExecute(player, Spells.shield, wand -> {
|
||||
|
||||
if(wand.getItem() instanceof ItemScroll) return; // Ignore scrolls since they shouldn't work
|
||||
|
||||
List<Entity> projectiles = EntityUtils.getEntitiesWithinRadius(5, player.posX, player.posY, player.posZ, world, Entity.class);
|
||||
projectiles.removeIf(e -> !(e instanceof IProjectile));
|
||||
Vec3d look = player.getLookVec();
|
||||
@@ -765,6 +782,7 @@ public class ItemArtefact extends Item {
|
||||
&& Streams.stream(player.getHeldEquipment()).anyMatch(s -> s.getItem() instanceof ISpellCastingItem
|
||||
&& ((ISpellCastingItem)s.getItem()).getCurrentSpell(s).getElement() == Element.NECROMANCY))){
|
||||
|
||||
event.getEntityLiving().addPotionEffect(new PotionEffect(WizardryPotions.curse_of_soulbinding, 400));
|
||||
CurseOfSoulbinding.getSoulboundCreatures(WizardData.get(player)).add(event.getEntity().getUniqueID());
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,16 @@ import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.Style;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
@@ -100,6 +107,13 @@ public class ItemScroll extends Item implements ISpellCastingItem, IWorkbenchIte
|
||||
tooltip.add(spell.getElement().getDisplayName());
|
||||
tooltip.add(spell.getType().getDisplayName());
|
||||
}
|
||||
// Advanced tooltips displays the source mod's name if the spell is not from Wizardry
|
||||
if (advanced.isAdvanced() && this.getRegistryName().toString().equals(Wizardry.MODID + ":scroll") && !spell.getRegistryName().getNamespace().equals(Wizardry.MODID)) {
|
||||
String modId = spell.getRegistryName().getNamespace();
|
||||
String name = new Style().setColor(TextFormatting.BLUE).setItalic(true).getFormattingCode() +
|
||||
Loader.instance().getIndexedModList().get(modId).getMetadata().name;
|
||||
tooltip.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,7 +209,7 @@ public class ItemScroll extends Item implements ISpellCastingItem, IWorkbenchIte
|
||||
if(!spell.isContinuous && !caster.isCreative()) stack.shrink(1);
|
||||
|
||||
// Now uses the vanilla cooldown mechanic to prevent spamming of spells
|
||||
if(!spell.isContinuous) caster.getCooldownTracker().setCooldown(this, spell.getCooldown());
|
||||
if(!spell.isContinuous && !caster.isCreative()) caster.getCooldownTracker().setCooldown(this, spell.getCooldown());
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -230,7 +244,7 @@ public class ItemScroll extends Item implements ISpellCastingItem, IWorkbenchIte
|
||||
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Finish(Source.SCROLL, spell, user, modifiers, castingTick));
|
||||
spell.finishCasting(user.world, user, Double.NaN, Double.NaN, Double.NaN, null, castingTick, modifiers);
|
||||
|
||||
if(user instanceof EntityPlayer){
|
||||
if(user instanceof EntityPlayer && !((EntityPlayer)user).isCreative()){
|
||||
((EntityPlayer)user).getCooldownTracker().setCooldown(this, spell.getCooldown());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package electroblob.wizardry.item;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.entity.projectile.EntityConjuredArrow;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.util.InventoryUtils;
|
||||
import net.minecraft.enchantment.EnchantmentHelper;
|
||||
@@ -14,6 +15,7 @@ import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.item.IItemPropertyGetter;
|
||||
import net.minecraft.item.ItemArrow;
|
||||
import net.minecraft.item.ItemBow;
|
||||
import net.minecraft.item.ItemSpectralArrow;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.stats.StatList;
|
||||
import net.minecraft.util.*;
|
||||
@@ -197,8 +199,7 @@ public class ItemSpectralBow extends ItemBow implements IConjuredItem {
|
||||
|
||||
if(!world.isRemote){
|
||||
|
||||
ItemArrow itemarrow = (ItemArrow)Items.ARROW;
|
||||
EntityArrow entityarrow = itemarrow.createArrow(world, new ItemStack(itemarrow), entityplayer);
|
||||
EntityConjuredArrow entityarrow = new EntityConjuredArrow(world, entityplayer);
|
||||
entityarrow.shoot(entityplayer, entityplayer.rotationPitch, entityplayer.rotationYaw, 0.0F,
|
||||
f * 3.0F, 1.0F);
|
||||
|
||||
|
||||
@@ -12,10 +12,15 @@ import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.Style;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
@@ -96,6 +101,13 @@ public class ItemSpellBook extends Item {
|
||||
tooltip.add(spell.getElement().getDisplayName());
|
||||
tooltip.add(spell.getType().getDisplayName());
|
||||
}
|
||||
// Advanced tooltips displays the source mod's name if the spell is not from Wizardry
|
||||
if (advanced.isAdvanced() && this.getRegistryName().toString().equals(Wizardry.MODID + ":spell_book") && !spell.getRegistryName().getNamespace().equals(Wizardry.MODID)) {
|
||||
String modId = spell.getRegistryName().getNamespace();
|
||||
String name = new Style().setColor(TextFormatting.BLUE).setItalic(true).getFormattingCode() +
|
||||
Loader.instance().getIndexedModList().get(modId).getMetadata().name;
|
||||
tooltip.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.EnumAction;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
@@ -45,6 +46,7 @@ import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
@@ -226,9 +228,15 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean isHeld){
|
||||
public void onUpdate(ItemStack stack, World world, Entity entity, int slot, boolean isHeldInMainhand){
|
||||
boolean isHeld = isHeldInMainhand || entity instanceof EntityLivingBase && ItemStack.areItemStacksEqual(stack, ((EntityLivingBase) entity).getHeldItemOffhand());
|
||||
|
||||
WandHelper.decrementCooldowns(stack);
|
||||
// If Wizardry.settings.wandsMustBeHeldToDecrementCooldown is false, the cooldowns will be decremented.
|
||||
// If Wizardry.settings.wandsMustBeHeldToDecrementCooldown is true and isHeld is true, the cooldowns will also be decremented.
|
||||
// If Wizardry.settings.wandsMustBeHeldToDecrementCooldown is true and isHeld is false, the cooldowns will not be decremented.
|
||||
if (!Wizardry.settings.wandsMustBeHeldToDecrementCooldown || isHeld) {
|
||||
WandHelper.decrementCooldowns(stack);
|
||||
}
|
||||
|
||||
// Decrements wand damage (increases mana) every 1.5 seconds if it has a condenser upgrade
|
||||
if(!world.isRemote && !this.isManaFull(stack) && world.getTotalWorldTime() % Constants.CONDENSER_TICK_INTERVAL == 0){
|
||||
@@ -836,8 +844,19 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
||||
Spell spell = Spell.byMetadata(spellBooks[i].getStack().getItemDamage());
|
||||
// If the wand is powerful enough for the spell, it's not already bound to that slot and it's enabled for wands
|
||||
if(!(spell.getTier().level > this.tier.level) && spells[i] != spell && spell.isEnabled(SpellProperties.Context.WANDS)){
|
||||
|
||||
// Decide if we can bind this multiple times
|
||||
if (Wizardry.settings.preventBindingSameSpellTwiceToWands && Arrays.stream(spells).anyMatch(s -> s == spell)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
spells[i] = spell;
|
||||
changed = true;
|
||||
|
||||
// setting to consume books upon use
|
||||
if (Wizardry.settings.singleUseSpellBooks) {
|
||||
spellBooks[i].getStack().shrink(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -849,7 +868,12 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
||||
|
||||
int chargeDepleted = this.getManaCapacity(centre.getStack()) - this.getMana(centre.getStack());
|
||||
|
||||
int manaPerItem = Constants.MANA_PER_CRYSTAL;
|
||||
// Not too pretty but allows addons implementing the IManaStoringItem interface to provide their mana amount for custom crystals,
|
||||
// previously this was defaulted to the regular crystal's amount, allowing players to exploit it if a crystal was worth less mana than that.
|
||||
int manaPerItem = crystals.getStack().getItem() instanceof IManaStoringItem ?
|
||||
((IManaStoringItem) crystals.getStack().getItem()).getMana(crystals.getStack()) :
|
||||
crystals.getStack().getItem() instanceof ItemCrystal ? Constants.MANA_PER_CRYSTAL : Constants.MANA_PER_SHARD;
|
||||
|
||||
if(crystals.getStack().getItem() == WizardryItems.crystal_shard) manaPerItem = Constants.MANA_PER_SHARD;
|
||||
if(crystals.getStack().getItem() == WizardryItems.grand_crystal) manaPerItem = Constants.GRAND_CRYSTAL_MANA;
|
||||
|
||||
@@ -870,6 +894,28 @@ public class ItemWand extends Item implements IWorkbenchItem, ISpellCastingItem,
|
||||
return changed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClearButtonPressed(EntityPlayer player, Slot centre, Slot crystals, Slot upgrade, Slot[] spellBooks){
|
||||
ItemStack stack = centre.getStack();
|
||||
if (stack.hasTagCompound() && stack.getTagCompound().hasKey(WandHelper.SPELL_ARRAY_KEY)) {
|
||||
NBTTagCompound nbt = stack.getTagCompound();
|
||||
int[] spells = nbt.getIntArray(WandHelper.SPELL_ARRAY_KEY);
|
||||
int expectedSlotCount = BASE_SPELL_SLOTS + WandHelper.getUpgradeLevel(stack,
|
||||
WizardryItems.attunement_upgrade);
|
||||
|
||||
// unbrick broken wands
|
||||
if (spells.length < expectedSlotCount) {
|
||||
spells = new int[expectedSlotCount];
|
||||
}
|
||||
Arrays.fill(spells, 0);
|
||||
nbt.setIntArray(WandHelper.SPELL_ARRAY_KEY, spells);
|
||||
stack.setTagCompound(nbt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClearable() { return true; }
|
||||
|
||||
// hitEntity is only called server-side, so we'll have to use events
|
||||
@SubscribeEvent
|
||||
public static void onAttackEntityEvent(AttackEntityEvent event){
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package electroblob.wizardry.item;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Streams;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.client.DrawingUtils;
|
||||
@@ -44,7 +46,11 @@ import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
@@ -54,6 +60,28 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
private static final float SAGE_OTHER_COST_REDUCTION = 0.2f;
|
||||
private static final float WARLOCK_SPEED_BOOST = 0.2f;
|
||||
private static final UUID WARLOCK_SPEED_BOOST_UUID = UUID.fromString("4bad7152-2663-4b1b-bb59-552e92847031");
|
||||
// Standard ItemArmor modifiers
|
||||
private 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")};
|
||||
|
||||
@Override
|
||||
public Multimap<String, AttributeModifier> getItemAttributeModifiers(EntityEquipmentSlot slot) {
|
||||
// The vanilla armor handling logic from ItemArmor.getItemAttributeModifiers was moved to ItemWizardArmour.getAttributeModifiers to allow checking if the stack has enough mana
|
||||
Multimap<String, AttributeModifier> multimap = ArrayListMultimap.create();
|
||||
return multimap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Multimap<String, AttributeModifier> getAttributeModifiers(EntityEquipmentSlot slot, ItemStack stack) {
|
||||
Multimap<String, AttributeModifier> multimap = super.getAttributeModifiers(slot, stack);
|
||||
|
||||
// only grant armor if the equipment has mana
|
||||
if (slot == this.armorType && !((ItemWizardArmour) stack.getItem()).isManaEmpty(stack)) {
|
||||
multimap.put(SharedMonsterAttributes.ARMOR.getName(), new AttributeModifier(ARMOR_MODIFIERS[slot.getIndex()], "Armor modifier", this.damageReduceAmount, 0));
|
||||
multimap.put(SharedMonsterAttributes.ARMOR_TOUGHNESS.getName(), new AttributeModifier(ARMOR_MODIFIERS[slot.getIndex()], "Armor toughness", this.toughness, 0));
|
||||
}
|
||||
|
||||
return multimap;
|
||||
}
|
||||
|
||||
public enum ArmourClass {
|
||||
|
||||
@@ -181,8 +209,8 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
|
||||
@Override
|
||||
public void onArmorTick(World world, EntityPlayer player, ItemStack itemStack){
|
||||
if(armorType == EntityEquipmentSlot.HEAD && isWearingFullSet(player, element, ArmourClass.BATTLEMAGE)
|
||||
&& player.ticksExisted % 20 == 0){
|
||||
if(armorType == EntityEquipmentSlot.HEAD && player.ticksExisted % 20 == 0
|
||||
&& isWearingFullSet(player, element, ArmourClass.BATTLEMAGE) && doAllArmourPiecesHaveMana(player)){
|
||||
player.addPotionEffect(new PotionEffect(WizardryPotions.ward, 219, 0, true, false));
|
||||
}
|
||||
}
|
||||
@@ -209,7 +237,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
modifiers.set(WizardryItems.cooldown_upgrade, modifiers.get(WizardryItems.cooldown_upgrade) - armourClass.cooldownReduction, true);
|
||||
|
||||
// Full set bonuses
|
||||
if(this.armorType == EntityEquipmentSlot.HEAD && isWearingFullSet(caster, element, armourClass)){
|
||||
if(this.armorType == EntityEquipmentSlot.HEAD && isWearingFullSet(caster, element, armourClass) && doAllArmourPiecesHaveMana(caster)){
|
||||
if(armourClass == ArmourClass.SAGE && spell.getElement() != this.element){
|
||||
modifiers.set(SpellModifiers.COST, 1 - SAGE_OTHER_COST_REDUCTION, false);
|
||||
}
|
||||
@@ -306,7 +334,12 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
|
||||
int chargeDepleted = this.getManaCapacity(centre.getStack()) - this.getMana(centre.getStack());
|
||||
|
||||
int manaPerItem = Constants.MANA_PER_CRYSTAL;
|
||||
// Not too pretty but allows addons implementing the IManaStoringItem interface to provide their mana amount for custom crystals,
|
||||
// previously this was defaulted to the regular crystal's amount, allowing players to exploit it if a crystal was worth less mana than that.
|
||||
int manaPerItem = crystals.getStack().getItem() instanceof IManaStoringItem ?
|
||||
((IManaStoringItem) crystals.getStack().getItem()).getMana(crystals.getStack()) :
|
||||
crystals.getStack().getItem() instanceof ItemCrystal ? Constants.MANA_PER_CRYSTAL : Constants.MANA_PER_SHARD;
|
||||
|
||||
if(crystals.getStack().getItem() == WizardryItems.crystal_shard) manaPerItem = Constants.MANA_PER_SHARD;
|
||||
if(crystals.getStack().getItem() == WizardryItems.grand_crystal) manaPerItem = Constants.GRAND_CRYSTAL_MANA;
|
||||
|
||||
@@ -335,7 +368,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
|
||||
IAttributeInstance movementSpeed = event.getEntityLiving().getAttributeMap().getAttributeInstance(SharedMonsterAttributes.MOVEMENT_SPEED);
|
||||
|
||||
if(isWearingFullSet(event.getEntityLiving(), null, ArmourClass.WARLOCK)){
|
||||
if(isWearingFullSet(event.getEntityLiving(), null, ArmourClass.WARLOCK) && doAllArmourPiecesHaveMana(event.getEntityLiving())){
|
||||
// Only apply the modifier once (can't just check this is the helmet since it might not be the last piece equipped)
|
||||
if(movementSpeed.getModifier(WARLOCK_SPEED_BOOST_UUID) == null){
|
||||
movementSpeed.applyModifier(new AttributeModifier(WARLOCK_SPEED_BOOST_UUID, "Warlock set bonus", WARLOCK_SPEED_BOOST, Operations.MULTIPLY_FLAT));
|
||||
@@ -405,7 +438,7 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
* @param armourClass The class to check, or null to accept any class as long as they are all the same.
|
||||
* @return True if the entity is wearing a full set of the given element and class, false otherwise.
|
||||
*/
|
||||
private static boolean isWearingFullSet(EntityLivingBase entity, @Nullable Element element, @Nullable ArmourClass armourClass){
|
||||
public static boolean isWearingFullSet(EntityLivingBase entity, @Nullable Element element, @Nullable ArmourClass armourClass){
|
||||
ItemStack helmet = entity.getItemStackFromSlot(EntityEquipmentSlot.HEAD);
|
||||
if(!(helmet.getItem() instanceof ItemWizardArmour)) return false;
|
||||
Element e = element == null ? ((ItemWizardArmour)helmet.getItem()).element : element;
|
||||
@@ -416,6 +449,16 @@ public class ItemWizardArmour extends ItemArmor implements IWorkbenchItem, IMana
|
||||
&& ((ItemWizardArmour)entity.getItemStackFromSlot(s).getItem()).armourClass == ac);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given entity's armour pieces which implement {@link IManaStoringItem} has mana. Ignores pieces which doesn't have a mana storage.
|
||||
* @param entity The entity to query.
|
||||
* @return True if all armour pieces which implement {@link IManaStoringItem} has mana, false otherwise.
|
||||
*/
|
||||
public static boolean doAllArmourPiecesHaveMana(EntityLivingBase entity){
|
||||
return Arrays.stream(InventoryUtils.ARMOUR_SLOTS).noneMatch(s -> entity.getItemStackFromSlot(s).getItem() instanceof IManaStoringItem
|
||||
&& ((IManaStoringItem) entity.getItemStackFromSlot(s).getItem()).isManaEmpty(entity.getItemStackFromSlot(s)));
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onLivingSetAttackTargetEvent(LivingSetAttackTargetEvent event){
|
||||
// Undo the mob detection penalty for wearing armour when invisible
|
||||
|
||||
@@ -10,6 +10,7 @@ import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.EnumActionResult;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.text.Style;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -36,7 +37,11 @@ public class ItemWizardHandbook extends Item {
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand){
|
||||
ItemStack stack = player.getHeldItem(hand);
|
||||
player.openGui(Wizardry.instance, WizardryGuiHandler.WIZARD_HANDBOOK, world, 0, 0, 0);
|
||||
if (Wizardry.settings.loadHandbook) {
|
||||
player.openGui(Wizardry.instance, WizardryGuiHandler.WIZARD_HANDBOOK, world, 0, 0, 0);
|
||||
} else if (!world.isRemote){
|
||||
player.sendStatusMessage(new TextComponentTranslation("item." + Wizardry.MODID + ":wizard_handbook.disabled"), false);
|
||||
}
|
||||
return ActionResult.newResult(EnumActionResult.SUCCESS, stack);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,12 +12,15 @@ import electroblob.wizardry.entity.living.*;
|
||||
import electroblob.wizardry.entity.projectile.EntityFirebomb;
|
||||
import electroblob.wizardry.entity.projectile.EntityMagicFireball;
|
||||
import electroblob.wizardry.event.SpellCastEvent;
|
||||
import electroblob.wizardry.event.SpellCastEvent.Source;
|
||||
import electroblob.wizardry.item.IManaStoringItem;
|
||||
import electroblob.wizardry.item.ISpellCastingItem;
|
||||
import electroblob.wizardry.item.ItemArtefact;
|
||||
import electroblob.wizardry.registry.*;
|
||||
import electroblob.wizardry.spell.Banish;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
import electroblob.wizardry.util.BlockUtils;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import electroblob.wizardry.util.SpellProperties.Context;
|
||||
import net.minecraft.entity.effect.EntityLightningBolt;
|
||||
import net.minecraft.entity.item.EntityFallingBlock;
|
||||
@@ -174,6 +177,23 @@ public abstract class Forfeit {
|
||||
|
||||
forfeit.apply(event.getWorld(), player);
|
||||
|
||||
ItemStack stack = player.getHeldItemMainhand();
|
||||
|
||||
if(!(stack.getItem() instanceof ISpellCastingItem)){
|
||||
stack = player.getHeldItemOffhand();
|
||||
if(!(stack.getItem() instanceof ISpellCastingItem)) stack = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
if(!stack.isEmpty()){
|
||||
// Still need to charge the player mana or consume the scroll
|
||||
if(event.getSource() == Source.SCROLL){
|
||||
if(!player.isCreative()) stack.shrink(1);
|
||||
}else if(stack.getItem() instanceof IManaStoringItem){
|
||||
int cost = (int)(event.getSpell().getCost() * event.getModifiers().get(SpellModifiers.COST) + 0.1f); // Weird floaty rounding
|
||||
((IManaStoringItem)stack.getItem()).consumeMana(stack, cost, player);
|
||||
}
|
||||
}
|
||||
|
||||
WizardryAdvancementTriggers.spell_failure.triggerFor(player);
|
||||
|
||||
EntityUtils.playSoundAtPlayer(player, forfeit.getSound(), WizardrySounds.SPELLS, 1, 1);
|
||||
@@ -222,10 +242,11 @@ public abstract class Forfeit {
|
||||
}));
|
||||
|
||||
add(Tier.MASTER, Element.FIRE, create("burn_surroundings", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
if(!w.isRemote && EntityUtils.canDamageBlocks(p, w)){
|
||||
List<BlockPos> sphere = BlockUtils.getBlockSphere(p.getPosition(), 6);
|
||||
for(BlockPos pos : sphere){
|
||||
if(w.rand.nextBoolean() && w.isAirBlock(pos)) w.setBlockState(pos, Blocks.FIRE.getDefaultState());
|
||||
if(w.rand.nextBoolean() && w.isAirBlock(pos) && BlockUtils.canPlaceBlock(p, w, pos))
|
||||
w.setBlockState(pos, Blocks.FIRE.getDefaultState());
|
||||
}
|
||||
}
|
||||
}));
|
||||
@@ -376,10 +397,11 @@ public abstract class Forfeit {
|
||||
}));
|
||||
|
||||
add(Tier.NOVICE, Element.EARTH, create("snares", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
if(!w.isRemote && EntityUtils.canDamageBlocks(p, w)){
|
||||
for(EnumFacing direction : EnumFacing.HORIZONTALS){
|
||||
BlockPos pos = p.getPosition().offset(direction);
|
||||
if(BlockUtils.canBlockBeReplaced(w, pos)) w.setBlockState(pos, WizardryBlocks.snare.getDefaultState());
|
||||
if(BlockUtils.canBlockBeReplaced(w, pos) && BlockUtils.canPlaceBlock(p, w, pos))
|
||||
w.setBlockState(pos, WizardryBlocks.snare.getDefaultState());
|
||||
}
|
||||
}
|
||||
}));
|
||||
@@ -393,9 +415,9 @@ public abstract class Forfeit {
|
||||
}));
|
||||
|
||||
add(Tier.APPRENTICE, Element.EARTH, create("uproot_plants", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
if(!w.isRemote && EntityUtils.canDamageBlocks(p, w)){
|
||||
List<BlockPos> sphere = BlockUtils.getBlockSphere(p.getPosition(), 5);
|
||||
sphere.removeIf(pos -> !(w.getBlockState(pos).getBlock() instanceof IPlantable));
|
||||
sphere.removeIf(pos -> !(w.getBlockState(pos).getBlock() instanceof IPlantable) || !BlockUtils.canBreakBlock(p, w, pos));
|
||||
sphere.forEach(pos -> w.destroyBlock(pos, true));
|
||||
}
|
||||
}));
|
||||
@@ -403,9 +425,9 @@ public abstract class Forfeit {
|
||||
add(Tier.APPRENTICE, Element.EARTH, create("poison_self", (w, p) -> p.addPotionEffect(new PotionEffect(MobEffects.POISON, 400, 1))));
|
||||
|
||||
add(Tier.ADVANCED, Element.EARTH, create("flood", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
if(!w.isRemote && EntityUtils.canDamageBlocks(p, w)){
|
||||
List<BlockPos> sphere = BlockUtils.getBlockSphere(p.getPosition().up(), 2);
|
||||
sphere.removeIf(pos -> !BlockUtils.canBlockBeReplaced(w, pos, true));
|
||||
sphere.removeIf(pos -> !BlockUtils.canBlockBeReplaced(w, pos, true) || !BlockUtils.canPlaceBlock(p, w, pos));
|
||||
sphere.forEach(pos -> w.setBlockState(pos, Blocks.WATER.getDefaultState()));
|
||||
}
|
||||
}));
|
||||
@@ -413,8 +435,7 @@ public abstract class Forfeit {
|
||||
add(Tier.MASTER, Element.EARTH, create("bury_self", (w, p) -> {
|
||||
if(!w.isRemote){
|
||||
List<BlockPos> sphere = BlockUtils.getBlockSphere(p.getPosition(), 4);
|
||||
sphere.removeIf(pos -> !w.getBlockState(pos).isFullCube());
|
||||
sphere.removeIf(pos -> BlockUtils.isBlockUnbreakable(w, pos));
|
||||
sphere.removeIf(pos -> !w.getBlockState(pos).isFullCube() || BlockUtils.isBlockUnbreakable(w, pos) || BlockUtils.canBreakBlock(p, w, pos));
|
||||
sphere.forEach(pos -> {
|
||||
EntityFallingBlock block = new EntityFallingBlock(w, pos.getX() + 0.5, pos.getY() + 0.5,
|
||||
pos.getZ() + 0.5, w.getBlockState(pos));
|
||||
@@ -465,6 +486,8 @@ public abstract class Forfeit {
|
||||
}
|
||||
}));
|
||||
|
||||
add(Tier.MASTER, Element.SORCERY, create("teleport_self_large_distance", (w, p) -> ((Banish)Spells.banish).teleport(p, w, 8 + w.rand.nextDouble() * 700)));
|
||||
|
||||
add(Tier.NOVICE, Element.HEALING, create("damage_self", (w, p) -> p.attackEntityFrom(DamageSource.MAGIC, 4)));
|
||||
|
||||
add(Tier.NOVICE, Element.HEALING, create("spill_armour", (w, p) -> {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package electroblob.wizardry.misc;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.item.IManaStoringItem;
|
||||
import electroblob.wizardry.item.ItemManaFlask;
|
||||
import net.minecraft.inventory.InventoryCrafting;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.CraftingManager;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
@@ -15,6 +15,8 @@ import net.minecraftforge.fml.common.gameevent.PlayerEvent;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
import net.minecraftforge.oredict.ShapelessOreRecipe;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Implements a dynamic crafting recipe for recharging items with mana flasks.
|
||||
*
|
||||
@@ -24,6 +26,8 @@ import net.minecraftforge.oredict.ShapelessOreRecipe;
|
||||
@Mod.EventBusSubscriber
|
||||
public class RecipeRechargeWithFlask extends ShapelessOreRecipe {
|
||||
|
||||
private static final Multimap<Item, RecipeRechargeWithFlask> FLASK_RECIPES = HashMultimap.create();
|
||||
|
||||
private final IManaStoringItem chargeable;
|
||||
private final ItemManaFlask flask;
|
||||
|
||||
@@ -38,6 +42,7 @@ public class RecipeRechargeWithFlask extends ShapelessOreRecipe {
|
||||
if(!(chargeable instanceof IManaStoringItem)) throw new IllegalArgumentException("Item to be charged must be an instance of IManaStoringItem");
|
||||
this.chargeable = (IManaStoringItem)chargeable;
|
||||
this.flask = flask;
|
||||
FLASK_RECIPES.put(chargeable, this);
|
||||
}
|
||||
|
||||
// Commented out for now because JEI spams the log with errors about the recipe having no output
|
||||
@@ -91,11 +96,11 @@ public class RecipeRechargeWithFlask extends ShapelessOreRecipe {
|
||||
// This means that although I no longer have to replace the result every tick, I still need to do it here
|
||||
// ... I thought the whole point of the new recipe system was so that I DIDN'T have to do this?!
|
||||
if(event.craftMatrix instanceof InventoryCrafting){
|
||||
for(IRecipe recipe : CraftingManager.REGISTRY){
|
||||
if(recipe instanceof RecipeRechargeWithFlask
|
||||
&& recipe.matches((InventoryCrafting)event.craftMatrix, event.player.world)){
|
||||
Collection<RecipeRechargeWithFlask> recipes = FLASK_RECIPES.get(event.crafting.getItem());
|
||||
for(RecipeRechargeWithFlask recipe : recipes){
|
||||
if(recipe.matches((InventoryCrafting)event.craftMatrix, event.player.world)){
|
||||
// Have to modify the itemstack in the actual event, it cannot be replaced
|
||||
((RecipeRechargeWithFlask)recipe).rechargeItemAndCopyNBT(event.crafting, (InventoryCrafting)event.craftMatrix);
|
||||
recipe.rechargeItemAndCopyNBT(event.crafting, (InventoryCrafting)event.craftMatrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package electroblob.wizardry.packet;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.event.ResurrectionEvent;
|
||||
import electroblob.wizardry.inventory.ContainerArcaneWorkbench;
|
||||
import electroblob.wizardry.item.ISpellCastingItem;
|
||||
import electroblob.wizardry.packet.PacketControlInput.Message;
|
||||
@@ -13,6 +14,7 @@ import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
|
||||
@@ -49,6 +51,17 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
|
||||
|
||||
break;
|
||||
|
||||
case CLEAR_BUTTON:
|
||||
|
||||
if(!(player.openContainer instanceof ContainerArcaneWorkbench)){
|
||||
Wizardry.logger.warn("Received a PacketControlInput, but the player that sent it was not " +
|
||||
"currently using an arcane workbench. This should not happen!");
|
||||
}else{
|
||||
((ContainerArcaneWorkbench)player.openContainer).onClearButtonPressed(player);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NEXT_SPELL_KEY:
|
||||
|
||||
if(wand.getItem() instanceof ISpellCastingItem){
|
||||
@@ -79,6 +92,7 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
|
||||
.filter(s -> Resurrection.canStackResurrect(s, player)).findFirst().orElse(null);
|
||||
|
||||
if(stack != null){
|
||||
if(MinecraftForge.EVENT_BUS.post(new ResurrectionEvent(player, player))) break;
|
||||
// This should suffice, since this is the only way a player can cast resurrection when dead!
|
||||
((ISpellCastingItem)stack.getItem()).cast(stack, Spells.resurrection, player, EnumHand.MAIN_HAND, 0, new SpellModifiers());
|
||||
break;
|
||||
@@ -130,7 +144,7 @@ public class PacketControlInput implements IMessageHandler<Message, IMessage> {
|
||||
}
|
||||
|
||||
public enum ControlType {
|
||||
APPLY_BUTTON, NEXT_SPELL_KEY, PREVIOUS_SPELL_KEY, RESURRECT_BUTTON, CANCEL_RESURRECT, POSSESSION_PROJECTILE
|
||||
APPLY_BUTTON, NEXT_SPELL_KEY, PREVIOUS_SPELL_KEY, RESURRECT_BUTTON, CANCEL_RESURRECT, POSSESSION_PROJECTILE, CLEAR_BUTTON
|
||||
}
|
||||
|
||||
public static class Message implements IMessage {
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.item.ItemWizardArmour;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.inventory.EntityEquipmentSlot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraftforge.common.ISpecialArmor;
|
||||
|
||||
public class CurseUndeath extends Curse {
|
||||
|
||||
@@ -25,7 +28,7 @@ public class CurseUndeath extends Curse {
|
||||
|
||||
// Adapted from EntityZombie
|
||||
if(entitylivingbase.world.isDaytime() && !entitylivingbase.world.isRemote){
|
||||
|
||||
|
||||
float f = entitylivingbase.getBrightness();
|
||||
|
||||
if(f > 0.5F && entitylivingbase.world.rand.nextFloat() * 30.0F < (f - 0.4F) * 2.0F
|
||||
@@ -35,14 +38,21 @@ public class CurseUndeath extends Curse {
|
||||
boolean flag = true;
|
||||
ItemStack itemstack = entitylivingbase.getItemStackFromSlot(EntityEquipmentSlot.HEAD);
|
||||
|
||||
if(!itemstack.isEmpty()){
|
||||
if(itemstack.isItemStackDamageable()){
|
||||
if (!itemstack.isEmpty()) {
|
||||
if (itemstack.isItemStackDamageable()) {
|
||||
|
||||
itemstack.setItemDamage(itemstack.getItemDamage() + entitylivingbase.world.rand.nextInt(2));
|
||||
|
||||
if(itemstack.getItemDamage() >= itemstack.getMaxDamage()){
|
||||
entitylivingbase.renderBrokenItemStack(itemstack);
|
||||
entitylivingbase.setItemStackToSlot(EntityEquipmentSlot.HEAD, ItemStack.EMPTY);
|
||||
if (itemstack.getItem() instanceof ISpecialArmor) {
|
||||
((ISpecialArmor) itemstack.getItem()).damageArmor(entitylivingbase, itemstack, DamageSource.ON_FIRE, entitylivingbase.world.rand.nextInt(2), EntityEquipmentSlot.HEAD.getSlotIndex());
|
||||
} else {
|
||||
itemstack.setItemDamage(itemstack.getItemDamage() + entitylivingbase.world.rand.nextInt(2));
|
||||
if (itemstack.getItemDamage() >= itemstack.getMaxDamage()) {
|
||||
if (itemstack.getItem() instanceof ItemWizardArmour) {
|
||||
entitylivingbase.setFire(8);
|
||||
} else {
|
||||
entitylivingbase.renderBrokenItemStack(itemstack);
|
||||
entitylivingbase.setItemStackToSlot(EntityEquipmentSlot.HEAD, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,17 +2,14 @@ package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import electroblob.wizardry.util.GeometryUtils;
|
||||
import electroblob.wizardry.util.NBTExtras;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.network.play.server.SPacketEntityVelocity;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
@@ -23,8 +20,6 @@ public class PotionContainment extends PotionMagicEffect {
|
||||
|
||||
public static final String ENTITY_TAG = "containmentPos";
|
||||
|
||||
private static final double RUBBERBAND_THRESHOLD = 0.24;
|
||||
|
||||
public PotionContainment(boolean isBadEffect, int liquidColour){
|
||||
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/containment.png"));
|
||||
this.setPotionName("potion." + Wizardry.MODID + ":containment");
|
||||
@@ -41,7 +36,6 @@ public class PotionContainment extends PotionMagicEffect {
|
||||
|
||||
@Override
|
||||
public void performEffect(EntityLivingBase target, int strength){
|
||||
|
||||
float maxDistance = getContainmentDistance(strength);
|
||||
|
||||
// Initialise the containment position to the entity's position if it wasn't set already
|
||||
@@ -63,59 +57,14 @@ public class PotionContainment extends PotionMagicEffect {
|
||||
if(target.getEntityBoundingBox().maxZ > origin.z + maxDistance) z = origin.z + maxDistance - target.width/2;
|
||||
if(target.getEntityBoundingBox().minZ < origin.z - maxDistance) z = origin.z - maxDistance + target.width/2;
|
||||
|
||||
if(x != target.posX || y != target.posY || z != target.posZ){
|
||||
|
||||
// if(target.world.isRemote){
|
||||
//
|
||||
// if(x != target.posX){
|
||||
// for(int i = 0; i < 20; i++){
|
||||
// ParticleBuilder.create(ParticleBuilder.Type.DUST).pos(
|
||||
// x,
|
||||
// target.posY + target.height * target.world.rand.nextFloat(),
|
||||
// target.posZ + target.width * (target.world.rand.nextFloat() - 0.5f))
|
||||
// .face(EnumFacing.EAST).clr(0.8f, 0.9f, 1).spawn(target.world);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(y != target.posY){
|
||||
// for(int i = 0; i < 20; i++){
|
||||
// ParticleBuilder.create(ParticleBuilder.Type.DUST).pos(
|
||||
// target.posX + target.width * (target.world.rand.nextFloat() - 0.5f),
|
||||
// y,
|
||||
// target.posZ + target.width * (target.world.rand.nextFloat() - 0.5f))
|
||||
// .face(EnumFacing.UP).clr(0.8f, 0.9f, 1).spawn(target.world);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if(z != target.posZ){
|
||||
// for(int i = 0; i < 20; i++){
|
||||
// ParticleBuilder.create(ParticleBuilder.Type.DUST).pos(
|
||||
// target.posX + target.width * (target.world.rand.nextFloat() - 0.5f),
|
||||
// target.posY + target.height * target.world.rand.nextFloat(),
|
||||
// z)
|
||||
// .face(EnumFacing.SOUTH).clr(0.8f, 0.9f, 1).spawn(target.world);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Rubberbanding prevention (the 0.25 limit is from NetHandlerPlayServer, just search "moved wrongly"
|
||||
if(target instanceof EntityPlayer){
|
||||
x = MathHelper.clamp(x, target.posX - RUBBERBAND_THRESHOLD, target.posX + RUBBERBAND_THRESHOLD);
|
||||
y = MathHelper.clamp(y, target.posY - RUBBERBAND_THRESHOLD, target.posY + RUBBERBAND_THRESHOLD);
|
||||
z = MathHelper.clamp(z, target.posZ - RUBBERBAND_THRESHOLD, target.posZ + RUBBERBAND_THRESHOLD);
|
||||
}
|
||||
|
||||
if(x != target.posX || y != target.posY || z != target.posZ)
|
||||
{
|
||||
target.addVelocity(0.15 * Math.signum(x - target.posX), 0.15 * Math.signum(y - target.posY), 0.15 * Math.signum(z - target.posZ));
|
||||
EntityUtils.undoGravity(target);
|
||||
target.addVelocity(0.35 * Math.signum(x - target.posX), 0.35 * Math.signum(y - target.posY), 0.35 * Math.signum(z - target.posZ));
|
||||
target.setPositionAndUpdate(x, y, z); // FIXME: This line must be causing the server rubberbanding, not sure why
|
||||
// Player motion is handled on that player's client so needs packets
|
||||
if(target instanceof EntityPlayerMP){
|
||||
((EntityPlayerMP)target).connection.sendPacket(new SPacketEntityVelocity(target));
|
||||
if(target.world.isRemote){
|
||||
target.world.playSound(target.posX, target.posY, target.posZ, WizardrySounds.ENTITY_FORCEFIELD_DEFLECT,
|
||||
WizardrySounds.SPELLS, 0.3f, 1f, false);
|
||||
}
|
||||
//
|
||||
// target.world.playSound(target.posX, target.posY, target.posZ, WizardrySounds.ENTITY_FORCEFIELD_DEFLECT,
|
||||
// WizardrySounds.SPELLS, 0.3f, 1f, false);
|
||||
|
||||
}
|
||||
|
||||
// Need to do this here because it's the only way to hook into potion ending both client- and server-side
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
public class PotionDiamondflesh extends PotionMagicEffect {
|
||||
|
||||
public PotionDiamondflesh(boolean isBadEffect, int liquidColour) {
|
||||
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/diamondflesh.png"));
|
||||
// This needs to be here because registerPotionAttributeModifier doesn't like it if the potion has no name yet.
|
||||
this.setPotionName("potion." + Wizardry.MODID + ":ironflesh");
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED,
|
||||
"158a8af2-6db0-4340-a01c-a7b60d10ddf4", -0.1f, EntityUtils.Operations.MULTIPLY_CUMULATIVE);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR_TOUGHNESS,
|
||||
"a68d4532-5847-426c-9b03-d541b113cec2", 3.0f, EntityUtils.Operations.ADD);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR,
|
||||
"46a095be-82dd-43fd-8b67-13f51591eb8e", 4.0f, EntityUtils.Operations.ADD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady(int duration, int amplifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import electroblob.wizardry.constants.Constants;
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
@@ -50,4 +51,18 @@ public class PotionFrost extends PotionMagicEffect implements ICustomPotionParti
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performEffect(EntityLivingBase entitylivingbase, int strength) {
|
||||
if (entitylivingbase.isBurning()) {
|
||||
if (entitylivingbase.isPotionActive(WizardryPotions.frost)) {
|
||||
entitylivingbase.removePotionEffect(WizardryPotions.frost);
|
||||
entitylivingbase.extinguish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady(int duration, int amplifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
public class PotionIronflesh extends PotionMagicEffect {
|
||||
|
||||
public PotionIronflesh(boolean isBadEffect, int liquidColour) {
|
||||
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/ironflesh.png"));
|
||||
// This needs to be here because registerPotionAttributeModifier doesn't like it if the potion has no name yet.
|
||||
this.setPotionName("potion." + Wizardry.MODID + ":ironflesh");
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED,
|
||||
"fe607d55-50e3-4f4f-a959-6571503f92f4", -0.1f, EntityUtils.Operations.MULTIPLY_CUMULATIVE);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.KNOCKBACK_RESISTANCE,
|
||||
"6f78206e-8dd4-4d44-9792-d7a882111951", 0.3f, EntityUtils.Operations.ADD);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR,
|
||||
"e1adff1e-8510-4a09-96ed-ef677cad20c1", 4.0f, EntityUtils.Operations.ADD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady(int duration, int amplifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package electroblob.wizardry.potion;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.util.EntityUtils;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
public class PotionOakflesh extends PotionMagicEffect {
|
||||
|
||||
public PotionOakflesh(boolean isBadEffect, int liquidColour) {
|
||||
super(isBadEffect, liquidColour, new ResourceLocation(Wizardry.MODID, "textures/gui/potion_icons/oakflesh.png"));
|
||||
// This needs to be here because registerPotionAttributeModifier doesn't like it if the potion has no name yet.
|
||||
this.setPotionName("potion." + Wizardry.MODID + ":ironflesh");
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.MOVEMENT_SPEED,
|
||||
"98b4ba66-7c50-4a4c-9f3f-40bcb37313b5", -0.1f, EntityUtils.Operations.MULTIPLY_CUMULATIVE);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.MAX_HEALTH,
|
||||
"ed9d0423-60f4-4998-bd8d-dc7c33bd45b8", 0.2f, EntityUtils.Operations.MULTIPLY_FLAT);
|
||||
this.registerPotionAttributeModifier(SharedMonsterAttributes.ARMOR,
|
||||
"0b607c3f-fb14-43d7-96b5-1c1b6f6da242", 3.0f, EntityUtils.Operations.ADD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady(int duration, int amplifier) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -359,7 +359,7 @@ public final class Spells {
|
||||
registry.register(new GreaterHeal());
|
||||
registry.register(new SpellConstruct<>("healing_aura", SpellActions.POINT_DOWN, EntityHealAura::new, false).addProperties(Spell.EFFECT_RADIUS, Spell.DAMAGE, Spell.HEALTH));
|
||||
registry.register(new Forcefield());
|
||||
registry.register(new SpellBuff("ironflesh", 0.4f, 0.5f, 0.6f, () -> MobEffects.RESISTANCE).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new SpellBuff("ironflesh", 0.4f, 0.5f, 0.6f, () -> WizardryPotions.ironflesh).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new Transience());
|
||||
|
||||
registry.register(new Meteor());
|
||||
@@ -378,9 +378,10 @@ public final class Spells {
|
||||
registry.register(new SpellMinion<>("silverfish_swarm", EntitySilverfishMinion::new).soundValues(1, 1.1f, 0.1f));
|
||||
registry.register(new SpellConstructRanged<>("black_hole", EntityBlackHole::new, false).addProperties(Spell.EFFECT_RADIUS).soundValues(2, 0.7f, 0));
|
||||
registry.register(new Shockwave());
|
||||
registry.register(new SummonIronGolem());
|
||||
registry.register(new SpellMinion<>("summon_iron_golem", EntitySpectralGolem::new).soundValues(1, 1.1f, 0.1f));
|
||||
|
||||
registry.register(new ArrowRain());
|
||||
registry.register(new SpellBuff("diamondflesh", 0.1f, 0.7f, 1, () -> MobEffects.RESISTANCE).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new SpellBuff("diamondflesh", 0.1f, 0.7f, 1, () -> WizardryPotions.diamondflesh).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new SpellBuff("font_of_vitality", 1, 0.8f, 0.3f, () -> MobEffects.ABSORPTION, () -> MobEffects.REGENERATION).soundValues(0.7f, 1.2f, 0.4f));
|
||||
|
||||
// Wizardry 1.1 spells
|
||||
@@ -398,7 +399,7 @@ public final class Spells {
|
||||
registry.register(new PocketWorkbench());
|
||||
registry.register(new ImbueWeapon());
|
||||
registry.register(new InvigoratingPresence());
|
||||
registry.register(new SpellBuff("oakflesh", 0.6f, 0.5f, 0.4f, () -> MobEffects.RESISTANCE).soundValues(0.7f, 1.2f, 0.4f));
|
||||
registry.register(new SpellBuff("oakflesh", 0.6f, 0.5f, 0.4f, () -> WizardryPotions.oakflesh).soundValues(0.7f, 1.2f, 0.4f));
|
||||
|
||||
registry.register(new SpellProjectile<>("greater_fireball", EntityLargeMagicFireball::new).addProperties(Spell.DAMAGE, EntityLargeMagicFireball.EXPLOSION_POWER));//new GreaterFireball());
|
||||
registry.register(new FlamingWeapon());
|
||||
|
||||
@@ -88,6 +88,7 @@ public class WizardryEntities {
|
||||
registry.register(createEntry(EntitySpiritHorse.class, "spirit_horse", TrackingType.LIVING).egg(0x5464c6, 0xbcc2e8).build());
|
||||
registry.register(createEntry(EntityPhoenix.class, "phoenix", TrackingType.LIVING).egg(0xff4900, 0xfde535).build());
|
||||
registry.register(createEntry(EntityIceGiant.class, "ice_giant", TrackingType.LIVING).egg(0x5bacd9, 0xeffaff).build());
|
||||
registry.register(createEntry(EntitySpectralGolem.class, "spectral_golem", TrackingType.LIVING).egg(0x5bacd9, 0xeffaff).build());
|
||||
|
||||
registry.register(createEntry(EntityMagicSlime.class, "magic_slime", TrackingType.LIVING).build());
|
||||
registry.register(createEntry(EntityDecoy.class, "decoy", TrackingType.LIVING).build());
|
||||
@@ -113,6 +114,7 @@ public class WizardryEntities {
|
||||
registry.register(createEntry(EntityDart.class, "dart", TrackingType.PROJECTILE).build());
|
||||
registry.register(createEntry(EntityIceLance.class, "ice_lance", TrackingType.PROJECTILE).build());
|
||||
registry.register(createEntry(EntityFlamecatcherArrow.class, "flamecatcher_arrow", TrackingType.PROJECTILE).build());
|
||||
registry.register(createEntry(EntityConjuredArrow.class, "conjured_arrow", TrackingType.PROJECTILE).build());
|
||||
|
||||
// Directionless projectiles
|
||||
registry.register(createEntry(EntityFirebomb.class, "firebomb", TrackingType.PROJECTILE).build());
|
||||
|
||||
@@ -6,7 +6,11 @@ import electroblob.wizardry.loot.RandomSpell;
|
||||
import electroblob.wizardry.loot.WizardSpell;
|
||||
import net.minecraft.entity.EnumCreatureType;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.storage.loot.*;
|
||||
import net.minecraft.world.storage.loot.LootEntry;
|
||||
import net.minecraft.world.storage.loot.LootEntryTable;
|
||||
import net.minecraft.world.storage.loot.LootPool;
|
||||
import net.minecraft.world.storage.loot.LootTableList;
|
||||
import net.minecraft.world.storage.loot.RandomValueRange;
|
||||
import net.minecraft.world.storage.loot.conditions.LootCondition;
|
||||
import net.minecraft.world.storage.loot.functions.LootFunctionManager;
|
||||
import net.minecraftforge.event.LootTableLoadEvent;
|
||||
@@ -90,23 +94,27 @@ public final class WizardryLoot {
|
||||
event.getTable().addPool(getAdditive(Wizardry.MODID + ":chests/jungle_dispenser_additions", Wizardry.MODID + "_additional_dispenser_loot"));
|
||||
}
|
||||
// Mob drops
|
||||
// Let's hope mods will play nice and store their entity loot tables under 'entities' or 'entity'
|
||||
// If not, packmakers will have to sort it out themselves using the whitelist/blacklist
|
||||
if(Arrays.asList(Wizardry.settings.mobLootTableWhitelist).contains(event.getName())){
|
||||
event.getTable().addPool(getAdditive(Wizardry.MODID + ":entities/mob_additions", Wizardry.MODID + "_additional_mob_drops"));
|
||||
|
||||
}else if(!Arrays.asList(Wizardry.settings.mobLootTableBlacklist).contains(event.getName())
|
||||
&& event.getName().getPath().contains("entities") || event.getName().getPath().contains("entity")){
|
||||
// Get the filename of the loot table json, for well-behaved mods this will be the entity name
|
||||
String[] split = event.getName().getPath().split("/");
|
||||
String entityName = split[split.length - 1];
|
||||
|
||||
EntityEntry entry = ForgeRegistries.ENTITIES.getValue(new ResourceLocation(entityName));
|
||||
if(entry == null) return; // If this is true it didn't work :(
|
||||
Class entityClass = entry.getEntityClass();
|
||||
|
||||
if(EnumCreatureType.MONSTER.getCreatureClass().isAssignableFrom(entityClass)){
|
||||
if (Wizardry.settings.injectMobDrops) {
|
||||
// Let's hope mods will play nice and store their entity loot tables under 'entities' or 'entity'
|
||||
// If not, packmakers will have to sort it out themselves using the whitelist/blacklist
|
||||
if (Arrays.asList(Wizardry.settings.mobLootTableWhitelist).contains(event.getName())) {
|
||||
event.getTable().addPool(getAdditive(Wizardry.MODID + ":entities/mob_additions", Wizardry.MODID + "_additional_mob_drops"));
|
||||
|
||||
} else if (!Arrays.asList(Wizardry.settings.mobLootTableBlacklist).contains(event.getName())
|
||||
&& event.getName().getPath().contains("entities") || event.getName().getPath().contains("entity")) {
|
||||
// Get the filename of the loot table json, for well-behaved mods this will be the entity name
|
||||
String[] split = event.getName().getPath().split("/");
|
||||
String entityName = split[split.length - 1];
|
||||
|
||||
EntityEntry entry = ForgeRegistries.ENTITIES.getValue(new ResourceLocation(entityName));
|
||||
if (entry == null) {
|
||||
return; // If this is true it didn't work :(
|
||||
}
|
||||
Class entityClass = entry.getEntityClass();
|
||||
|
||||
if (EnumCreatureType.MONSTER.getCreatureClass().isAssignableFrom(entityClass)) {
|
||||
event.getTable().addPool(getAdditive(Wizardry.MODID + ":entities/mob_additions", Wizardry.MODID + "_additional_mob_drops"));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fishing loot
|
||||
|
||||
@@ -57,6 +57,9 @@ public final class WizardryPotions {
|
||||
public static final Potion frost_step = placeholder();
|
||||
public static final Potion mark_of_sacrifice = placeholder();
|
||||
public static final Potion mirage = placeholder();
|
||||
public static final Potion oakflesh = placeholder();
|
||||
public static final Potion ironflesh = placeholder();
|
||||
public static final Potion diamondflesh = placeholder();
|
||||
|
||||
/**
|
||||
* Sets both the registry and unlocalised names of the given potion, then registers it with the given registry. Use
|
||||
@@ -201,6 +204,10 @@ public final class WizardryPotions {
|
||||
public void spawnCustomParticle(World world, double x, double y, double z){} // We only want the syncing
|
||||
}.setBeneficial());
|
||||
|
||||
registerPotion(registry, "oakflesh", new PotionOakflesh(false, 0).setBeneficial());
|
||||
registerPotion(registry, "ironflesh", new PotionIronflesh(false, 0).setBeneficial());
|
||||
registerPotion(registry, "diamondflesh", new PotionDiamondflesh(false, 0).setBeneficial());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,7 +33,7 @@ public class ConjureBlock extends SpellRay {
|
||||
@Override
|
||||
protected boolean onBlockHit(World world, BlockPos pos, EnumFacing side, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
||||
|
||||
if(caster.isSneaking() && world.getBlockState(pos).getBlock() == WizardryBlocks.spectral_block){
|
||||
if(caster != null && caster.isSneaking() && world.getBlockState(pos).getBlock() == WizardryBlocks.spectral_block){
|
||||
|
||||
if(!world.isRemote){
|
||||
// Dispelling of blocks
|
||||
|
||||
@@ -53,7 +53,7 @@ public class CurseOfSoulbinding extends SpellRay {
|
||||
|
||||
@Override
|
||||
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
||||
|
||||
|
||||
if(EntityUtils.isLiving(target) && caster instanceof EntityPlayer){
|
||||
WizardData data = WizardData.get((EntityPlayer)caster);
|
||||
if(data != null){
|
||||
@@ -66,7 +66,7 @@ public class CurseOfSoulbinding extends SpellRay {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ public class CurseOfSoulbinding extends SpellRay {
|
||||
protected boolean onMiss(World world, EntityLivingBase caster, Vec3d origin, Vec3d direction, int ticksInUse, SpellModifiers modifiers){
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void spawnParticle(World world, double x, double y, double z, double vx, double vy, double vz){
|
||||
ParticleBuilder.create(Type.DARK_MAGIC).pos(x, y, z).clr(0.4f, 0, 0).spawn(world);
|
||||
@@ -103,9 +103,9 @@ public class CurseOfSoulbinding extends SpellRay {
|
||||
|
||||
Entity entity = EntityUtils.getEntityByUUID(player.world, iterator.next());
|
||||
|
||||
if(entity == null) iterator.remove();
|
||||
|
||||
if(entity instanceof EntityLivingBase){
|
||||
if (entity == null || (entity instanceof EntityLivingBase && !((EntityLivingBase) entity).isPotionActive(WizardryPotions.curse_of_soulbinding))) {
|
||||
iterator.remove();
|
||||
} else if (entity instanceof EntityLivingBase) {
|
||||
// Retaliatory effect
|
||||
if(DamageSafetyChecker.attackEntitySafely(entity, MagicDamage.causeDirectMagicDamage(player,
|
||||
MagicDamage.DamageType.MAGIC, true), event.getAmount(), event.getSource().getDamageType(),
|
||||
|
||||
@@ -5,6 +5,7 @@ import electroblob.wizardry.constants.Constants;
|
||||
import electroblob.wizardry.entity.living.ISpellCaster;
|
||||
import electroblob.wizardry.event.SpellCastEvent;
|
||||
import electroblob.wizardry.item.SpellActions;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
@@ -24,11 +25,14 @@ import javax.annotation.Nullable;
|
||||
@Mod.EventBusSubscriber
|
||||
public class EmpoweringPresence extends SpellAreaEffect {
|
||||
|
||||
/** The fraction by which potency is increased per level of the empowerment effect. */
|
||||
public static final String POTENCY_PER_LEVEL = "potency_per_level";
|
||||
|
||||
public EmpoweringPresence(){
|
||||
super("empowering_presence", SpellActions.POINT_UP, false);
|
||||
this.alwaysSucceed(true);
|
||||
this.targetAllies(true);
|
||||
addProperties(EFFECT_DURATION, EFFECT_STRENGTH);
|
||||
addProperties(EFFECT_DURATION, EFFECT_STRENGTH, POTENCY_PER_LEVEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,7 +66,7 @@ public class EmpoweringPresence extends SpellAreaEffect {
|
||||
if(event.getCaster() != null && event.getCaster().isPotionActive(WizardryPotions.empowerment)
|
||||
&& !(event.getSpell() instanceof EmpoweringPresence)){ // Prevent exponential empowerment stacking!
|
||||
|
||||
float potency = 1 + Constants.EMPOWERMENT_POTENCY_PER_LEVEL
|
||||
float potency = 1 + Spells.empowering_presence.getProperty(POTENCY_PER_LEVEL).floatValue()
|
||||
* (event.getCaster().getActivePotionEffect(WizardryPotions.empowerment).getAmplifier() + 1);
|
||||
|
||||
event.getModifiers().set(SpellModifiers.POTENCY,
|
||||
|
||||
@@ -53,7 +53,7 @@ public class FireBreath extends SpellRay {
|
||||
this.getNameForTranslationFormatted()), true);
|
||||
// This now only damages in line with the maxHurtResistantTime. Some mods don't play nicely and fiddle
|
||||
// with this mechanic for their own purposes, so this line makes sure that doesn't affect wizardry.
|
||||
}else if(ticksInUse % ((EntityLivingBase)target).maxHurtResistantTime == 1){
|
||||
}else if(ticksInUse % 10 == 0){
|
||||
target.setFire((int)(getProperty(BURN_DURATION).floatValue() * modifiers.get(WizardryItems.duration_upgrade)));
|
||||
EntityUtils.attackEntityWithoutKnockback(target,
|
||||
MagicDamage.causeDirectMagicDamage(caster, DamageType.FIRE),
|
||||
|
||||
@@ -56,7 +56,7 @@ public class FlameRay extends SpellRay {
|
||||
this.getNameForTranslationFormatted()), true);
|
||||
// This now only damages in line with the maxHurtResistantTime. Some mods don't play nicely and fiddle
|
||||
// with this mechanic for their own purposes, so this line makes sure that doesn't affect wizardry.
|
||||
}else if(ticksInUse % ((EntityLivingBase)target).maxHurtResistantTime == 1){
|
||||
}else if(ticksInUse % 10 == 0){
|
||||
target.setFire((int)(getProperty(BURN_DURATION).floatValue() * modifiers.get(WizardryItems.duration_upgrade)));
|
||||
EntityUtils.attackEntityWithoutKnockback(target,
|
||||
MagicDamage.causeDirectMagicDamage(caster, DamageType.FIRE),
|
||||
|
||||
@@ -59,18 +59,19 @@ public class FrostRay extends SpellRay {
|
||||
this.getNameForTranslationFormatted()), true);
|
||||
// This now only damages in line with the maxHurtResistantTime. Some mods don't play nicely and fiddle
|
||||
// with this mechanic for their own purposes, so this line makes sure that doesn't affect wizardry.
|
||||
}else if(ticksInUse % ((EntityLivingBase)target).maxHurtResistantTime == 1){
|
||||
}else{
|
||||
// For frost ray the entity can move slightly, unlike freeze
|
||||
((EntityLivingBase)target).addPotionEffect(new PotionEffect(WizardryPotions.frost,
|
||||
(int)(getProperty(EFFECT_DURATION).floatValue() * modifiers.get(WizardryItems.duration_upgrade)),
|
||||
getProperty(EFFECT_STRENGTH).intValue()));
|
||||
|
||||
float damage = getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY);
|
||||
if(target instanceof EntityBlaze || target instanceof EntityMagmaCube) damage *= 2;
|
||||
|
||||
EntityUtils.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster,
|
||||
DamageType.FROST), damage);
|
||||
if(ticksInUse % 10 == 0){
|
||||
float damage = getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY);
|
||||
if(target instanceof EntityBlaze || target instanceof EntityMagmaCube) damage *= 2;
|
||||
|
||||
EntityUtils.attackEntityWithoutKnockback(target, MagicDamage.causeDirectMagicDamage(caster,
|
||||
DamageType.FROST), damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
@@ -24,14 +25,14 @@ public class Glide extends Spell {
|
||||
|
||||
@Override
|
||||
protected void playSound(World world, EntityLivingBase entity, int ticksInUse, int duration, SpellModifiers modifiers, String... sounds){
|
||||
if(ticksInUse == 0 && world.isRemote) Wizardry.proxy.playSpellSoundLoop(entity, this, this.sounds[0], this.sounds[0], this.sounds[0],
|
||||
if(ticksInUse == 0 && world.isRemote) Wizardry.proxy.playSpellSoundLoop(entity, this, this.sounds[0], this.sounds[0], SoundEvents.UI_TOAST_OUT,
|
||||
WizardrySounds.SPELLS, volume, pitch + pitchVariation * (world.rand.nextFloat() - 0.5f));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void playSound(World world, double x, double y, double z, int ticksInUse, int duration, SpellModifiers modifiers, String... sounds){
|
||||
if(ticksInUse == 0 && world.isRemote){
|
||||
Wizardry.proxy.playSpellSoundLoop(world, x, y, z, this, this.sounds[0], this.sounds[0], this.sounds[0],
|
||||
Wizardry.proxy.playSpellSoundLoop(world, x, y, z, this, this.sounds[0], this.sounds[0], SoundEvents.UI_TOAST_OUT,
|
||||
WizardrySounds.SPELLS, volume, pitch + pitchVariation * (world.rand.nextFloat() - 0.5f), duration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class LifeDrain extends SpellRay {
|
||||
|
||||
if(EntityUtils.isLiving(target)){
|
||||
|
||||
if(ticksInUse % 12 == 0){
|
||||
if(ticksInUse % 10 == 0){
|
||||
|
||||
float damage = getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY);
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ public class LightningRay extends SpellRay {
|
||||
this.getNameForTranslationFormatted()), true);
|
||||
// This now only damages in line with the maxHurtResistantTime. Some mods don't play nicely and fiddle
|
||||
// with this mechanic for their own purposes, so this line makes sure that doesn't affect wizardry.
|
||||
}else if(ticksInUse % ((EntityLivingBase)target).maxHurtResistantTime == 1){
|
||||
}else if(ticksInUse % 10 == 0){
|
||||
EntityUtils.attackEntityWithoutKnockback(target,
|
||||
MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
|
||||
getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY));
|
||||
|
||||
@@ -53,7 +53,7 @@ public class LightningWeb extends SpellRay {
|
||||
@Override
|
||||
protected boolean onEntityHit(World world, Entity target, Vec3d hit, EntityLivingBase caster, Vec3d origin, int ticksInUse, SpellModifiers modifiers){
|
||||
|
||||
if(EntityUtils.isLiving(target)){
|
||||
if(EntityUtils.isLiving(target) && ticksInUse % 10 == 0){
|
||||
|
||||
electrocute(world, caster, origin, target, getProperty(PRIMARY_DAMAGE).floatValue()
|
||||
* modifiers.get(SpellModifiers.POTENCY), ticksInUse);
|
||||
|
||||
@@ -63,7 +63,7 @@ public class MarkSacrifice extends SpellRay {
|
||||
PotionEffect effect = event.getEntityLiving().getActivePotionEffect(WizardryPotions.mark_of_sacrifice);
|
||||
|
||||
if(effect != null && event.getSource().isMagicDamage()){
|
||||
event.setAmount(event.getAmount() * (1 + effect.getAmplifier() * DAMAGE_INCREASE_PER_LEVEL));
|
||||
event.setAmount(event.getAmount() * (1 + (1 + effect.getAmplifier()) * DAMAGE_INCREASE_PER_LEVEL));
|
||||
event.getEntityLiving().removePotionEffect(WizardryPotions.mark_of_sacrifice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,6 +111,9 @@ public class MindControl extends SpellRay {
|
||||
|
||||
/** 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(Entity target){
|
||||
|
||||
// TODO: Add a max health limit that scales with potency
|
||||
|
||||
return target instanceof EntityLiving && target.isNonBoss() && !(target instanceof INpc)
|
||||
&& !(target instanceof EntityEvilWizard) && !Arrays.asList(Wizardry.settings.mindControlTargetsBlacklist)
|
||||
.contains(EntityList.getKey(target.getClass()));
|
||||
|
||||
@@ -30,9 +30,14 @@ public class Paralysis extends SpellRay {
|
||||
* will end. */
|
||||
private static final String CRITICAL_HEALTH = "critical_health";
|
||||
|
||||
/**
|
||||
* Multiplier for affecting players
|
||||
*/
|
||||
private static final String PLAYER_EFFECT_DURATION_MULTIPLIER = "player_effect_duration_multiplier";
|
||||
|
||||
public Paralysis(){
|
||||
super("paralysis", SpellActions.POINT, false);
|
||||
addProperties(DAMAGE, EFFECT_DURATION, CRITICAL_HEALTH);
|
||||
addProperties(DAMAGE, EFFECT_DURATION, CRITICAL_HEALTH, PLAYER_EFFECT_DURATION_MULTIPLIER);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,9 +62,10 @@ public class Paralysis extends SpellRay {
|
||||
target.attackEntityFrom(MagicDamage.causeDirectMagicDamage(caster, DamageType.SHOCK),
|
||||
getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY));
|
||||
}
|
||||
|
||||
|
||||
float durationMultiplier = target instanceof EntityPlayer ? modifiers.get(PLAYER_EFFECT_DURATION_MULTIPLIER) : 1.0f;
|
||||
((EntityLivingBase)target).addPotionEffect(new PotionEffect(WizardryPotions.paralysis,
|
||||
(int)(getProperty(EFFECT_DURATION).floatValue() * modifiers.get(WizardryItems.duration_upgrade)), 0));
|
||||
(int)(getProperty(EFFECT_DURATION).floatValue() * durationMultiplier * modifiers.get(WizardryItems.duration_upgrade)), 0));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -58,7 +58,7 @@ public class RayOfPurification extends SpellRay {
|
||||
if(!world.isRemote && ticksInUse == 1 && caster instanceof EntityPlayer) ((EntityPlayer)caster)
|
||||
.sendStatusMessage(new TextComponentTranslation("spell.resist", target.getName(),
|
||||
this.getNameForTranslationFormatted()), true);
|
||||
}else{
|
||||
}else if (ticksInUse % 10 == 0) {
|
||||
|
||||
float damage = getProperty(DAMAGE).floatValue() * modifiers.get(SpellModifiers.POTENCY);
|
||||
// Fire
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package electroblob.wizardry.spell;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.data.WizardData;
|
||||
import electroblob.wizardry.event.ResurrectionEvent;
|
||||
import electroblob.wizardry.item.ISpellCastingItem;
|
||||
import electroblob.wizardry.item.SpellActions;
|
||||
import electroblob.wizardry.packet.PacketResurrection;
|
||||
@@ -8,6 +10,7 @@ import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import electroblob.wizardry.registry.Spells;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
@@ -16,11 +19,16 @@ import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
@EventBusSubscriber
|
||||
public class Resurrection extends Spell {
|
||||
|
||||
public static final String WAIT_TIME = "wait_time";
|
||||
@@ -55,6 +63,9 @@ public class Resurrection extends Spell {
|
||||
.orElse(null);
|
||||
|
||||
if(nearestDeadAlly != null){
|
||||
|
||||
if(MinecraftForge.EVENT_BUS.post(new ResurrectionEvent(nearestDeadAlly, caster))) return false;
|
||||
|
||||
// When the player entity dies, it is removed from world#loadedEntityList. However, it is NOT removed
|
||||
// from playerEntityList (and probably a few other places) until respawn is clicked, and since that
|
||||
// never happens here we need to clean up those references or the player will have duplicate entries
|
||||
@@ -112,4 +123,42 @@ public class Resurrection extends Spell {
|
||||
&& ((ISpellCastingItem)stack.getItem()).canCast(stack, Spells.resurrection, player, EnumHand.MAIN_HAND, 0, new SpellModifiers());
|
||||
}
|
||||
|
||||
}
|
||||
@SubscribeEvent
|
||||
public static void onPlayerTickEvent(LivingUpdateEvent event){
|
||||
|
||||
if(event.getEntity() instanceof EntityPlayer){
|
||||
|
||||
EntityPlayer player = (EntityPlayer)event.getEntity();
|
||||
|
||||
if(player.world.isRemote && !player.isEntityAlive()){
|
||||
|
||||
EntityPlayer firstPersonPlayer = Wizardry.proxy.getThePlayer();
|
||||
|
||||
if(WizardData.get(firstPersonPlayer).isPlayerAlly(player)){
|
||||
|
||||
ItemStack wand = firstPersonPlayer.getHeldItemMainhand();
|
||||
|
||||
if(!(wand.getItem() instanceof ISpellCastingItem)){
|
||||
wand = firstPersonPlayer.getHeldItemOffhand();
|
||||
if(!(wand.getItem() instanceof ISpellCastingItem)) return;
|
||||
}
|
||||
|
||||
if(((ISpellCastingItem)wand.getItem()).getCurrentSpell(wand) == Spells.resurrection){
|
||||
|
||||
// TODO: Find some way of getting at the modifiers before the spell is cast
|
||||
int waitTime = Spells.resurrection.getProperty(WAIT_TIME).intValue();
|
||||
|
||||
if(player.deathTime > waitTime){
|
||||
ParticleBuilder.create(Type.SPARKLE, player.world.rand, player.posX, player.posY + 0.5, player.posZ, 0.5, false)
|
||||
.clr(1, 1, 0.3f).vel(0, 0.02, 0).spawn(player.world);
|
||||
}else{
|
||||
ParticleBuilder.create(Type.DUST, player.world.rand, player.posX, player.posY + 0.5, player.posZ, 0.5, false)
|
||||
.clr(1, 1, 0.3f).vel(0, 0.02, 0).time(50).spawn(player.world);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -189,7 +189,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
||||
private static int nextSpellId = 0;
|
||||
/** The spell's integer ID, mainly used for networking. */
|
||||
// This was added after I learnt the hard way why you can't assume Forge's registry IDs are sequential...
|
||||
private final int id;
|
||||
private int id;
|
||||
|
||||
/**
|
||||
* This constructor should be called from any subclasses, either feeding in the constants directly or through their
|
||||
@@ -225,6 +225,7 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
||||
this.icon = new ResourceLocation(modID, "textures/spells/" + name + ".png");
|
||||
this.sounds = createSounds();
|
||||
this.id = nextSpellId++;
|
||||
Wizardry.logger.debug("Registering spell " + this.unlocalisedName +" with networkID " + id);
|
||||
this.items(WizardryItems.spell_book, WizardryItems.scroll);
|
||||
this.npcSelector((e, o) -> false);
|
||||
}
|
||||
@@ -560,6 +561,11 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
||||
return id;
|
||||
}
|
||||
|
||||
/** Sets the networkID of this spell. Do not call this or it will cause all packets to fail. */
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
/** Returns the {@code ResourceLocation} for this spell's icon. */
|
||||
public final ResourceLocation getIcon(){
|
||||
return icon;
|
||||
@@ -916,6 +922,11 @@ public abstract class Spell extends IForgeRegistryEntry.Impl<Spell> implements C
|
||||
return Arrays.asList(applicableItems).contains(item);
|
||||
}
|
||||
|
||||
/** Returns the list of items this spell is applicable to. */
|
||||
public List<Item> getApplicableItems() {
|
||||
return Arrays.asList(applicableItems);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets which items this spell can appear on (these default to the regular spell book and scroll).
|
||||
* @param applicableItems The items this spell should naturally appear on (or no items at all).
|
||||
|
||||
@@ -125,7 +125,8 @@ public class SpellBuff extends Spell {
|
||||
@Override
|
||||
public boolean cast(World world, EntityLiving caster, EnumHand hand, int ticksInUse, EntityLivingBase target, SpellModifiers modifiers){
|
||||
// Wizards can only cast a buff spell if they don't already have its effects.
|
||||
if(caster.getActivePotionMap().keySet().containsAll(potionSet)) return false;
|
||||
// Some buff spells doesn't add any potion effects, those are ignored by this check
|
||||
if(!potionSet.isEmpty() && caster.getActivePotionMap().keySet().containsAll(potionSet)) return false;
|
||||
// Only return on the server side or the client probably won't spawn particles
|
||||
if(!this.applyEffects(caster, modifiers) && !world.isRemote) return false;
|
||||
if(world.isRemote) this.spawnParticles(world, caster, modifiers);
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
package electroblob.wizardry.spell;
|
||||
|
||||
import electroblob.wizardry.item.SpellActions;
|
||||
import electroblob.wizardry.util.BlockUtils;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import electroblob.wizardry.util.SpellModifiers;
|
||||
import net.minecraft.entity.monster.EntityIronGolem;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class SummonIronGolem extends Spell {
|
||||
|
||||
public SummonIronGolem(){
|
||||
super("summon_iron_golem", SpellActions.SUMMON, false);
|
||||
addProperties(SpellMinion.SUMMON_RADIUS);
|
||||
soundValues(1, 1.1f, 0.2f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cast(World world, EntityPlayer caster, EnumHand hand, int ticksInUse, SpellModifiers modifiers){
|
||||
|
||||
BlockPos pos = BlockUtils.findNearbyFloorSpace(caster, getProperty(SpellMinion.SUMMON_RADIUS).intValue(),
|
||||
getProperty(SpellMinion.SUMMON_RADIUS).intValue());
|
||||
|
||||
if(pos == null) return false;
|
||||
|
||||
if(!world.isRemote){
|
||||
|
||||
EntityIronGolem golem = new EntityIronGolem(world);
|
||||
golem.setPosition(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5);
|
||||
golem.setPlayerCreated(true);
|
||||
world.spawnEntity(golem);
|
||||
|
||||
}else{
|
||||
|
||||
for(int i=0; i<10; i++){
|
||||
double x = pos.getX() + world.rand.nextDouble() * 2 - 1;
|
||||
double y = pos.getY() + 0.5 + world.rand.nextDouble();
|
||||
double z = pos.getZ() + world.rand.nextDouble() * 2 - 1;
|
||||
ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).clr(0.6f, 0.6f, 1).spawn(world);
|
||||
}
|
||||
}
|
||||
|
||||
this.playSound(world, caster, ticksInUse, -1, modifiers);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package electroblob.wizardry.tileentity;
|
||||
|
||||
import electroblob.wizardry.block.BlockReceptacle;
|
||||
import electroblob.wizardry.constants.Element;
|
||||
import electroblob.wizardry.event.ImbuementActivateEvent;
|
||||
import electroblob.wizardry.item.IManaStoringItem;
|
||||
import electroblob.wizardry.item.ItemWizardArmour;
|
||||
import electroblob.wizardry.registry.*;
|
||||
@@ -24,6 +25,7 @@ import net.minecraft.world.World;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraft.world.storage.loot.LootContext;
|
||||
import net.minecraft.world.storage.loot.LootTable;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@@ -233,6 +235,14 @@ public class TileEntityImbuementAltar extends TileEntity implements ITickable {
|
||||
*/
|
||||
public static ItemStack getImbuementResult(ItemStack input, Element[] receptacleElements, boolean fullLootGen, World world, EntityPlayer lastUser){
|
||||
|
||||
ItemStack eventResult = ItemStack.EMPTY;
|
||||
|
||||
if (world != null && MinecraftForge.EVENT_BUS.post(new ImbuementActivateEvent(input, receptacleElements, world, lastUser, eventResult))) {
|
||||
// return the stack if something changes the result from an empty stack.
|
||||
//noinspection ConstantConditions
|
||||
if (eventResult != ItemStack.EMPTY) return eventResult;
|
||||
}
|
||||
|
||||
if(input.getItem() instanceof ItemWizardArmour && ((ItemWizardArmour)input.getItem()).element == null){
|
||||
|
||||
if(Arrays.stream(receptacleElements).distinct().count() == 1 && receptacleElements[0] != null){ // All the same element
|
||||
|
||||
@@ -201,7 +201,7 @@ public final class AllyDesignationSystem {
|
||||
// Owned entities inherit their owner's allies
|
||||
if(allyOf instanceof IEntityOwnable){
|
||||
Entity owner = ((IEntityOwnable)allyOf).getOwner();
|
||||
if(owner instanceof EntityLivingBase && isAllied((EntityLivingBase)owner, possibleAlly)) return true;
|
||||
if(owner instanceof EntityLivingBase && (owner == possibleAlly || isAllied((EntityLivingBase)owner, possibleAlly))) return true;
|
||||
}
|
||||
|
||||
if(allyOf instanceof EntityPlayer && possibleAlly instanceof EntityPlayer
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package electroblob.wizardry.util;
|
||||
|
||||
import electroblob.wizardry.Settings;
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.entity.living.*;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.boss.EntityDragon;
|
||||
@@ -195,7 +197,7 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage
|
||||
* @return A damagesource object of type EntityDamageSource
|
||||
*/
|
||||
public static DamageSource causeDirectMagicDamage(Entity caster, DamageType type, boolean isRetaliatory){
|
||||
return new MagicDamage(DIRECT_MAGIC_DAMAGE, caster, type, isRetaliatory);
|
||||
return new MagicDamage(getDirectDamageNameForType(type), caster, type, isRetaliatory);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,7 +243,15 @@ public class MagicDamage extends EntityDamageSource implements IElementalDamage
|
||||
*/
|
||||
public static DamageSource causeIndirectMagicDamage(Entity magic, Entity caster, DamageType type,
|
||||
boolean isRetaliatory){
|
||||
return new IndirectMagicDamage(INDIRECT_MAGIC_DAMAGE, magic, caster, type, isRetaliatory);
|
||||
return new IndirectMagicDamage(getIndirectDamageNameForType(type), magic, caster, type, isRetaliatory);
|
||||
}
|
||||
|
||||
public static String getIndirectDamageNameForType(DamageType type) {
|
||||
return Wizardry.settings.damageTypePerElement ? type.name().toLowerCase() + "_" + INDIRECT_MAGIC_DAMAGE : INDIRECT_MAGIC_DAMAGE;
|
||||
}
|
||||
|
||||
public static String getDirectDamageNameForType(DamageType type) {
|
||||
return Wizardry.settings.damageTypePerElement ? type.name().toLowerCase() + "_" + DIRECT_MAGIC_DAMAGE : DIRECT_MAGIC_DAMAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -34,7 +34,9 @@ import java.util.Random;
|
||||
* <code>ParticleBuilder.create(Type.SPARKLE).pos(x, y, z).vel(vx, vy, vz).clr(r, g, b).spawn(world);</code>
|
||||
* <p></p>
|
||||
* It also goes without saying that <b>this class should only ever be used client-side</b>. Attempting to spawn particles
|
||||
* on the server side will not work and will print a warning to the console.
|
||||
* on the server side will not work and will print a warning to the console. {@code ParticleBuilder} is not threadsafe
|
||||
* and attempting to call it from multiple threads at once will very likely cause an {@link IllegalStateException}.
|
||||
*
|
||||
* @author Electroblob
|
||||
* @since Wizardry 4.2
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package electroblob.wizardry.util;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.spell.Spell;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Helper class which ensures that all spellpack spell networkIDs are distributed in alphabetical order. Introducing this was necessary as mods (especially with
|
||||
* (load-after) dependencies were not always registering their spells in the exact same order. This is definitely
|
||||
*/
|
||||
public class SpellNetworkIDSorter {
|
||||
|
||||
public static void init() {
|
||||
|
||||
//reorder network IDs based on addon modids. This is necessary as modloading order doesn't seem to be guaranteed to match between various servers and clients
|
||||
Wizardry.logger.debug("Reordering all spell NetworkIDs based on addon modid alphabetical order");
|
||||
|
||||
// the first available ID after all default spells
|
||||
int nextSpellId = (int) Spell.getAllSpells().stream().filter(spell -> spell.getRegistryName().getNamespace().equals(Wizardry.MODID)).count() + 1;
|
||||
List<Spell> addonSpells = Spell.getAllSpells().stream().filter(spell -> !spell.getRegistryName().getNamespace().equals(Wizardry.MODID)).collect(Collectors.toList());
|
||||
|
||||
// sorting spells
|
||||
addonSpells.sort(Comparator.comparing((Spell o) -> o.getRegistryName().toString()));
|
||||
for (Spell spell : addonSpells) {
|
||||
Wizardry.logger.debug("Updating networkID of spell " + spell.getRegistryName().toString() + " from " + spell.networkID() + " to " + nextSpellId);
|
||||
spell.setId(nextSpellId++);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,6 +83,7 @@ item.ebwizardry\:arcane_tome.desc=Upgrades any %1$s wand with sufficient progres
|
||||
item.ebwizardry\:wizard_handbook.name=The Wizard's Handbook
|
||||
item.ebwizardry\:wizard_handbook.author=by %1$s
|
||||
item.ebwizardry\:wizard_handbook.desc=Your not-so-pocket-sized guide to the arcane arts! A must-have for any aspiring wizard who seeks to learn the secrets of magic.\n\nRight-click while holding this book to read it.
|
||||
item.ebwizardry\:wizard_handbook.disabled=This item was disabled in the config!
|
||||
|
||||
item.ebwizardry\:wand.generic=wand
|
||||
|
||||
@@ -402,6 +403,10 @@ item.ebwizardry\:generic.disabled=This item has been disabled in the config
|
||||
item.ebwizardry\:ring.generic.desc=Equip this ring in the Baubles inventory or by placing it on your hotbar. Up to 2 rings may be equipped at once.
|
||||
item.ebwizardry\:amulet.generic.desc=Equip this amulet in the Baubles inventory or by placing it on your hotbar. Only one amulet may be equipped at a time.
|
||||
item.ebwizardry\:charm.generic.desc=Equip this charm in the Baubles inventory or by placing it on your hotbar. Only one charm may be equipped at a time.
|
||||
item.ebwizardry\:belt.generic.desc=Equip this belt in the Baubles inventory or by placing it on your hotbar. Only one belt may be equipped at a time.
|
||||
item.ebwizardry\:body.generic.desc=Equip this body item in the Baubles inventory or by placing it on your hotbar. Only one body item may be equipped at a time.
|
||||
item.ebwizardry\:trinket.generic.desc=Equip this trinket in the Baubles inventory or by placing it on your hotbar. Only one trinklet may be equipped at a time.
|
||||
item.ebwizardry\:head.generic.desc=Equip this headgear in the Baubles inventory or by placing it on your hotbar. Only one headgear may be equipped at a time.
|
||||
|
||||
item.ebwizardry\:ring_condensing.name=Ring of Condensing
|
||||
item.ebwizardry\:ring_condensing.desc=Slowly regenerates mana for all wands on your hotbar
|
||||
@@ -438,7 +443,7 @@ item.ebwizardry\:ring_hammer.desc=Lightning hammers can be picked up and thrown
|
||||
item.ebwizardry\:ring_stormcloud.name=Lokenzen's Ring
|
||||
item.ebwizardry\:ring_stormcloud.desc=Stormcloud moves towards targets and lasts longer with every strike
|
||||
item.ebwizardry\:ring_soulbinding.name=Soulwalker's Ring
|
||||
item.ebwizardry\:ring_soulbinding.desc=Creatures damaged by necromancy spells become soulbound to you
|
||||
item.ebwizardry\:ring_soulbinding.desc=Creatures damaged by necromancy spells become soulbound to you for 20 seconds
|
||||
item.ebwizardry\:ring_leeching.name=Ring of Leeching
|
||||
item.ebwizardry\:ring_leeching.desc=All necromancy attacks have a 30%% chance to trigger a life drain effect
|
||||
item.ebwizardry\:ring_necromancy_melee.name=Ring of Necrotic Touch
|
||||
@@ -732,6 +737,7 @@ entity.ebwizardry\:evil_wizard.name=Wizard
|
||||
entity.ebwizardry\:decoy.name=Decoy
|
||||
entity.ebwizardry\:vex_minion.name=Vex
|
||||
entity.ebwizardry\:remnant.name=Remnant
|
||||
entity.ebwizardry\:spectral_golem.name=Spectral Golem
|
||||
|
||||
entity.ebwizardry\:magic_missile.name=Magic
|
||||
entity.ebwizardry\:arc.name=Magic
|
||||
@@ -758,6 +764,7 @@ entity.ebwizardry\:smoke_bomb.name=Magic
|
||||
entity.ebwizardry\:ice_spike.name=Magic
|
||||
entity.ebwizardry\:combustion_rune.name=Magic
|
||||
entity.ebwizardry\:flamecatcher_arrow.name=Magic
|
||||
entity.ebwizardry\:conjured_arrow.name=Magic
|
||||
|
||||
entity.ebwizardry\:black_hole.name=Black Hole
|
||||
entity.ebwizardry\:shield.name=Shield
|
||||
@@ -875,6 +882,7 @@ container.ebwizardry\:arcane_workbench.sort_tier=Sort by Tier
|
||||
container.ebwizardry\:arcane_workbench.sort_element=Sort by Element
|
||||
container.ebwizardry\:arcane_workbench.sort_alphabetical=Sort Alphabetically
|
||||
container.ebwizardry\:arcane_workbench.search_tooltip=%1$sSearch Tips\n\ntier=%2$s, %1$st=%2$s: match tiers\n%1$selement=%2$s, %1$se=%2$s: match elements\n%1$stype=%2$s, %1$sp=%2$s: match spell types\n%1$sdiscovered=true/false%2$s, %1$sd=t/f%2$s: include only (un)discovered\n%1$smodid=%2$s, %1$sm=%2$s: match mod IDs\n\nSeparate multiple values with %1$s,%2$s\nSeparate multiple criteria with %1$s;
|
||||
container.ebwizardry\:arcane_workbench.clear=Clear Spell Slots
|
||||
|
||||
container.ebwizardry\:bookshelf=Bookshelf
|
||||
|
||||
@@ -1075,7 +1083,7 @@ spell.ebwizardry\:stormcloud=Stormcloud
|
||||
spell.ebwizardry\:summon_blaze=Summon Blaze
|
||||
spell.ebwizardry\:summon_ice_giant=Summon Ice Giant
|
||||
spell.ebwizardry\:summon_ice_wraith=Summon Ice Wraith
|
||||
spell.ebwizardry\:summon_iron_golem=Summon Iron Golem
|
||||
spell.ebwizardry\:summon_iron_golem=Summon Spectral Golem
|
||||
spell.ebwizardry\:summon_lightning_wraith=Summon Lightning Wraith
|
||||
spell.ebwizardry\:summon_phoenix=Summon Phoenix
|
||||
spell.ebwizardry\:summon_shadow_wraith=Summon Shadow Wraith
|
||||
@@ -1203,7 +1211,7 @@ spell.ebwizardry\:intimidate.desc=Emits an intimidating growl which causes nearb
|
||||
spell.ebwizardry\:invigorating_presence.desc=Grants the caster and all nearby allies increased strength for 45 seconds.
|
||||
spell.ebwizardry\:invisibility.desc=Makes the caster invisible for 30 seconds.
|
||||
spell.ebwizardry\:invoke_weather.desc=Changes the weather in the world.
|
||||
spell.ebwizardry\:ironflesh.desc=Greatly improves the caster's damage resistance for 30 seconds.
|
||||
spell.ebwizardry\:ironflesh.desc=Greatly improves the caster's armor and knockback resistance for 30 seconds.
|
||||
spell.ebwizardry\:leap.desc=Causes the caster to jump upwards several blocks and slightly forward.
|
||||
spell.ebwizardry\:levitation.desc=Raises the caster upwards while the use item button is held. Will also negate fall damage if used before hitting the ground.
|
||||
spell.ebwizardry\:life_drain.desc=Creates a stream of withering energy in the direction you are pointing which drains the life of the target and uses it to gradually regenerate your health.
|
||||
@@ -1226,7 +1234,7 @@ spell.ebwizardry\:mine.desc=Breaks the block the caster is looking at. Potency w
|
||||
spell.ebwizardry\:mirage.desc=Creates an illusion where the caster appears to be a few blocks away from their actual position, blinking around every few seconds. The illusion lasts for 20 seconds.
|
||||
spell.ebwizardry\:muffle.desc=Silences any sounds made by the caster for 30 seconds. When muffled, mobs can only detect you when looking towards you.
|
||||
spell.ebwizardry\:none.desc=To get a spell book with the /give command, use id\: /give [player] ebwizardry\:spell_book 1 [spell id] (if you found this book in a chest, some other mod has messed things up).
|
||||
spell.ebwizardry\:oakflesh.desc=Improves the caster's damage resistance for 30 seconds.
|
||||
spell.ebwizardry\:oakflesh.desc=Slightly improves the caster's vitality and damage resistance for 30 seconds.
|
||||
spell.ebwizardry\:paralysis.desc=Delivers a powerful lightning bolt that paralyses targets for 5 seconds. Paralysed creatures cannot move and will still take damage - but too much will snap the creature out of paralysis.
|
||||
spell.ebwizardry\:permafrost.desc=Spreads a layer of slippery ice on the ground where you are pointing, the extreme cold of which causes creatures to slowly take damage.
|
||||
spell.ebwizardry\:petrify.desc=Turns the target to stone until broken out, with a chance for it to break out when it is dark. The target cannot move or do anything while petrified but is also impervious to all damage.
|
||||
@@ -1363,6 +1371,7 @@ forfeit.ebwizardry\:bury_self=The ground collapses beneath you!
|
||||
|
||||
forfeit.ebwizardry\:spill_inventory=Your items spill themselves everywhere!
|
||||
forfeit.ebwizardry\:teleport_self=You are instantly teleported somewhere!
|
||||
forfeit.ebwizardry\:teleport_self_large_distance=You are instantly teleported somewhere far away!
|
||||
forfeit.ebwizardry\:levitate_self=You begin to float upwards helplessly!
|
||||
forfeit.ebwizardry\:vex_horde=A horde of vexes materializes around you!
|
||||
forfeit.ebwizardry\:black_hole=A swirling vortex appears in front of you!
|
||||
@@ -1400,6 +1409,9 @@ potion.ebwizardry\:containment=Containment
|
||||
potion.ebwizardry\:frost_step=Frost Step
|
||||
potion.ebwizardry\:mark_of_sacrifice=Mark of Sacrifice
|
||||
potion.ebwizardry\:mirage=Mirage
|
||||
potion.ebwizardry\:oakflesh=Oakflesh
|
||||
potion.ebwizardry\:ironflesh=Ironflesh
|
||||
potion.ebwizardry\:diamondflesh=Diamondflesh
|
||||
|
||||
enchantment.ebwizardry\:magic_sword=Imbuement
|
||||
enchantment.ebwizardry\:magic_bow=Imbuement
|
||||
@@ -1436,6 +1448,25 @@ key.ebwizardry.spell_8=Spell Slot 8
|
||||
|
||||
death.attack.wizardry_magic=%1$s was killed by %2$s using magic
|
||||
death.attack.indirect_wizardry_magic=%1$s was killed by %2$s using magic
|
||||
death.attack.magic_wizardry_magic=%1$s was killed by %2$s using magic
|
||||
death.attack.magic_indirect_wizardry_magic=%1$s was killed by %2$s using magic
|
||||
|
||||
death.attack.fire_wizardry_magic=%1$s was killed by %2$s using fire magic
|
||||
death.attack.fire_indirect_wizardry_magic=%1$s was killed by %2$s using fire magic
|
||||
death.attack.frost_wizardry_magic=%1$s was killed by %2$s using frost magic
|
||||
death.attack.frost_indirect_wizardry_magic=%1$s was killed by %2$s using frost magic
|
||||
death.attack.shock_wizardry_magic=%1$s was killed by %2$s using a shock magic
|
||||
death.attack.shock_indirect_wizardry_magic=%1$s was killed by %2$s using shock magic
|
||||
death.attack.wither_wizardry_magic=%1$s was killed by %2$s using withering magic
|
||||
death.attack.wither_indirect_wizardry_magic=%1$s was killed by %2$s withering magic
|
||||
death.attack.poison_wizardry_magic=%1$s was killed by %2$s using poison magic
|
||||
death.attack.poison_indirect_wizardry_magic=%1$s was killed by %2$s poison magic
|
||||
death.attack.force_wizardry_magic=%1$s was killed by %2$s using a magical force
|
||||
death.attack.force_indirect_wizardry_magic=%1$s was killed by %2$s using magical force
|
||||
death.attack.blast_wizardry_magic=%1$s was killed by %2$s using a magical blast
|
||||
death.attack.blast_indirect_wizardry_magic=%1$s was killed by %2$s using magical blast
|
||||
death.attack.radiant_wizardry_magic=%1$s was killed by %2$s using radiant magic
|
||||
death.attack.radiant_indirect_wizardry_magic=%1$s was killed by %2$s using radiant magic
|
||||
|
||||
soundCategory.ebwizardry_spells=Spells
|
||||
|
||||
@@ -1504,6 +1535,12 @@ config.ebwizardry.player_block_damage.true=Yes - kaboom!
|
||||
config.ebwizardry.player_block_damage.false=No - activate anti-grief (TM)
|
||||
config.ebwizardry.dispenser_block_damage=Dispenser Block Damage
|
||||
config.ebwizardry.dispenser_block_damage.tooltip=Whether spells cast by dispensers can destroy blocks in the world. Wizardry makes every attempt to respect protection mods and plugins, but cannot guarantee it will work in all cases for every mod. If you need absolutely watertight anti-grief, disable this setting.
|
||||
config.ebwizardry.damage_type_per_element=Damage Type Per Element
|
||||
config.ebwizardry.damage_type_per_element.tooltip=Whether damage should be registered with the old system (wizardry_magic/indirect_wizardry_magic) prefixed damage with the elements like necromancy_indirect_wizardry_magic, necromancy_wizardry_magic. This is disabled by default to not break existing modpacks. The intention of this setting is to allow differentiating various damage types for e.g. the Distinct Damage Descriptions mod
|
||||
config.ebwizardry.single_use_spell_books=Spell Books Are Consumed By Wands
|
||||
config.ebwizardry.single_use_spell_books.tooltip=Whether spell books are consumed when they are bound to a wand.
|
||||
config.ebwizardry.prevent_binding_same_spell_twice_to_wands=Prevent Binding The Same Spell To A Wand Multiple Times
|
||||
config.ebwizardry.prevent_binding_same_spell_twice_to_wands.tooltip=Whether to prevent binding the same spell to a wand multiple times
|
||||
config.ebwizardry.telekinetic_disarmament=Telekinetic Disarmament
|
||||
config.ebwizardry.telekinetic_disarmament.tooltip=Whether to allow players to disarm other players using the telekinesis spell. Disable to prevent stealing of items.
|
||||
config.ebwizardry.telekinetic_disarmament.true=Yes - let people steal things
|
||||
@@ -1524,6 +1561,20 @@ config.ebwizardry.slow_time_affects_players=Slow Time Affects Players
|
||||
config.ebwizardry.slow_time_affects_players.tooltip=Whether players are slowed when another nearby player uses the slow time spell. If this is disabled, mobs and projectiles will still be affected but players will move at normal speed.
|
||||
config.ebwizardry.bonemeal_grows_crystal_flowers=Bonemeal Grows Crystal Flowers
|
||||
config.ebwizardry.bonemeal_grows_crystal_flowers.tooltip=Whether using bonemeal on grass blocks has a chance to grow crystal flowers.
|
||||
config.ebwizardry.wands_must_be_held_to_decrement_cooldown=Wands Must Be Held To Decrement Cooldown
|
||||
config.ebwizardry.wands_must_be_held_to_decrement_cooldown.tooltip=Whether wands only decrement their cooldowns if a player holds them.
|
||||
config.ebwizardry.cooldown_reduction_per_level=Cooldown Reduction Per Level
|
||||
config.ebwizardry.cooldown_reduction_per_level.tooltip=The fraction by which cooldowns are reduced for each level of cooldown upgrade.
|
||||
config.ebwizardry.potency_increase_per_tier=Potency Increase Per Tier
|
||||
config.ebwizardry.potency_increase_per_tier.tooltip=The fraction by which potency is increased for each tier of matching wand. May cause extreme lag with high values!
|
||||
config.ebwizardry.duration_increase_per_level=Duration Increase Per Level
|
||||
config.ebwizardry.duration_increase_per_level.tooltip=The fraction by which spell duration is increased for each level of duration upgrade.
|
||||
config.ebwizardry.range_increase_per_level=Range Increase Per Level
|
||||
config.ebwizardry.range_increase_per_level.tooltip=The fraction by which spell range is increased for each level of range upgrade. May cause extreme lag with high values!
|
||||
config.ebwizardry.blast_increase_per_level=Blast Increase Per Level
|
||||
config.ebwizardry.blast_increase_per_level.tooltip=The fraction by which spell blast is increased for each level of blast upgrade. May cause extreme lag with high values!
|
||||
config.ebwizardry.frost_slowness_increase_per_level=Frost Slowness Increase Per Level
|
||||
config.ebwizardry.frost_slowness_increase_per_level.tooltip=The fraction by which movement speed is reduced per level of frost effect.
|
||||
|
||||
config.ebwizardry.category.difficulty=Difficulty Settings
|
||||
config.ebwizardry.category.difficulty.tooltip=Configure wizardry's difficulty
|
||||
@@ -1580,6 +1631,8 @@ config.ebwizardry.mob_loot_table_whitelist=Mob Loot Table Whitelist
|
||||
config.ebwizardry.mob_loot_table_whitelist.tooltip=Whitelist for loot tables to inject additional mob drops (as specified in loot_tables/entities/mob_additions.json) into. Wizardry makes a best guess as to which loot tables belong to hostile mobs, but this may not always be correct or appropriate; add loot table locations (not entity IDs) to this list to manually include them.
|
||||
config.ebwizardry.mob_loot_table_blacklist=Mob Loot Table Blacklist
|
||||
config.ebwizardry.mob_loot_table_blacklist.tooltip=Blacklist for loot tables to inject additional mob drops (as specified in loot_tables/entities/mob_additions.json) into. Wizardry makes a best guess as to which loot tables belong to hostile mobs, but this may not always be correct or appropriate; add loot table locations (not entity IDs) to this list to manually exclude them.
|
||||
config.ebwizardry.inject_mob_drops=Allow Wizardry Mob Loot
|
||||
config.ebwizardry.inject_mob_drops.tooltip=Whether to inject Wizardry loot to mobs, based on the loot table 'Mob Loot Table Whitelist' / 'Mob Loot Table Blacklist' settings. If disabled, the lists won't have any effect!
|
||||
config.ebwizardry.mob_spawn_dimensions=Mob Spawning Dimensions
|
||||
config.ebwizardry.mob_spawn_dimensions.tooltip=List of ids of dimensions in which wizardry's hostile mobs can spawn.
|
||||
config.ebwizardry.mob_spawn_biome_blacklist=Mob Spawning Biome Blacklist
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -200,16 +200,16 @@ item.ebwizardry\:identification_scroll.desc=알 수 없는 주문서나 두루
|
||||
item.ebwizardry\:identification_scroll.desc_extended=오른쪽 버튼을 클릭하여 식별하지 않은 주문서를 식별할 수 있습니다.
|
||||
item.ebwizardry\:identification_scroll.nothing_to_identify=식별할 주문이 없습니다!
|
||||
|
||||
item.ebwizardry\:resplendent_thread.name=찬란의 실
|
||||
item.ebwizardry\:resplendent_thread.name=찬란한 실타래
|
||||
item.ebwizardry\:resplendent_thread.desc=일반적인 마법사의 갑옷을 학자의 갑옷으로 강화합니다
|
||||
item.ebwizardry\:resplendent_thread.desc_extended=희미하게 빛나는 실로 신비로운 무늬를 수놓아 로브의 질을 높이고, 마법 부여의 효과를 상승시킵니다.\n\n신비로운 작업대에서 마법사 갑옷에 이 강화를 적용할 수 있습니다.
|
||||
|
||||
item.ebwizardry\:crystal_silver_plating.name=은도금된 수정
|
||||
item.ebwizardry\:crystal_silver_plating.desc=일반적인 마법사의 갑옷을 전투법사의 갑옷으로 강화합니다
|
||||
item.ebwizardry\:crystal_silver_plating.desc_extended=엘다르의 공장에서 만들어진 거의 신화적인 합금으로, 우수한 마법 굴절도를 가지고 있습니다.\n\n신비로운 작업대에서 마법사 갑옷에 이 강화를 적용할 수 있습니다.
|
||||
item.ebwizardry\:crystal_silver_plating.desc_extended=엘다르의 대장간에서 만들어진 거의 신화적인 합금으로, 우수한 마법 굴절도를 가지고 있습니다.\n\n신비로운 작업대에서 마법사 갑옷에 이 강화를 적용할 수 있습니다.
|
||||
|
||||
item.ebwizardry\:ethereal_crystalweave.name=천상의 수정천
|
||||
item.ebwizardry\:ethereal_crystalweave.desc=일반적인 마법사의 갑옷을 워록의 갑옷으로 강화합니다
|
||||
item.ebwizardry\:ethereal_crystalweave.desc=일반적인 마법사의 갑옷을 주술사의 갑옷으로 강화합니다
|
||||
item.ebwizardry\:ethereal_crystalweave.desc_extended=동물의 가죽처럼 두껍지만 한 장의 종이보다 가벼운 마나의 천입니다.\n\n신비로운 작업대에서 마법사 갑옷에 이 강화를 적용할 수 있습니다.
|
||||
|
||||
item.ebwizardry\:magic_silk.name=마법 비단
|
||||
@@ -346,45 +346,45 @@ item.ebwizardry\:battlemage_chestplate_healing.name=치유 전투법사 흉갑
|
||||
item.ebwizardry\:battlemage_leggings_healing.name=치유 전투법사 각반
|
||||
item.ebwizardry\:battlemage_boots_healing.name=치유 전투법사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood.name=워록 후드
|
||||
item.ebwizardry\:warlock_robe.name=워록 로브
|
||||
item.ebwizardry\:warlock_leggings.name=워록 각반
|
||||
item.ebwizardry\:warlock_boots.name=워록 부츠
|
||||
item.ebwizardry\:warlock_hood.name=주술사 후드
|
||||
item.ebwizardry\:warlock_robe.name=주술사 로브
|
||||
item.ebwizardry\:warlock_leggings.name=주술사 각반
|
||||
item.ebwizardry\:warlock_boots.name=주술사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood_fire.name=화염워록 후드
|
||||
item.ebwizardry\:warlock_robe_fire.name=화염워록 로브
|
||||
item.ebwizardry\:warlock_leggings_fire.name=화염워록 각반
|
||||
item.ebwizardry\:warlock_boots_fire.name=화염워록 부츠
|
||||
item.ebwizardry\:warlock_hood_fire.name=화염주술사 후드
|
||||
item.ebwizardry\:warlock_robe_fire.name=화염주술사 로브
|
||||
item.ebwizardry\:warlock_leggings_fire.name=화염주술사 각반
|
||||
item.ebwizardry\:warlock_boots_fire.name=화염주술사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood_ice.name=얼음워록 후드
|
||||
item.ebwizardry\:warlock_robe_ice.name=얼음워록 로브
|
||||
item.ebwizardry\:warlock_leggings_ice.name=얼음워록 각반
|
||||
item.ebwizardry\:warlock_boots_ice.name=얼음워록 부츠
|
||||
item.ebwizardry\:warlock_hood_ice.name=얼음주술사 후드
|
||||
item.ebwizardry\:warlock_robe_ice.name=얼음주술사 로브
|
||||
item.ebwizardry\:warlock_leggings_ice.name=얼음주술사 각반
|
||||
item.ebwizardry\:warlock_boots_ice.name=얼음주술사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood_lightning.name=벼락워록 후드
|
||||
item.ebwizardry\:warlock_robe_lightning.name=벼락워록 로브
|
||||
item.ebwizardry\:warlock_leggings_lightning.name=벼락워록 각반
|
||||
item.ebwizardry\:warlock_boots_lightning.name=벼락워록 부츠
|
||||
item.ebwizardry\:warlock_hood_lightning.name=벼락주술사 후드
|
||||
item.ebwizardry\:warlock_robe_lightning.name=벼락주술사 로브
|
||||
item.ebwizardry\:warlock_leggings_lightning.name=벼락주술사 각반
|
||||
item.ebwizardry\:warlock_boots_lightning.name=벼락주술사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood_necromancy.name=사령워록 후드
|
||||
item.ebwizardry\:warlock_robe_necromancy.name=사령워록 로브
|
||||
item.ebwizardry\:warlock_leggings_necromancy.name=사령워록 각반
|
||||
item.ebwizardry\:warlock_boots_necromancy.name=사령워록 부츠
|
||||
item.ebwizardry\:warlock_hood_necromancy.name=사령주술사 후드
|
||||
item.ebwizardry\:warlock_robe_necromancy.name=사령주술사 로브
|
||||
item.ebwizardry\:warlock_leggings_necromancy.name=사령주술사 각반
|
||||
item.ebwizardry\:warlock_boots_necromancy.name=사령주술사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood_earth.name=대지워록 후드
|
||||
item.ebwizardry\:warlock_robe_earth.name=대지워록 로브
|
||||
item.ebwizardry\:warlock_leggings_earth.name=대지워록 각반
|
||||
item.ebwizardry\:warlock_boots_earth.name=대지워록 부츠
|
||||
item.ebwizardry\:warlock_hood_earth.name=대지주술사 후드
|
||||
item.ebwizardry\:warlock_robe_earth.name=대지주술사 로브
|
||||
item.ebwizardry\:warlock_leggings_earth.name=대지주술사 각반
|
||||
item.ebwizardry\:warlock_boots_earth.name=대지주술사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood_sorcery.name=신비워록 후드
|
||||
item.ebwizardry\:warlock_robe_sorcery.name=신비워록 로브
|
||||
item.ebwizardry\:warlock_leggings_sorcery.name=신비워록 각반
|
||||
item.ebwizardry\:warlock_boots_sorcery.name=신비워록 부츠
|
||||
item.ebwizardry\:warlock_hood_sorcery.name=신비주술사 후드
|
||||
item.ebwizardry\:warlock_robe_sorcery.name=신비주술사 로브
|
||||
item.ebwizardry\:warlock_leggings_sorcery.name=신비주술사 각반
|
||||
item.ebwizardry\:warlock_boots_sorcery.name=신비주술사 부츠
|
||||
|
||||
item.ebwizardry\:warlock_hood_healing.name=치유워록 후드
|
||||
item.ebwizardry\:warlock_robe_healing.name=치유워록 로브
|
||||
item.ebwizardry\:warlock_leggings_healing.name=치유워록 각반
|
||||
item.ebwizardry\:warlock_boots_healing.name=치유워록 부츠
|
||||
item.ebwizardry\:warlock_hood_healing.name=치유주술사 후드
|
||||
item.ebwizardry\:warlock_robe_healing.name=치유주술사 로브
|
||||
item.ebwizardry\:warlock_leggings_healing.name=치유주술사 각반
|
||||
item.ebwizardry\:warlock_boots_healing.name=치유주술사 부츠
|
||||
|
||||
item.ebwizardry\:spawn_wizard.name=생성: 마법사
|
||||
item.ebwizardry\:spawn_evil_wizard.name=생성: 사악한 마법사
|
||||
@@ -538,7 +538,7 @@ item.ebwizardry\:charm_flight.name=에메랄드 딱정벌레 날개
|
||||
item.ebwizardry\:charm_flight.desc=비행 및 활공 속도가 50%%더 빨라집니다
|
||||
item.ebwizardry\:charm_growth.name=마법수정 꽃 부적
|
||||
item.ebwizardry\:charm_growth.desc=수확의 축복 주문이 35%%확률로 식물을 완전히 자라게 합니다
|
||||
item.ebwizardry\:charm_abseiling.name=마법이 부여된 실타래
|
||||
item.ebwizardry\:charm_abseiling.name=마법이 부여된 실뭉치
|
||||
item.ebwizardry\:charm_abseiling.desc=덩굴의 얽매임을 사용하며 공중에 있을 때 웅크리면 덩굴의 길이가 늘어납니다
|
||||
item.ebwizardry\:charm_silk_touch.name=월광석 보주
|
||||
item.ebwizardry\:charm_silk_touch.desc=채광 주문에 섬세한 손길이 적용됩니다
|
||||
@@ -850,8 +850,8 @@ advancement.ebwizardry\:sage=학자의 길
|
||||
advancement.ebwizardry\:sage.desc=학자의 갑옷을 획득하세요
|
||||
advancement.ebwizardry\:battlemage=전투법사의 서약
|
||||
advancement.ebwizardry\:battlemage.desc=전투법사의 갑옷을 획득하세요
|
||||
advancement.ebwizardry\:warlock=워록의 방식
|
||||
advancement.ebwizardry\:warlock.desc=워록의 갑옷을 획득하세요
|
||||
advancement.ebwizardry\:warlock=주술사의 방식
|
||||
advancement.ebwizardry\:warlock.desc=주술사의 갑옷을 획득하세요
|
||||
|
||||
advancement.ebwizardry\:enchant_scroll=두루마리!
|
||||
advancement.ebwizardry\:enchant_scroll.desc=빈 두루마리를 만들고 신비로운 작업대에서 주문의 마법을 부여하세요
|
||||
|
||||
@@ -52,8 +52,8 @@ tile.ebwizardry\:dark_oak_lectern.name=Кафедра из тёмного дуб
|
||||
tile.ebwizardry\:receptacle.name=Вместилище
|
||||
tile.ebwizardry\:imbuement_altar.name=Алтарь наполнения
|
||||
|
||||
item.ebwizardry\:crystal_magic.name=Магический кристалл
|
||||
item.ebwizardry\:crystal_magic.desc=Переливающиеся цвета этого кристалла, кажется, медленно меняются и кружатся, намекая на магическую энергию внутри. Возможно, эту магию можно задействовать, как-нибудь...
|
||||
item.ebwizardry\:crystal_magic.name=Волшебный кристалл
|
||||
item.ebwizardry\:crystal_magic.desc=Переливающиеся цвета этого кристалла, кажется, медленно меняются и кружатся, намекая на волшебную энергию внутри. Возможно, эту магию можно задействовать, как-нибудь...
|
||||
item.ebwizardry\:crystal_fire.name=Огненный кристалл
|
||||
item.ebwizardry\:crystal_fire.desc=Кристалл, который светится оранжево-огненным цветом. Возможно, он - ключ к разблокировки элемента огня...
|
||||
item.ebwizardry\:crystal_ice.name=Ледяной кристалл
|
||||
@@ -96,7 +96,7 @@ item.ebwizardry\:wand.levelup=%1$s готов улучшиться до уров
|
||||
item.ebwizardry\:wand.addally=%1$s был добавлен в Ваш список союзников.
|
||||
item.ebwizardry\:wand.removeally=%1$s был убран из Вашего списка союзников.
|
||||
|
||||
item.ebwizardry\:magic_wand.name=Магический жезл
|
||||
item.ebwizardry\:magic_wand.name=Волшебный жезл
|
||||
item.ebwizardry\:apprentice_wand.name=Жезл ученика
|
||||
item.ebwizardry\:advanced_wand.name=Продвинутый жезл
|
||||
item.ebwizardry\:master_wand.name=Жезл мастера
|
||||
@@ -145,10 +145,10 @@ item.ebwizardry\:medium_mana_flask.name=Средняя колба с маной
|
||||
item.ebwizardry\:large_mana_flask.name=Большая колба с маной
|
||||
item.ebwizardry\:mana_flask.desc=Изготовьте колбу с маной с использованием Жезла или части брони Волшебника, чтобы восстановить %s маны.
|
||||
|
||||
item.ebwizardry\:grand_crystal.name=Большой магический кристалл
|
||||
item.ebwizardry\:grand_crystal.desc=Крупный магический кристалл, в несколько раз больше тех, что обнаружены естественным образом. Кто-то, видимо, вырастил его искусственно - но как?
|
||||
item.ebwizardry\:crystal_shard.name=Магический кристальный осколок
|
||||
item.ebwizardry\:crystal_shard.desc=Маленький кусочек раздробленного магического кристалла. Он содержит в себе немного кол-во маны, но он может иметь другое применение...
|
||||
item.ebwizardry\:grand_crystal.name=Большой волшебный кристалл
|
||||
item.ebwizardry\:grand_crystal.desc=Крупный волшебный кристалл, в несколько раз больше тех, что обнаружены естественным образом. Кто-то, видимо, вырастил его искусственно - но как?
|
||||
item.ebwizardry\:crystal_shard.name=Волшебный кристальный осколок
|
||||
item.ebwizardry\:crystal_shard.desc=Маленький кусочек раздробленного волшебного кристалла. Он содержит в себе немного количество маны, но он может иметь другое применение...
|
||||
|
||||
item.ebwizardry\:astral_diamond.name=Звёздный алмаз
|
||||
item.ebwizardry\:astral_diamond.desc=Высоко-ценившиеся драгоценный камень, который ярко сверкает над звёздным светом. Поговаривают, что самые могущественные Волшебники ищут Звёздные алмазы в замен, на самые неуловимые Таинственные знания.
|
||||
@@ -176,7 +176,7 @@ item.ebwizardry\:range_upgrade.desc=Улучшает эффективный ра
|
||||
item.ebwizardry\:duration_upgrade.desc=Улучшает продолжительность эффектов брошенным Жезлом.
|
||||
item.ebwizardry\:cooldown_upgrade.desc=Улучшает скорость отката заклинания Жезла.
|
||||
item.ebwizardry\:blast_upgrade.desc=Улучшает область эффекта заклинаний брошенным Жезлом.
|
||||
item.ebwizardry\:attunement_upgrade.desc=Улучшает кол-во заклинаний, которых можно привязать к Жезлу.
|
||||
item.ebwizardry\:attunement_upgrade.desc=Улучшает количество заклинаний, которых можно привязать к Жезлу.
|
||||
item.ebwizardry\:melee_upgrade.desc=Улучшает жезл на использование маны, для нанесения большего урона по мобам, при ударе.
|
||||
|
||||
item.ebwizardry\:flaming_axe.name=Пылающий топор
|
||||
@@ -204,7 +204,7 @@ item.ebwizardry\:armour_upgrade.name=Мистическая печать защ
|
||||
item.ebwizardry\:armour_upgrade.desc=Улучшает любую Броню волшебника, чтобы сделать её %1$s Легендарной.
|
||||
item.ebwizardry\:armour_upgrade.desc_extended=Примените это Улучшение в часть брони Волшебника в Мистическом верстаке.
|
||||
|
||||
item.ebwizardry\:magic_silk.name=Магический шёлк
|
||||
item.ebwizardry\:magic_silk.name=Волшебный шёлк
|
||||
|
||||
item.ebwizardry\:spectral_dust.name=Спектральный прах
|
||||
|
||||
@@ -274,7 +274,7 @@ item.ebwizardry\:ring_condensing.desc=Медленно восстанавлив
|
||||
item.ebwizardry\:ring_siphoning.name=Кольцо выкачивания
|
||||
item.ebwizardry\:ring_siphoning.desc=Увеличивает выкачивание маны на 30%%.
|
||||
item.ebwizardry\:ring_battlemage.name=Кольцо боевого мага
|
||||
item.ebwizardry\:ring_battlemage.desc=Удерживая жезл в левой руке и меч в основной руке, даёт 10%% дополнительного магического урона.
|
||||
item.ebwizardry\:ring_battlemage.desc=Удерживая жезл в левой руке и меч в основной руке, даёт 10%% дополнительного волшебного урона.
|
||||
item.ebwizardry\:ring_combustion.name=Кольцо горения
|
||||
item.ebwizardry\:ring_combustion.desc=Существа, убитые Огненными заклинаниями, взрываются.
|
||||
item.ebwizardry\:ring_fire_melee.name=Кольцо огненного прикосновения
|
||||
@@ -339,7 +339,7 @@ item.ebwizardry\:ring_interdiction.desc=Ваше силовое поле пов
|
||||
item.ebwizardry\:amulet_arcane_defence.name=Амулет мистической защиты
|
||||
item.ebwizardry\:amulet_arcane_defence.desc=Медленно восстанавливается мана на всю одетую броню Волшебника.
|
||||
item.ebwizardry\:amulet_warding.name=Амулет защиты
|
||||
item.ebwizardry\:amulet_warding.desc=Сокращает весь входящий магический урон на 10%%.
|
||||
item.ebwizardry\:amulet_warding.desc=Сокращает весь входящий волшебный урон на 10%%.
|
||||
item.ebwizardry\:amulet_wisdom.name=Амулет мудрости
|
||||
item.ebwizardry\:amulet_wisdom.desc=Существенно сокращает шанс отрицательных эффектов при использовании неоткрытых Заклинаний.
|
||||
item.ebwizardry\:amulet_fire_protection.name=Амулет быстрой пламени
|
||||
@@ -591,7 +591,7 @@ 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\:magic_slime.name=Волшебный слизень
|
||||
entity.ebwizardry\:silverfish_minion.name=Чешуйница
|
||||
entity.ebwizardry\:storm_elemental.name=Грозовой элементаль
|
||||
entity.ebwizardry\:evil_wizard.name=Злой волшебник
|
||||
@@ -599,31 +599,31 @@ entity.ebwizardry\:decoy.name=Приманка
|
||||
entity.ebwizardry\:vex_minion.name=Досаждатель
|
||||
entity.ebwizardry\:remnant.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\:combustion_rune.name=Магическая
|
||||
entity.ebwizardry\:flamecatcher_arrow.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\:combustion_rune.name=Волшебная
|
||||
entity.ebwizardry\:flamecatcher_arrow.name=Волшебная
|
||||
|
||||
entity.ebwizardry\:black_hole.name=Чёрная дыра
|
||||
entity.ebwizardry\:shield.name=Щит
|
||||
@@ -652,9 +652,9 @@ itemGroup.ebwizardrygear=Снаряжение wizardry
|
||||
advancement.ebwizardry\:root=Волшебство
|
||||
advancement.ebwizardry\:root.desc=Путешествие волшебника к освоению Мистики.
|
||||
advancement.ebwizardry\:crystal=Любопытный кристалл...
|
||||
advancement.ebwizardry\:crystal.desc=Добудьте магический кристалл.
|
||||
advancement.ebwizardry\:crystal.desc=Добудьте волшебный кристалл.
|
||||
advancement.ebwizardry\:arcane_initiate=Приступить к Мистике.
|
||||
advancement.ebwizardry\:arcane_initiate.desc=Создайте магический Жезл из Золотого самородка, Палки и Магического кристалла.
|
||||
advancement.ebwizardry\:arcane_initiate.desc=Создайте волшебный Жезл из Золотого самородка, Палки и Волшебного кристалла.
|
||||
|
||||
advancement.ebwizardry\:apprentice=Ученик волшебника.
|
||||
advancement.ebwizardry\:apprentice.desc=Используйте фолиант арканы, чтобы улучшить свой жезл.
|
||||
@@ -665,13 +665,13 @@ advancement.ebwizardry\:advanced.desc=Улучшите свой Жезл до П
|
||||
advancement.ebwizardry\:master=Мастер в Мистике.
|
||||
advancement.ebwizardry\:master.desc=Получите жезл мастера.
|
||||
advancement.ebwizardry\:max_out_wand=Полностью оборудован.
|
||||
advancement.ebwizardry\:max_out_wand.desc=Примените максимальное кол-во улучшений в жезл Мастера.
|
||||
advancement.ebwizardry\:max_out_wand.desc=Примените максимальное количество улучшений в жезл Мастера.
|
||||
advancement.ebwizardry\:all_spells=Маг на все руки.
|
||||
advancement.ebwizardry\:all_spells.desc=Бросьте каждое Заклинание в игре.
|
||||
|
||||
advancement.ebwizardry\:wizard_tower=Кто здесь живёт?
|
||||
advancement.ebwizardry\:wizard_tower.desc=Посетите башню Волшебника.
|
||||
advancement.ebwizardry\:wizard_trade=Магическое решение.
|
||||
advancement.ebwizardry\:wizard_trade=Волшебное решение.
|
||||
advancement.ebwizardry\:wizard_trade.desc=Купите предмет у Волшебника.
|
||||
advancement.ebwizardry\:anger_wizard=Вы пожалеете об этом.
|
||||
advancement.ebwizardry\:anger_wizard.desc=Разозлите волшебника.
|
||||
@@ -815,7 +815,7 @@ spell.ebwizardry\:disintegration=Распад
|
||||
spell.ebwizardry\:divination=Предсказание
|
||||
spell.ebwizardry\:dragon_fireball=Огненный шар дракона
|
||||
spell.ebwizardry\:earthquake=Землятресение
|
||||
spell.ebwizardry\:empowering_presence=Магическое усиление
|
||||
spell.ebwizardry\:empowering_presence=Волшебное усиление
|
||||
spell.ebwizardry\:enrage=Разозление
|
||||
spell.ebwizardry\:entrapment=Провокация
|
||||
spell.ebwizardry\:evade=Уклонение
|
||||
@@ -888,7 +888,7 @@ spell.ebwizardry\:lightning_pulse=Молниевый пульс
|
||||
spell.ebwizardry\:lightning_ray=Молниевый луч
|
||||
spell.ebwizardry\:lightning_sigil=Молниевый сигил
|
||||
spell.ebwizardry\:lightning_web=Молниевая паутина
|
||||
spell.ebwizardry\:magic_missile=Магический снаряд
|
||||
spell.ebwizardry\:magic_missile=Волшебный снаряд
|
||||
spell.ebwizardry\:mark_sacrifice=Знак жертвоприношения
|
||||
spell.ebwizardry\:metamorphosis=Метаморфоз
|
||||
spell.ebwizardry\:meteor=Метеор
|
||||
@@ -983,7 +983,7 @@ spell.ebwizardry\:chain_lightning.desc=Стреляет искрами свет
|
||||
spell.ebwizardry\:charge.desc=Заставляет заклинателя стремительно заряжаться в том направлении, куда он смотрит, повреждая и отбрасывая всё на своём пути.
|
||||
spell.ebwizardry\:clairvoyance.desc=Раскрывает путь в запоминающее место. С этим выбранным заклинанием, shift + пкм по блоку, чтобы задать место. Бросьте это Заклинание как обычно, чтобы раскрыть путь. Путь исчезнет через 90 секунд.
|
||||
spell.ebwizardry\:cobwebs.desc=Создаёт паутины туда, куда Вы указываете, она-же, сильно сдерживают движение любых существ пойманные среди них. Паутины пропадут через 20 секунд либо если сломать.
|
||||
spell.ebwizardry\:combustion_rune.desc=Помещает магические наземные мины на землю туда, куда Вы указываете, которые взрываются когда ступите на них.
|
||||
spell.ebwizardry\:combustion_rune.desc=Помещает волшебные наземные мины на землю туда, куда Вы указываете, которые взрываются когда ступите на них.
|
||||
spell.ebwizardry\:conjure_armour.desc=Создаёт спектральную броню вокруг Заклинателя, обеспечивающая защиту равной по защите Железной брони. Броня длится 60 секунд. У заклинателя должен быть Пустой слот для брони.
|
||||
spell.ebwizardry\:conjure_block.desc=Призывает спектральный блок туда, куда Вы указываете. Спектральный блок исчезает через 45 секунд, или Вы можете устранить его, снова бросив на него Заклинание.
|
||||
spell.ebwizardry\:conjure_bow.desc=Создаёт спектральный лук с безграничными стрелами, которые длятся 60 секунд.
|
||||
@@ -1005,7 +1005,7 @@ spell.ebwizardry\:disintegration.desc=Выстреливает мощной мо
|
||||
spell.ebwizardry\:divination.desc=Направляет заклинателя к близлежащим Рудам и Ресурсам. Мощь, увеличит вероятность найти больше ценных руд.
|
||||
spell.ebwizardry\:dragon_fireball.desc=Запускает огненный шар дракона в направлении, по которому Вы указываете, который выпускает сохраняющиеся Отравляющие облака при попадании.
|
||||
spell.ebwizardry\:earthquake.desc=Истинный мастер земной магии, который может сдвинуть горы.
|
||||
spell.ebwizardry\:empowering_presence.desc=Даёт Заклинателю и ближайшим Союзникам усиленный магический урон на 30 секунд.
|
||||
spell.ebwizardry\:empowering_presence.desc=Даёт Заклинателю и ближайшим Союзникам усиленный волшебный урон на 30 секунд.
|
||||
spell.ebwizardry\:enrage.desc=Причиняет близлежащих существ впадать в ярость, вместо этого, останавливая всё, что они делали напасть на Заклинателя.
|
||||
spell.ebwizardry\:entrapment.desc=Заманивает цель в Сферу тьмы, которая беспомощно тянет её вверх и непрерывно повреждает её.
|
||||
spell.ebwizardry\:evade.desc=Заставляет заклинателя быстро отпрыгнуть в сторону, чтобы увернуться от происходящих атак.
|
||||
@@ -1014,7 +1014,7 @@ 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\:fire_sigil.desc=Помещает волшебную огненную ловушку на землю, которая повреждает и поджигает существо сдетонирующее её.
|
||||
spell.ebwizardry\:fireskin.desc=Покрывает заклинателя в пламя на 30 секунд, причиняет всё, что атакует его загореться.
|
||||
spell.ebwizardry\:firestorm.desc="Очистите землю и очистите почву!\nДеревья должны гореть, а озера должны кипеть!\nСпалите дерево и подпалите камень!\nВсем склониться перед адским троном!"
|
||||
spell.ebwizardry\:fire_breath.desc="Я, дракон."
|
||||
@@ -1023,26 +1023,26 @@ 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_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\:forest_of_thorns.desc=Посреди леса кроется скрытая поляна,\nВ поляне играет Волшебник,\nМагические искусства невыразимого порядка,\nГлубоко в лесу шипов.
|
||||
spell.ebwizardry\:forest_of_thorns.desc=Посреди леса кроется скрытая поляна,\nВ поляне играет Волшебник,\nВолшебные искусства невыразимого порядка,\nГлубоко в лесу шипов.
|
||||
spell.ebwizardry\:freeze.desc=Замораживает цель на 10 секунд. Также будет замораживать воду и создавать на земле снег.
|
||||
spell.ebwizardry\:freezing_weapon.desc=Временно наполняет первое оружие в панели быстрого доступа Заклинателя силой мороза, причиняя замораживание жертв. Магия выветрится через 45 секунд.
|
||||
spell.ebwizardry\:frost_axe.desc=Создаёт морозный топор, который замораживает врагов при ударе. Длится 30 секунд.
|
||||
spell.ebwizardry\:frost_barrier.desc=Создаёт баррикаду льда впереди Заклинателя, которая ограждает их от поступающих атак. Барьер длится 20 секунд.
|
||||
spell.ebwizardry\:frost_ray.desc=Создаёт поток мороза в направлении, по которому Вы указываете, который замедляет и регулярно повреждает цели.
|
||||
spell.ebwizardry\:frost_sigil.desc=Помещает магическую ледяную ловушку на землю, которая повреждает и замораживает существо, сдетонирующее её.
|
||||
spell.ebwizardry\:frost_sigil.desc=Помещает волшебную ледяную ловушку на землю, которая повреждает и замораживает существо, сдетонирующее её.
|
||||
spell.ebwizardry\:frost_step.desc=Позволяет заклинателю замораживать воду пока он бродит, на 30 секунд.
|
||||
spell.ebwizardry\:grapple.desc=Выстреливает магической лианой, которая позволяет Заклинателю захватываться в сторону блоков или сматывать существ. Отпустите лкм, чтобы освободить Блок или Существо.
|
||||
spell.ebwizardry\:grapple.desc=Выстреливает волшебной лианой, которая позволяет Заклинателю захватываться в сторону блоков или сматывать существ. Отпустите лкм, чтобы освободить Блок или Существо.
|
||||
spell.ebwizardry\:glide.desc=При удержании Лкм, позволяет Заклинателю скользить вниз, пока он находится в воздухе.
|
||||
spell.ebwizardry\:greater_fireball.desc=Запускает большой огненный шар в направлении, по которому Вы указываете, который врывается при попадании.
|
||||
spell.ebwizardry\:greater_heal.desc=Излечивает заклинателя 4-мя сердцами.
|
||||
spell.ebwizardry\:greater_telekinesis.desc=Позволяет заклинателю подбирать блок или существо и удерживать его в воздухе до тех пор, пока зажата кнопка Лкм. Shift во время удержания блока или существа, выбросит его на короткое расстояние.
|
||||
spell.ebwizardry\:greater_ward.desc=Даёт заклинателю мощный защитный эффект, который существенно сокращает входящий магический урон на 30 секунд.
|
||||
spell.ebwizardry\:greater_ward.desc=Даёт заклинателю мощный защитный эффект, который существенно сокращает входящий волшебный урон на 30 секунд.
|
||||
spell.ebwizardry\:group_heal.desc=Лечит заклинателя и всех поблизости союзников, и, призывает существо с 3-мя сердцами.
|
||||
spell.ebwizardry\:growth_aura.desc=Выращивает все посевы рядом от Заклинателя. Также выращивает высокую траву и цветы на блоке травы.
|
||||
spell.ebwizardry\:guardian_beam.desc=Стреляет лучами из глаз Стража в направлении, по которому Вы указываете, который повреждает цели и истощает их запас воздуха под водой.
|
||||
@@ -1069,17 +1069,17 @@ spell.ebwizardry\:ironflesh.desc=Существенно улучшает соп
|
||||
spell.ebwizardry\:leap.desc=Заставляет заклинателя прыгать выше на несколько блоков и слегка вперёд.
|
||||
spell.ebwizardry\:levitation.desc=Поднимает заклинателя вверх, пока зажата кнопка Лкм. Также будет сводить на нет урон от падения, если оно используется до удара об землю.
|
||||
spell.ebwizardry\:life_drain.desc=Создаёт поток иссушительной энергии в направлении, по которому Вы указываете, которая высасывает жизнь из цели и использует её, чтобы мало-помалу восстановить Ваше здоровье.
|
||||
spell.ebwizardry\:light.desc=Создаёт магическую точку света, которая освещает окружающую область. Длится 30 секунд.
|
||||
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_sigil.desc=Размещает волшебную молниевую ловушку на землю, которая повреждает существо, сдетонирующее её и зацепит других поблизости существ.
|
||||
spell.ebwizardry\:lightning_web.desc="Сконцентрируйтесь. Направьте шторм в свой разум сквозь Жезл и освободите свою ярость."
|
||||
spell.ebwizardry\:magic_missile.desc=Стреляет молнией магической энергией в направлении, по которому Вы указываете.
|
||||
spell.ebwizardry\:mark_sacrifice.desc=Помечает цель как божественную жертву. Следующая магическая атака на помеченного существа, нанесёт 60%% дополнительного урона с каждым уровнем эффекта.
|
||||
spell.ebwizardry\:magic_missile.desc=Стреляет молнией волшебной энергией в направлении, по которому Вы указываете.
|
||||
spell.ebwizardry\:mark_sacrifice.desc=Помечает цель как божественную жертву. Следующая волшебная атака на помеченного существа, нанесёт 60%% дополнительного урона с каждым уровнем эффекта.
|
||||
spell.ebwizardry\:metamorphosis.desc=Преобразует цель в другую форму. Работает только на определённых существ.
|
||||
spell.ebwizardry\:meteor.desc=Некоторые волшебники хотят увидеть, как горит мир...
|
||||
spell.ebwizardry\:mind_control.desc=Берёт контроль над разумом цели на 30 секунд, заставив его поменяться местами и драться вместо Заклинателя. Не будет работать на существ, которые слишком сильны волей.
|
||||
@@ -1099,12 +1099,12 @@ spell.ebwizardry\:pocket_workbench.desc=Позволяет заклинател
|
||||
spell.ebwizardry\:poison.desc=Стреляет ядом в направлении, по которому Вы указываете.
|
||||
spell.ebwizardry\:poison_bomb.desc=Запускает отравляющую бомбу в направлении, по которому Вы указываете, которая взрывается при попадании, а также отравляет ближайших существ.
|
||||
spell.ebwizardry\:possession.desc="Стать своим врагом."
|
||||
spell.ebwizardry\:radiant_totem.desc=Создаёт сияющий тотем, который выстреливает лучом света на поблизости существ, лечащий Союзников, но повреждает мобов. Длится 30 секунд. Мощь, повысит кол-во целей.
|
||||
spell.ebwizardry\:radiant_totem.desc=Создаёт сияющий тотем, который выстреливает лучом света на поблизости существ, лечащий Союзников, но повреждает мобов. Длится 30 секунд. Мощь, повысит количество целей.
|
||||
spell.ebwizardry\:ray_of_purification.desc=Испускает луч ослепительного света, который повреждает и слепит цели. Неживые существа получат 2-й урон и загорятся.
|
||||
spell.ebwizardry\:remove_curse.desc=Снимает любое проклятие, которое на данный момент влияет на Заклинателя.
|
||||
spell.ebwizardry\:replenish_hunger.desc=Восполняет уровень еды Заклинателя 3-мя очками голода.
|
||||
spell.ebwizardry\:resurrection.desc=С мастером целителем рядом с Вами, быть мертвым... необязательно.
|
||||
spell.ebwizardry\:reversal.desc=Снимает случайный отрицательный эффект зелья и наносит его на цель, который будет страдать от этого эффекта в течение оставшегося периода времени. Мощь, увеличивает кол-во эффектов, которые будут обращены.
|
||||
spell.ebwizardry\:reversal.desc=Снимает случайный отрицательный эффект зелья и наносит его на цель, который будет страдать от этого эффекта в течение оставшегося периода времени. Мощь, увеличивает количество эффектов, которые будут обращены.
|
||||
spell.ebwizardry\:ring_of_fire.desc=Создаёт кольцо огня вокруг Заклинателя, которое повреждает всех ближайших врагов и поджигает их.
|
||||
spell.ebwizardry\:satiety.desc=Пополняет уровень еды Заклинателя 8-ю очками голода.
|
||||
spell.ebwizardry\:shadow_ward.desc=Создаёт стену тьмы впереди Заклинателя, которая причиняет половину всего входящего урона наносимого нападающему.
|
||||
@@ -1119,7 +1119,7 @@ spell.ebwizardry\:smoke_bomb.desc=Запускает дымовую бомбу
|
||||
spell.ebwizardry\:snare.desc=Устанавливает ловушку на землю, которая повреждает и ненадолго замедляет существо, которое сдетонирует её.
|
||||
spell.ebwizardry\:snowball.desc=Запускает снежок в направлении, по которому Вы указываете.
|
||||
spell.ebwizardry\:spark_bomb.desc=Запускает шоковый заряд в направлении, по которому Вы указываете, который выпускает искры на ближайших врагов при попадании.
|
||||
spell.ebwizardry\:spectral_pathway.desc=Создаёт несокрушимый магический мост впереди Вас, который расширяется на 15 блоков. Мост исчезнет через 1 минуту.
|
||||
spell.ebwizardry\:spectral_pathway.desc=Создаёт несокрушимый волшебный мост впереди Вас, который расширяется на 15 блоков. Мост исчезнет через 1 минуту.
|
||||
spell.ebwizardry\:speed_time.desc=...день, ночь, рассвет, сумерки, восход и закат\: таким образом, проходит время, которое охватывает нас в бесконечном цикле...
|
||||
spell.ebwizardry\:spider_swarm.desc=Призывает рой ядовитых пауков сражающихся за Вас. Пауки пропадут через 30 секунд, либо если их убьют.
|
||||
spell.ebwizardry\:static_aura.desc=Окружает заклинателя молнией на 30 секунд, стреляя искрами молнии во что-либо, кто ударит его.
|
||||
@@ -1148,7 +1148,7 @@ spell.ebwizardry\:transportation.desc=Перемещает заклинател
|
||||
spell.ebwizardry\:vanishing_box.desc=Даёт заклинателю доступ к хранилищу Сундуку края.
|
||||
spell.ebwizardry\:vex_swarm.desc=Призывает рой летающих досаждателей сражающихся за Вас. Досаждатели пропадут через 30 секунд, либо если их убьют.
|
||||
spell.ebwizardry\:wall_of_frost.desc=Зима в Ваших пальцах.
|
||||
spell.ebwizardry\:ward.desc=Даёт заклинателю защитный эффект, который снижает входящий магический урон на 30 секунд.
|
||||
spell.ebwizardry\:ward.desc=Даёт заклинателю защитный эффект, который снижает входящий волшебный урон на 30 секунд.
|
||||
spell.ebwizardry\:water_breathing.desc=Позволяет заклинателю дышать под водой на 1 минуту.
|
||||
spell.ebwizardry\:whirlwind.desc=Заставляет цель взлетать вверх и подальше от Вас на скорости.
|
||||
spell.ebwizardry\:wither.desc=Стреляет лучом тьмы, которая иссушает всё, что прикоснётся.
|
||||
@@ -1269,7 +1269,7 @@ enchantment.ebwizardry\:flaming_weapon=Наполнение огнём
|
||||
enchantment.ebwizardry\:freezing_weapon=Наполнение морозом
|
||||
enchantment.ebwizardry\:shocking_weapon=Наполнение молнией
|
||||
|
||||
enchantment.ebwizardry\:magic_protection=Магическая защита
|
||||
enchantment.ebwizardry\:magic_protection=Волшебная защита
|
||||
enchantment.ebwizardry\:frost_protection=Морозная защита
|
||||
enchantment.ebwizardry\:shock_protection=Шоковая защита
|
||||
|
||||
@@ -1279,7 +1279,7 @@ enchantment.ebwizardry.flaming_weapon.desc=Часть заклинания Ог
|
||||
enchantment.ebwizardry.freezing_weapon.desc=Часть заклинания Замороженного оружия; недостижимо в режиме Выживания (книга не сработает).
|
||||
enchantment.ebwizardry.shocking_weapon.desc=Часть заклинания Шокирующего оружия; недостижимо в режиме Выживания (книга не сработает).
|
||||
|
||||
enchantment.ebwizardry.magic_protection.desc=Уменьшает весь магический урон.
|
||||
enchantment.ebwizardry.magic_protection.desc=Уменьшает весь волшебный урон.
|
||||
enchantment.ebwizardry.frost_protection.desc=Уменьшает урон от заморозки.
|
||||
enchantment.ebwizardry.shock_protection.desc=Уменьшает урон от шока.
|
||||
|
||||
@@ -1336,6 +1336,8 @@ commands.ebwizardry\:discoverspell.removespell=Убрано %1$s из данны
|
||||
|
||||
config.ebwizardry.title.general=Параметры мода
|
||||
|
||||
config.ebwizardry.redundant_keys=В Вашем файле конфигурации содержатся лишние параметры, они ничего не сделают! [Подробности см. В журнале]
|
||||
|
||||
config.ebwizardry.generic.true=Вкл
|
||||
config.ebwizardry.generic.false=Выкл
|
||||
|
||||
@@ -1463,9 +1465,9 @@ config.ebwizardry.bookshelf_blocks.tooltip=Список названий бло
|
||||
config.ebwizardry.book_items=Книги
|
||||
config.ebwizardry.book_items.tooltip=Список названий предметов в реестре, которых можно поместить в Книжную полку, в дополнение к стандартным. Названия предметов не чувствительны к регистру. Для предметов мода, префикс с ID мода (например: thaumcraft:thaumonomicon).
|
||||
config.ebwizardry.bookshelf_search_radius=Радиус поиска Книжной полки
|
||||
config.ebwizardry.bookshelf_search_radius.tooltip=Максимальное кол-во блоков может быть в Книжной полке из Мистического верстака или Кафедры, чтобы иметь возможность соединиться к ней.
|
||||
config.ebwizardry.bookshelf_search_radius.tooltip=Максимальное количество блоков может быть в Книжной полке из Мистического верстака или Кафедры, чтобы иметь возможность соединиться к ней.
|
||||
config.ebwizardry.currency_items=Предметы валюты
|
||||
config.ebwizardry.currency_items.tooltip=Список названий предметов в реестре, который торгующийся Волшебник может использовать в качестве Валюты (в первом слоте; второй слот не затрагивается). Каждая запись в этом списке должна содержать название предмета в реестре, с последующим одним местом, затем целое число, определяющее 'значение' предмета. Более высокие значения означают, что требуется меньшее кол-во Валютных предметов для получения торговли.
|
||||
config.ebwizardry.currency_items.tooltip=Список названий предметов в реестре, который торгующийся Волшебник может использовать в качестве Валюты (в первом слоте; второй слот не затрагивается). Каждая запись в этом списке должна содержать название предмета в реестре, с последующим одним местом, затем целое число, определяющее 'значение' предмета. Более высокие значения означают, что требуется меньшее количество Валютных предметов для получения торговли.
|
||||
|
||||
config.ebwizardry.category.worldgen=Настройки генерации мира
|
||||
config.ebwizardry.category.worldgen.tooltip=Настройте возможности генерации мира Wizardry
|
||||
@@ -1630,9 +1632,9 @@ integration.antiqueatlas.marker.ebwizardry.obelisk=Обелиск
|
||||
integration.antiqueatlas.marker.ebwizardry.shrine=Святилища
|
||||
integration.antiqueatlas.marker.ebwizardry.library_ruins=Разрушенная библиотека
|
||||
|
||||
spell.ebwizardry\:magic_missile_festive=Магическая омела
|
||||
spell.ebwizardry\:magic_missile_festive=Волшебная омела
|
||||
spell.ebwizardry\:summon_snow_golem_festive=Призывает замороженного Снеговика
|
||||
spell.ebwizardry\:invigorating_presence_festive=Бодрое усиление
|
||||
spell.ebwizardry\:empowering_presence_festive=Магическое усиление
|
||||
spell.ebwizardry\:empowering_presence_festive=Волшебное усиление
|
||||
|
||||
wizard.debug=%1$s, %2$s, %3$s.
|
||||
@@ -363,6 +363,7 @@
|
||||
"spell.zombie_apocalypse.start": {"category": "spells", "sounds": ["ebwizardry:dark_aura_start"]},
|
||||
"spell.zombie_apocalypse.loop": {"category": "spells", "sounds": ["ebwizardry:dark_aura_loop"]},
|
||||
"spell.zombie_apocalypse.end": {"category": "spells", "sounds": ["ebwizardry:dark_aura_end"]},
|
||||
"spell.mirage": {"category": "spells", "sounds": ["ebwizardry:buff"]},
|
||||
|
||||
"forfeit.burn_self": {"category": "spells", "sounds": ["fire/ignite"]},
|
||||
"forfeit.fireball": {"category": "spells", "sounds": ["mob/ghast/fireball4"]},
|
||||
@@ -409,4 +410,4 @@
|
||||
"forfeit.weaken_self": {"category": "spells", "sounds": ["mob/guardian/curse"]},
|
||||
"forfeit.jam_self": {"category": "spells", "sounds": ["ebwizardry:effect1", "ebwizardry:effect2"]},
|
||||
"forfeit.curse_self": {"category": "spells", "sounds": ["mob/guardian/curse"]}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"chargeup": 25,
|
||||
"cooldown": 300,
|
||||
"base_properties": {
|
||||
"resistance_duration": 600,
|
||||
"resistance_strength": 2
|
||||
"diamondflesh_duration": 600,
|
||||
"diamondflesh_strength": 0
|
||||
}
|
||||
}
|
||||
@@ -14,11 +14,12 @@
|
||||
"element": "healing",
|
||||
"type": "buff",
|
||||
"cost": 30,
|
||||
"chargeup": 0,
|
||||
"chargeup": 20,
|
||||
"cooldown": 60,
|
||||
"base_properties": {
|
||||
"effect_radius": 5,
|
||||
"effect_duration": 900,
|
||||
"effect_strength": 1
|
||||
"effect_strength": 0,
|
||||
"potency_per_level": 0.15
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
"chargeup": 15,
|
||||
"cooldown": 100,
|
||||
"base_properties": {
|
||||
"resistance_duration": 600,
|
||||
"resistance_strength": 1
|
||||
"ironflesh_duration": 600,
|
||||
"ironflesh_strength": 0
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
"chargeup": 0,
|
||||
"cooldown": 50,
|
||||
"base_properties": {
|
||||
"resistance_duration": 600,
|
||||
"resistance_strength": 0
|
||||
"oakflesh_duration": 600,
|
||||
"oakflesh_strength": 0
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
"range": 10,
|
||||
"damage": 4,
|
||||
"effect_duration": 100,
|
||||
"critical_health": 4
|
||||
"critical_health": 4,
|
||||
"player_effect_duration_multiplier": 0.5
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user