Compare commits

...

150 Commits

Author SHA1 Message Date
Electroblob 9c1042f686 Update version number 2018-06-05 17:01:04 +01:00
Electroblob cad3fee1b9 Update mcmod.info 2018-06-05 16:58:33 +01:00
Electroblob 5947b2ee62 Fix smoke bomb recipe and allow charcoal to be used 2018-06-05 16:00:47 +01:00
Electroblob 177a39bad1 Cleanup 2018-06-05 15:43:56 +01:00
Electroblob cdf8f6e32d Remove now-redundant recipe config options 2018-06-05 15:43:48 +01:00
Electroblob f88aac11e9 Convert all non-dynamic recipes to JSON, add ore dictionary support where appropriate and change incorrect "amount" tag to "count", fixes #18 2018-06-05 15:43:14 +01:00
Electroblob 05b905b988 Fix light level detection for petrified creatures breaking out 2018-06-05 14:12:33 +01:00
Electroblob 669cd2892d Add check for valid special wand upgrades, fixes #48 2018-06-05 11:12:03 +01:00
Electroblob dd07d08ff0 Return true in ADS methods when passed a null attacker, acting as a fallback for when caster does not save properly; fixes #40 2018-06-04 23:45:10 +01:00
Electroblob 54bb327fdf Properly sync thrower field for all throwable projectiles, fixes #42 (does not fix vanilla throwables though) 2018-06-04 23:42:12 +01:00
Electroblob 2cd8b46c1f Add toughness to legendary wizard armour 2018-06-04 18:32:32 +01:00
Electroblob b61413f7f1 Remove ISpecialArmor from ItemWizardArmour since it is no longer necessary, fixes #44 2018-06-04 18:20:55 +01:00
Electroblob 4e7765a7e7 Allow tab-completion of spell names in commands without specifying the modid 2018-06-04 18:04:36 +01:00
Electroblob 49a6dc43c1 Cleanup 2018-06-04 17:20:39 +01:00
Electroblob b82bc6698f Make crystal ore drop xp when mined 2018-06-04 17:17:58 +01:00
Electroblob 1e43c67660 Tweak summoned creature targeting so that non-evil wizards' minions no longer attack players unless the player in question has angered the wizard 2018-06-04 17:17:33 +01:00
Electroblob c129571167 Change EntityWizard to implement IMerchant and INpc directly rather than extending EntityVillager, fixes #38 plus a number of other bugs 2018-06-04 16:36:20 +01:00
Electroblob b23a643c0e Make arcane workbench drop items correctly when broken, fixes #20 2018-06-04 15:00:02 +01:00
Electroblob 194bff3e6a Miscellaneous lang file fixes 2018-06-04 13:09:23 +01:00
Electroblob 426ca78288 Sort config options into a more logical order 2018-06-04 12:51:12 +01:00
Electroblob f15919fdce Organise the config file and GUI into categories 2018-06-04 12:39:56 +01:00
Electroblob 2124842136 Fix transportation stone not dropping when unsupported, fixes #23 2018-06-03 23:57:22 +01:00
Electroblob 70e697876b Centralise code for config GUI category classes 2018-06-03 23:24:42 +01:00
Electroblob 9b5e5a871c Add dimension whitelist option for evil wizard spawning and restrict numbers to 1 per chunk, closes #26 2018-06-03 22:22:18 +01:00
Electroblob 5ba92e5de5 Change whitelist/blacklist storage from strings to resourcelocations to bring it in line with the registry system 2018-06-03 22:17:57 +01:00
Electroblob 4e6780a3cf Replace getEntityString with getKey(...).toString() 2018-06-03 18:19:10 +01:00
Electroblob 00584ad635 Move resistances config setup from preInit to init 2018-06-03 18:18:29 +01:00
Electroblob f72ed33515 Add mind control targets blacklist config option 2018-06-03 18:17:05 +01:00
Electroblob c2366ed1ba Change crystal ore drop quantity to drop the intended 1-3 crystals (rather than the previous 1-2) and change fortune behaviour to work like vanilla ores, see discussion in #43 2018-06-03 15:52:13 +01:00
Electroblob 46df8d7311 Add smelting recipe for crystal ore, closes #43 2018-06-03 15:15:50 +01:00
Electroblob d4579b9184 Remove all calls to GlStateManager.pushAttrib() and pullAttrib() and a few other tweaks to gl calls, fixes #12, #46 and #47 2018-06-03 12:39:25 +01:00
Electroblob ee6f0cfe70 Correct death message lang key in code, fixes #41 2018-06-02 16:08:48 +01:00
Electroblob 6155fd9c68 Display non-keyboard keybinds correctly, fixes #36 2018-06-02 15:14:32 +01:00
Electroblob 32c0608b51 Stop spirit horses dropping leather, fixes #37. Also adds the same overrides to spirit wolves; since regular wolves don't drop anything this wasn't noticeable. 2018-06-02 13:39:21 +01:00
Electroblob 404df6af23 Fixes #32 2018-06-02 13:35:37 +01:00
Electroblob 764e10538b Update LICENSE.md 2018-05-21 10:45:11 +01:00
Electroblob 6b1b590e30 Merge pull request #25 from Shadows-of-Fire/client
Fixes #17, #22, and maybe #12
2018-05-04 19:50:11 +01:00
Shadows_of_Fire 8360e520cd De-duplicate armor value 2018-05-04 14:34:09 -04:00
Shadows_of_Fire 005a17d750 Fix armor value tooltips 2018-05-04 14:23:57 -04:00
Shadows_of_Fire 28abe036a0 Armor properly has 0 damage reduction when oom
tooltip is being buggy, won't display armor reduction values.
2018-05-04 08:18:15 -04:00
Shadows_of_Fire ca96112b67 Fix wizard armor breaking 2018-05-04 07:35:51 -04:00
Shadows_of_Fire b8e847c6a6 Fixes #22 2018-05-04 06:53:11 -04:00
Shadows_of_Fire 35cb2c31fc Convert to GlStateManager calls
also removes the weird reflection being used to access the RenderItem
2018-05-04 06:45:57 -04:00
Electroblob 30dd587d34 Move wiki resources to wiki git repository 2018-05-03 20:47:46 +01:00
Electroblob 4644814582 Add wiki resources 2018-05-03 20:31:25 +01:00
Electroblob 7db3151d8a Change hardness of transportation to 0.3, fixes #19 2018-05-02 18:23:07 +01:00
Electroblob c8ca73cca9 Fix incorrect event handler annotation 2018-05-02 13:35:47 +01:00
Electroblob d5a0479ebe Update .gitignore 2018-05-02 13:19:30 +01:00
Electroblob 339ec69a72 Update version number 2018-04-14 15:53:51 +01:00
Electroblob b2cb717aa3 Cleanup 2018-04-14 15:47:31 +01:00
Electroblob cf4a02f37f Fix crash related to creative tab sorting with HQM installed 2018-04-14 15:28:19 +01:00
Electroblob 84304dd7ce Prevent possible server crash with static initialiser block 2018-04-14 15:26:47 +01:00
Electroblob e3b44eb194 Make entities attacked by summoned creatures revenge-target the summoned creature rather than its summoner 2018-04-14 14:09:16 +01:00
Electroblob 2cbb0a590f Correct position of spell cooldown bar when spell HUD is at top of screen; fixes #14 2018-04-14 13:22:53 +01:00
Electroblob 6b9c864890 Move target position references inside null checks; fixes #13 2018-04-14 13:19:17 +01:00
Electroblob c15a0763d5 Merge branch '1.12.2' of https://github.com/Electroblob77/Wizardry into 1.12.2 2018-04-10 16:04:35 +01:00
Electroblob 4a23d88f30 Add obfuscated names to reflective field access 2018-04-10 16:03:23 +01:00
Electroblob 286705c79b Update README.md 2018-04-09 23:11:23 +01:00
Electroblob 3895f5c531 Cleanup 2018-04-09 17:29:41 +01:00
Electroblob c51e0bd218 Fix mods list logo 2018-04-09 17:29:18 +01:00
Electroblob 766570aeb2 Fix spell book for crystals trade not working 2018-04-09 17:28:59 +01:00
Electroblob 4e91b0d19d Fix broken lang key in config GUI 2018-04-08 00:04:35 +01:00
Electroblob 65f7630546 Update minecraft version number in wizard's handbook 2018-04-08 00:04:06 +01:00
Electroblob 8cf7572041 Update mcmod.info 2018-04-08 00:03:39 +01:00
Electroblob db057a5ca9 Update credits 2018-04-08 00:03:15 +01:00
Electroblob 267fb2daf4 Cleanup 2018-04-07 22:50:08 +01:00
Electroblob b96526b284 Fix ice wraith not attacking 2018-04-07 22:49:44 +01:00
Electroblob e01b5c728c Flip the item on the arcane workbench the right way up 2018-04-07 22:48:10 +01:00
Electroblob 0cf1d74fd5 Fix buttons rendering incorrectly in wizard's handbook 2018-04-07 20:31:48 +01:00
Electroblob 8316dcad70 Change some advancement icon frames and add new background 2018-04-07 17:49:59 +01:00
Electroblob df1eb68f35 Remove last few harcoded mod ID strings 2018-04-07 12:47:18 +01:00
Electroblob 416868bafb More cleanup 2018-04-07 00:08:43 +01:00
Electroblob 0424e409fc Fix root advancement localisations and rename all advancement translation keys to bring them in line with everything else 2018-04-07 00:08:26 +01:00
Electroblob a5b38e8f83 Stop mana flask charging recipes appearing in recipe book; fixes #11 2018-04-06 23:52:30 +01:00
Electroblob 1e0613c949 Cleanup 2018-04-06 22:53:53 +01:00
Electroblob d33290d890 Fix various warnings (deprecated method usage, etc.) 2018-04-06 22:53:41 +01:00
Electroblob e22d428016 Update version number 2018-04-06 22:51:07 +01:00
Electroblob baa407ce61 Merge pull request #10 from 12foo/1.12.2-corail
1.12 port update
2018-03-18 16:27:49 +00:00
Philipp Rustemeier ea11910af2 Post-merge fixups
In particular, act as if a spellbook has been discovered during tooltip
generation if player is null. This allows JEI to index all the spell
names.
2018-03-16 18:09:40 +01:00
Philipp Rustemeier 873b5a4f4d Fix Arcane Workbench GUI
- Explicitly render inventory mouseover tooltips (this is apparently required now for them to appear)
- When a wand is in, report the actual new xSize to Minecraft so things like JEI don't overdraw the tooltip on the right
2018-03-16 18:08:55 +01:00
Philipp Rustemeier 6890ae765a Fix JSON recipe crafting with ore dictionary
In current Forge, you can use OD entries in normal crafting recipes; using the special forge crafting recipe types is no longer necessary.
2018-03-16 18:08:55 +01:00
Philipp Rustemeier b9d240799d Finish changing modid to 'ebwizardry'
- Fix up translations, resource IDs, paths etc.
- Where possible, the modid part in most strings now just reuses Wizardry.MODID
2018-03-16 18:08:47 +01:00
Philipp Rustemeier 612bbdb64d Replace Achievements with Advancements
- Advancements are now in JSON files, converted by the included migration script.
- WizardryAdvancementTrigger is a generic achievement trigger that can be reused throughout the code to trigger custom advancements not covered by the JSON conditions.
- Plus some other small and obvious fixes.
2018-03-16 18:08:34 +01:00
Philipp Rustemeier 62c2a9e9b8 Various small fixes for 1.12 2018-03-16 18:07:37 +01:00
Electroblob bc3051fcf0 Merge pull request #8 from Corail31/1.12.2
1.12 conversion
2018-03-16 00:00:53 +00:00
Corail31 489fb82fbd 1.12 conversion 2018-03-09 11:56:31 +01:00
Electroblob edff82acca Update README.md 2018-03-09 10:05:01 +00:00
Electroblob 15e2a36518 Fix broken crafting recipes and Minecraft version number in wizard's handbook 2018-03-07 11:00:47 +00:00
Electroblob c5402285d8 Fix crash when viewing recipe pages of wizard's handbook 2018-03-06 23:36:16 +00:00
Electroblob b4fdf181be Fix incorrect achievement description keys in lang files 2018-02-27 23:41:18 +00:00
Electroblob ddd70b954c Change transportation stone item to use 2D texture instead of 3D model 2018-02-27 23:39:45 +00:00
Electroblob f17f01dc4b Rename handbook_ru_RU.txt to handbook_ru_ru.txt 2018-02-27 18:19:52 +00:00
Electroblob 257d5c28a1 Rename handbook_es_MX.txt to handbook_es_mx.txt 2018-02-27 18:19:32 +00:00
Electroblob 3cc410192c Rename handbook_es_ES.txt to handbook_es_es.txt 2018-02-27 18:19:15 +00:00
Electroblob b033a53f82 Rename handbook_en_US.txt to handbook_en_us.txt 2018-02-27 18:18:53 +00:00
Electroblob d189991c65 Rename handbook_en_GB.txt to handbook_en_gb.txt 2018-02-27 18:18:33 +00:00
Electroblob edb2a2d5a5 Merge branch '1.11.2' of https://github.com/Electroblob77/Wizardry into 1.11.2 2018-02-26 23:18:44 +00:00
Electroblob de66c3abba Update README.md 2018-02-26 22:55:54 +00:00
Electroblob f9b546daa9 Fix incorrect method call in summoned creature classes; was causing caster not be loaded properly
I can't believe I didn't notice this before...
2018-02-26 19:02:14 +00:00
Electroblob 6f776fbae6 Cleanup 2018-02-26 18:37:52 +00:00
Electroblob 13444f1de3 Additional method for 76f6d43 2018-02-26 18:37:09 +00:00
Electroblob 1581d18a43 Temporarily fix shadow ward not damaging its caster 2018-02-26 18:36:13 +00:00
Electroblob 46eae53313 Fix phase step missing sound 2018-02-26 18:35:12 +00:00
Electroblob 76f6d431bb Fix metamorphosis making entities disappear 2018-02-26 18:34:18 +00:00
Electroblob 2ad2b9988b Fix NBT copying for metamorphosis 2018-02-25 18:44:46 +00:00
Electroblob 8b363b6b4f Update ru_ru.lang (credit: VilagVil) 2018-02-25 18:43:55 +00:00
Electroblob 76d4e3d029 Cleanup and minor code tweaks 2018-02-24 13:49:27 +00:00
Electroblob 74ddcd79ca Rewrite metamorphosis to work with husks/strays and skeleton minions 2018-02-24 13:47:33 +00:00
Electroblob 6cd3e16939 Fix decay spawning too infrequently 2018-02-24 12:42:50 +00:00
Electroblob d462acc489 Add wither skeleton minion localisations 2018-02-23 17:40:29 +00:00
Electroblob eeb2785899 Rewrote some of the mind control logic to properly fix targeting 2018-02-23 13:25:05 +00:00
Electroblob 11af545bd2 Cleanup 2018-02-23 12:40:03 +00:00
Electroblob d4c9242b14 Fix mind-controlled entities not attacking any more after their initial target is killed
This problem arose as a result of the previous bugfix a4695bc
2018-02-23 12:39:44 +00:00
Electroblob db9812eac9 Register wither skeleton minions properly 2018-02-23 12:37:48 +00:00
Electroblob d792d50f92 Fix various problems caused by armour stands being a subclass of EntityLivingBase 2018-02-23 12:37:14 +00:00
Electroblob 3632511983 Add fixes from 52d12c0, a4695bc and f4d7ba6 to 1.11.2 branch 2018-02-22 14:50:20 +00:00
Electroblob f54b92be16 Replace hasKey with hasUniqueId where appropriate, should fix some weirdness with a few spells 2018-02-22 13:32:09 +00:00
Electroblob a567281183 Fix null itemstack error 2018-02-22 12:56:03 +00:00
Electroblob 56a24ee7b5 Fix problems with pocket furnace spell caused by incorrect itemstack check 2018-02-22 12:37:31 +00:00
Electroblob 5715928dbd Actually fix spell chat readout localisations 2018-02-22 12:21:05 +00:00
Electroblob e0001b5d37 Fix broken localisations for spell chat readouts 2018-02-21 10:51:31 +00:00
Electroblob 15fb75a7c3 Fix magic projectiles hitting their thrower on the client side 2018-02-21 10:50:52 +00:00
Electroblob d7750ad80c Merge pull request #5 from Electroblob77/Electroblob77-filename-case-fix
Rename lang files to all lowercase
2018-02-18 22:38:34 +00:00
Electroblob 9940908485 Rename ru_RU.lang to ru_ru.lang 2018-02-18 22:35:26 +00:00
Electroblob b7895ca744 Rename es_MX.lang to es_mx.lang 2018-02-18 22:35:01 +00:00
Electroblob 574ffa891d Rename es_ES.lang to es_es.lang 2018-02-18 22:33:31 +00:00
Electroblob 67069c818f Rename en_US.lang to en_us.lang 2018-02-18 22:33:03 +00:00
Electroblob d2900e5692 Rename en_GB.lang to en_gb.lang 2018-02-18 22:31:27 +00:00
Electroblob a1fa1d91c2 Fix broken entity localisations 2018-02-18 01:58:10 +00:00
Electroblob 338f6d54d0 Even more cleanup 2018-02-16 22:36:26 +00:00
Electroblob 3be254a247 Remove unnecessary empty itemstack checks, see comments on d0fda72 2018-02-16 22:28:00 +00:00
Electroblob bec52edce4 More cleanup 2018-02-16 22:26:28 +00:00
Electroblob 2dd52ce6b1 Fix x/z coordinate error, see comment on d0fda72 2018-02-16 16:14:28 +00:00
Electroblob d0d6f3a1fc Cleanup 2018-02-16 16:05:46 +00:00
Electroblob 9bf657aeab Add wizardry loot to woodland mansions and end cities 2018-02-16 16:01:01 +00:00
Electroblob c4ea81432f Replace Minecraft version number in text files with substitute value 2018-02-16 15:46:13 +00:00
Electroblob b08651c11e Replace deprecated slipperiness field access with getter 2018-02-16 15:45:18 +00:00
Electroblob aabcf43c1d Update build.gradle 2018-02-16 15:36:54 +00:00
Electroblob 066d6858c3 Update README.md 2018-02-13 16:29:49 +00:00
Electroblob 9c626d6756 Update CREDITS.md 2018-02-13 16:28:50 +00:00
Electroblob 00db03f546 Update CREDITS.md 2018-02-13 16:27:51 +00:00
Electroblob 071eb45d3c Merge pull request #4 from Corail31/1.11.2
More updating to 1.11.2 and stable_32 mcp mappings
2018-02-12 17:57:19 +00:00
Corail31 d0fda72a59 First Checkup 2018-02-11 22:51:13 +01:00
Electroblob 7f7605c089 Miscellaneous fixes and cleanup 2018-02-11 18:53:50 +00:00
Electroblob 2b24c3fb2a Add fix from 6d77918 to 1.11.2 branch 2018-02-09 18:26:11 +00:00
Electroblob e5c02cd0df Merge branch '1.11.2' of https://github.com/Electroblob77/Wizardry into 1.11.2 2018-02-07 21:42:22 +00:00
Electroblob 037611f1c3 Update build.gradle 2018-02-07 21:41:33 +00:00
Electroblob 2284f6db24 Update README.md 2018-02-07 21:31:11 +00:00
Electroblob 3df5597dcc Initial 1.11.2 update 2018-02-07 21:15:50 +00:00
Electroblob 67f6be0671 Update README.md 2018-02-06 17:28:56 +00:00
1026 changed files with 23050 additions and 20093 deletions
+2
View File
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
+1
View File
@@ -21,4 +21,5 @@ build
eclipse eclipse
run run
misc misc
libs
Thumbs.db Thumbs.db
+7 -2
View File
@@ -1,8 +1,8 @@
# Credits # Credits
Electroblob's Wizardry Electroblob's Wizardry
Version 2.1.0 Version 4.1.0
For Minecraft 1.10.2 For Minecraft 1.12.2
Designed, coded and textured by Electroblob 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: In addition, I'd like to thank the following individuals for their contributions to the mod:
#### Code
- Corail31
- 12foo
#### Translations #### Translations
- Russian: VilagVil - Russian: VilagVil
+2 -2
View File
@@ -1,7 +1,7 @@
# License # License
This repository is copyright © Electroblob 2018. The following license is provided to allow you to creatively contribute to and improve the repository. This repository is copyright © Electroblob 2018. The following license is provided to allow you to creatively contribute to and improve the repository.
This license applies only to the source code and assets present in this repository. The compiled mod (available at https://minecraft.curseforge.com/projects/electroblobs-wizardry) comes under its own separate license, see the aforementioned webpage for details. This license applies only to the source code, assets and wiki pages present in this repository. The compiled mod (available at https://minecraft.curseforge.com/projects/electroblobs-wizardry) comes under its own separate license, see the aforementioned webpage for details.
TL;DR: Do what you want with this repo on Github, but ask me first if you want to put it anywhere else or publish your version. Don't try and make money off the repo or anything in it. I'm not responsible if the code breaks things, and if you help me out by submitting a PR, I can use and modify the contents of that PR as long as I give you credit. (This brief summary is non-binding and does not override or replace the full license below.) TL;DR: Do what you want with this repo on Github, but ask me first if you want to put it anywhere else or publish your version. Don't try and make money off the repo or anything in it. I'm not responsible if the code breaks things, and if you help me out by submitting a PR, I can use and modify the contents of that PR as long as I give you credit. (This brief summary is non-binding and does not override or replace the full license below.)
@@ -17,7 +17,7 @@ TL;DR: Do what you want with this repo on Github, but ask me first if you want t
'Electroblob's Wizardry', 'Wizardry', 'the mod' - The Minecraft modification Electroblob's Wizardry 'Electroblob's Wizardry', 'Wizardry', 'the mod' - The Minecraft modification Electroblob's Wizardry
'Repository' - This repository on Github, containing this license, other informational files, configurations, code and assets which are part of Electroblob's Wizardry 'Repository' - This repository on Github, containing this license, the wiki, other informational files, configurations, code and assets which are part of Electroblob's Wizardry
'Curseforge' - The webpage https://minecraft.curseforge.com/projects/electroblobs-wizardry 'Curseforge' - The webpage https://minecraft.curseforge.com/projects/electroblobs-wizardry
+2 -2
View File
@@ -1,8 +1,8 @@
# Wizardry # Wizardry  [![Curseforge](http://cf.way2muchnoise.eu/full_electroblobs-wizardry_downloads.svg)](https://minecraft.curseforge.com/projects/electroblobs-wizardry) [![Curseforge](http://cf.way2muchnoise.eu/versions/For%20MC_electroblobs-wizardry_all.svg)](https://minecraft.curseforge.com/projects/electroblobs-wizardry) [![Discord](https://img.shields.io/discord/417798297265242145.svg?colorB=7289DA&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHYAAABWAgMAAABnZYq0AAAACVBMVEUAAB38%2FPz%2F%2F%2F%2Bm8P%2F9AAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfhBxwQJhxy2iqrAAABoElEQVRIx7WWzdGEIAyGgcMeKMESrMJ6rILZCiiBg4eYKr%2Fd1ZAfgXFm98sJfAyGNwno3G9sLucgYGpQ4OGVRxQTREMDZjF7ILSWjoiHo1n%2BE03Aw8p7CNY5IhkYd%2F%2F6MtO3f8BNhR1QWnarCH4tr6myl0cWgUVNcfMcXACP1hKrGMt8wcAyxide7Ymcgqale7hN6846uJCkQxw6GG7h2MH4Czz3cLqD1zHu0VOXMfZjHLoYvsdd0Q7ZvsOkafJ1P4QXxrWFd14wMc60h8JKCbyQvImzlFjyGoZTKzohwWR2UzSONHhYXBQOaKKsySsahwGGDnb%2FiYPJw22sCqzirSULYy1qtHhXGbtgrM0oagBV4XiTJok3GoLoDNH8ooTmBm7ZMsbpFzi2bgPGoXWXME6XT%2BRJ4GLddxJ4PpQy7tmfoU2HPN6cKg%2BledKHBKlF8oNSt5w5g5o8eXhu1IOlpl5kGerDxIVT%2BztzKepulD8utXqpChamkzzuo7xYGk%2FkpSYuviLXun5bzdRf0Krejzqyz7Z3p0I1v2d6HmA07dofmS48njAiuMgAAAAASUVORK5CYII%3D)](https://discord.gg/MTmMzMv)
![Image not found](https://media-elerium.cursecdn.com/attachments/203/387/banner7.png) ![Image not found](https://media-elerium.cursecdn.com/attachments/203/387/banner7.png)
Source code for Electroblob's Wizardry, a Minecraft mod currently for versions 1.7.10 and 1.10.2. Wizardry adds an RPG-style system of magic spells to Minecraft with the aim of being as playable as possible. No crazy constructs, no perk trees, no complex recipes - simply find spell books, cast spells, and master the arcane! Source code for Electroblob's Wizardry, a Minecraft mod currently for versions 1.7.10, 1.10.2, 1.11.2, and 1.12.2. Wizardry adds an RPG-style system of magic spells to Minecraft with the aim of being as playable as possible. No crazy constructs, no perk trees, no complex recipes - simply find spell books, cast spells, and master the arcane!
Please read the [guide for contributing](guide_for_contributing.md) before submitting an issue or a PR. Please read the [guide for contributing](guide_for_contributing.md) before submitting an issue or a PR.
+12 -11
View File
@@ -4,30 +4,32 @@ buildscript {
maven { url = "http://files.minecraftforge.net/maven" } maven { url = "http://files.minecraftforge.net/maven" }
} }
dependencies { dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.2-SNAPSHOT' classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
} }
} }
apply plugin: 'net.minecraftforge.gradle.forge' apply plugin: 'net.minecraftforge.gradle.forge'
//Only edit below this line, the above code adds and enables the nessasary things for Forge to be setup. //Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
version = " 2.1.0 - MC 1.10.2" version = " 4.1.2 - MC 1.12.2"
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "Electroblob's Wizardry " archivesBaseName = "Electroblob's Wizardry "
srcCompat = JavaVersion.VERSION_1_8 sourceCompatibility = targetCompatibility = "1.8" // Need this here so eclipse task generates correctly.
targetCompat = JavaVersion.VERSION_1_8 compileJava {
sourceCompatibility = targetCompatibility = "1.8"
}
minecraft { minecraft {
version = "1.10.2-12.18.3.2185" version = "1.12.2-14.23.2.2611"
runDir = "run" runDir = "run"
// the mappings can be changed at any time, and must be in the following format. // the mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD snapshot are built nightly. // snapshot_YYYYMMDD snapshot are built nightly.
// stable_# stables are built at the discretion of the MCP team. // stable_# stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not allways work. // 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. // simply re-run your setup task after changing the mappings to update your workspace.
mappings = "snapshot_20161111" mappings = "snapshot_20180316"
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
} }
@@ -55,8 +57,7 @@ dependencies {
} }
processResources processResources {
{
// this will ensure that this task is redone when the versions change. // this will ensure that this task is redone when the versions change.
inputs.property "version", project.version inputs.property "version", project.version
inputs.property "mcversion", project.minecraft.version inputs.property "mcversion", project.minecraft.version
@@ -69,7 +70,7 @@ processResources
expand 'version':project.version, 'mcversion':project.minecraft.version expand 'version':project.version, 'mcversion':project.minecraft.version
} }
// copy everything else, thats not the mcmod.info // copy everything else except the mcmod.info
from(sourceSets.main.resources.srcDirs) { from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info' exclude 'mcmod.info'
} }
@@ -23,119 +23,135 @@ import net.minecraftforge.common.config.Property;
/** /**
* The common proxy for wizardry, serving the usual purpose of dealing with all things that need to be handled * The common proxy for wizardry, serving the usual purpose of dealing with all things that need to be handled
* differently on the client and the server. A lot of the methods here appear to do absolutely nothing; this is * differently on the client and the server. A lot of the methods here appear to do absolutely nothing; this is because
* because they do client-only things which are only handled in the client proxy. * they do client-only things which are only handled in the client proxy.
*
* @see {@link electroblob.wizardry.client.ClientProxy} * @see {@link electroblob.wizardry.client.ClientProxy}
* @author Electroblob * @author Electroblob
* @since Wizardry 1.0 * @since Wizardry 1.0
* */ */
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public class CommonProxy { public class CommonProxy {
// SECTION Registry // SECTION Registry
// =============================================================================================================== // ===============================================================================================================
public void registerRenderers(){} public void registerRenderers(){
}
public void initialiseLayers(){
}
public void registerKeyBindings(){
}
public void initialiseLayers(){}
public void registerKeyBindings(){}
public void registerSpellHUD(){} public void registerSpellHUD(){}
public net.minecraft.client.model.ModelBiped getWizardArmourModel(){ return null; }
public void initMixedFontRenderer(){} public net.minecraft.client.model.ModelBiped getWizardArmourModel(){
return null;
}
public void initGuiBits(){}
// SECTION Particles // SECTION Particles
// =============================================================================================================== // ===============================================================================================================
/** /**
* Spawns a custom particle of the specified type. * Spawns a custom particle of the specified type.
* *
* @param type EnumParticleType of the particle * @param type EnumParticleType of the particle
* @param world Reference to the World object * @param world Reference to the World object
* @param x Particle x position * @param x Particle x position
* @param y Particle y position * @param y Particle y position
* @param z Particle z position * @param z Particle z position
* @param velX Particle x velocity * @param velX Particle x velocity
* @param velY Particle y velocity * @param velY Particle y velocity
* @param velZ Particle z velocity * @param velZ Particle z velocity
* @param maxAge Lifetime of the particle in ticks * @param maxAge Lifetime of the particle in ticks
* @param r Red component of particle colour; will be clamped to between 0 and 1 * @param r Red component of particle colour; will be clamped to between 0 and 1
* @param g Red component of particle colour; will be clamped to between 0 and 1 * @param g Red component of particle colour; will be clamped to between 0 and 1
* @param b Red component of particle colour; will be clamped to between 0 and 1 * @param b Red component of particle colour; will be clamped to between 0 and 1
* @param doGravity Whether the particle is affected by gravity (only affects SPARKLE at the moment) * @param doGravity Whether the particle is affected by gravity (only affects SPARKLE at the moment)
* @param radius The radius of the particle's motion, for cirular motion particles * @param radius The radius of the particle's motion, for cirular motion particles
*/ */
public void spawnParticle(WizardryParticleType type, World world, double x, double y, double z, double velX, double velY, double velZ, int maxAge, float r, float g, float b, boolean doGravity, double radius){ public void spawnParticle(WizardryParticleType type, World world, double x, double y, double z, double velX,
// Does nothing since particles are client-side only double velY, double velZ, int maxAge, float r, float g, float b, boolean doGravity, double radius){
} // Does nothing since particles are client-side only
}
/** Spawns a custom particle of the specified type. doGravity defaults to false and radius defaults to 0.
* Note that some of these settings may not affect the particle; some particles are always affected by /**
* gravity, for instance. * Spawns a custom particle of the specified type. doGravity defaults to false and radius defaults to 0. Note that
* * some of these settings may not affect the particle; some particles are always affected by gravity, for instance.
* @param type EnumParticleType of the particle *
* @param world Reference to the World object * @param type EnumParticleType of the particle
* @param x Particle x position * @param world Reference to the World object
* @param y Particle y position * @param x Particle x position
* @param z Particle z position * @param y Particle y position
* @param velX Particle x velocity * @param z Particle z position
* @param velY Particle y velocity * @param velX Particle x velocity
* @param velZ Particle z velocity * @param velY Particle y velocity
* @param maxAge Lifetime of the particle in ticks * @param velZ Particle z velocity
* @param r Red component of particle colour; will be clamped to between 0 and 1 (unless this is a MAGIC_FIRE particle, in which case this is the scale) * @param maxAge Lifetime of the particle in ticks
* @param g Red component of particle colour; will be clamped to between 0 and 1 * @param r Red component of particle colour; will be clamped to between 0 and 1 (unless this is a MAGIC_FIRE
* @param b Red component of particle colour; will be clamped to between 0 and 1 * particle, in which case this is the scale)
*/ * @param g Red component of particle colour; will be clamped to between 0 and 1
public void spawnParticle(WizardryParticleType type, World world, double x, double y, double z, double velX, double velY, double velZ, int maxAge, float r, float g, float b){ * @param b Red component of particle colour; will be clamped to between 0 and 1
this.spawnParticle(type, world, x, y, z, velX, velY, velZ, maxAge, r, g, b, false, 0); */
} public void spawnParticle(WizardryParticleType type, World world, double x, double y, double z, double velX,
double velY, double velZ, int maxAge, float r, float g, float b){
/** Spawns a custom particle of the specified type. Colour defaults to white, doGravity defaults to false and radius this.spawnParticle(type, world, x, y, z, velX, velY, velZ, maxAge, r, g, b, false, 0);
* defaults to 0. Note that some of these settings may not affect the particle; some particles are always affected by }
* gravity, for instance.
* /**
* @param type EnumParticleType of the particle * Spawns a custom particle of the specified type. Colour defaults to white, doGravity defaults to false and radius
* @param world Reference to the World object * defaults to 0. Note that some of these settings may not affect the particle; some particles are always affected
* @param x Particle x position * by gravity, for instance.
* @param y Particle y position *
* @param z Particle z position * @param type EnumParticleType of the particle
* @param velX Particle x velocity * @param world Reference to the World object
* @param velY Particle y velocity * @param x Particle x position
* @param velZ Particle z velocity * @param y Particle y position
* @param maxAge Lifetime of the particle in ticks * @param z Particle z position
*/ * @param velX Particle x velocity
public void spawnParticle(WizardryParticleType type, World world, double x, double y, double z, double velX, double velY, double velZ, int maxAge){ * @param velY Particle y velocity
this.spawnParticle(type, world, x, y, z, velX, velY, velZ, maxAge, 1, 1, 1, false, 0); * @param velZ Particle z velocity
} * @param maxAge Lifetime of the particle in ticks
*/
public void spawnTornadoParticle(World world, double x, double y, double z, double velX, double velZ, double radius, int maxAge, IBlockState block, BlockPos pos){} public void spawnParticle(WizardryParticleType type, World world, double x, double y, double z, double velX,
double velY, double velZ, int maxAge){
this.spawnParticle(type, world, x, y, z, velX, velY, velZ, maxAge, 1, 1, 1, false, 0);
}
public void spawnTornadoParticle(World world, double x, double y, double z, double velX, double velZ, double radius,
int maxAge, IBlockState block, BlockPos pos){
}
// SECTION Items // SECTION Items
// =============================================================================================================== // ===============================================================================================================
public net.minecraft.client.gui.FontRenderer getFontRenderer(ItemStack stack) { public net.minecraft.client.gui.FontRenderer getFontRenderer(ItemStack stack){
return null; return null;
} }
/** Returns the translated name of the scroll, taking spell discovery into account. If, for some reason, this gets /**
* Returns the translated name of the scroll, taking spell discovery into account. If, for some reason, this gets
* called server-side, it uses the deprecated server version of I18n, with a warning. Since any likely server-side * called server-side, it uses the deprecated server version of I18n, with a warning. Since any likely server-side
* use of this method will be for text-based logic purposes (like Bibliocraft's book checking system), and since no * use of this method will be for text-based logic purposes (like Bibliocraft's book checking system), and since no
* particular player instance can be accessed, spell discovery is ignored. */ * particular player instance can be accessed, spell discovery is ignored.
*/
public String getScrollDisplayName(ItemStack scroll){ public String getScrollDisplayName(ItemStack scroll){
// I have now learnt that the server side I18n always translates to the default en_US, so I could just return // I have now learnt that the server side I18n always translates to the default en_US, so I could just return
// a hardcoded name in English instead. // a hardcoded name in English instead.
Wizardry.logger.info("A mod has called ItemScroll#getItemStackDisplayName from the server side. Using the" Wizardry.logger.info("A mod has called ItemScroll#getItemStackDisplayName from the server side. Using the"
+ "deprecated server-side translation methods as a fallback."); + "deprecated server-side translation methods as a fallback.");
// Displays [Empty slot] if spell is continuous. // Displays [Empty slot] if spell is continuous.
Spell spell = Spell.get(scroll.getItemDamage()); Spell spell = Spell.get(scroll.getItemDamage());
if(spell.isContinuous) spell = Spells.none; if(spell.isContinuous) spell = Spells.none;
return I18n.translateToLocalFormatted("item.wizardry:wizardry:scroll.name", I18n.translateToLocal("spell." + spell.getUnlocalisedName())).trim(); return I18n.translateToLocalFormatted("item." + Wizardry.MODID + ":scroll.name",
I18n.translateToLocal("spell." + spell.getUnlocalisedName())).trim();
} }
public double getConjuredBowDurability(ItemStack stack){ public double getConjuredBowDurability(ItemStack stack){
@@ -144,33 +160,53 @@ public class CommonProxy {
// SECTION Packet Handlers // SECTION Packet Handlers
// =============================================================================================================== // ===============================================================================================================
public void handlePlayerSyncPacket(PacketPlayerSync.Message message){} public void handlePlayerSyncPacket(PacketPlayerSync.Message message){
public void handleGlyphDataPacket(PacketGlyphData.Message message){} }
public void handleCastSpellPacket(PacketCastSpell.Message message){}
public void handleCastContinuousSpellPacket(PacketCastContinuousSpell.Message message){} public void handleGlyphDataPacket(PacketGlyphData.Message message){
public void handleNPCCastSpellPacket(Message message){} }
public void handleTransportationPacket(PacketTransportation.Message message){}
public void handleClairvoyancePacket(PacketClairvoyance.Message message){} public void handleCastSpellPacket(PacketCastSpell.Message message){
}
public void handleCastContinuousSpellPacket(PacketCastContinuousSpell.Message message){
}
public void handleNPCCastSpellPacket(Message message){
}
public void handleTransportationPacket(PacketTransportation.Message message){
}
public void handleClairvoyancePacket(PacketClairvoyance.Message message){
}
// SECTION Misc // SECTION Misc
// =============================================================================================================== // ===============================================================================================================
public void setToNumberSliderEntry(Property property){} public void setToNumberSliderEntry(Property property){
//public void setToEntityNameEntry(Property property){} }
// public void setToEntityNameEntry(Property property){}
/** Plays a sound which moves with the given entity.
* /**
* @param entity The source of the sound * Plays a sound which moves with the given entity.
* @param sound The SoundEvent to play *
* @param volume Volume relative to 1 * @param entity The source of the sound
* @param pitch Pitch relative to 1 * @param sound The SoundEvent to play
* @param repeat Whether to repeat the sound for as long as the entity is alive (or until stopped manually) * @param volume Volume relative to 1
*/ * @param pitch Pitch relative to 1
public void playMovingSound(Entity entity, SoundEvent sound, float volume, float pitch, boolean repeat){} * @param repeat Whether to repeat the sound for as long as the entity is alive (or until stopped manually)
*/
/** Gets the client side world using Minecraft.getMinecraft().theWorld. <b>Only to be called client side!</b> public void playMovingSound(Entity entity, SoundEvent sound, float volume, float pitch, boolean repeat){
* Returns null on the server side. */ }
public World getTheWorld(){ return null; }
/**
* Gets the client side world using Minecraft.getMinecraft().world. <b>Only to be called client side!</b> Returns
* null on the server side.
*/
public World getTheWorld(){
return null;
}
} }
+344 -260
View File
@@ -1,6 +1,7 @@
package electroblob.wizardry; package electroblob.wizardry;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@@ -11,6 +12,7 @@ import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType; import electroblob.wizardry.util.MagicDamage.DamageType;
import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityList;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.translation.I18n; import net.minecraft.util.text.translation.I18n;
import net.minecraftforge.common.config.ConfigCategory; import net.minecraftforge.common.config.ConfigCategory;
import net.minecraftforge.common.config.Configuration; import net.minecraftforge.common.config.Configuration;
@@ -18,7 +20,8 @@ import net.minecraftforge.common.config.Property;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
/** Singleton class which deals with everything related to wizardry's config file. To access individual settings, use /**
* Singleton class which deals with everything related to wizardry's config file. To access individual settings, use
* {@link Wizardry#settings}. Also stores a few string constants for easy access. * {@link Wizardry#settings}. Also stores a few string constants for easy access.
* <p> * <p>
* As part of the 1.2 update and code overhaul, the way the config settings work in multiplayer has been tightened up. * As part of the 1.2 update and code overhaul, the way the config settings work in multiplayer has been tightened up.
@@ -28,22 +31,24 @@ import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
* has an effect if the local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world. Examples * has an effect if the local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world. Examples
* include worldgen, mob drops and commands. * include worldgen, mob drops and commands.
* <li>Synchronised settings. These settings affect both client-side AND server-side code, and are synchronised with * <li>Synchronised settings. These settings affect both client-side AND server-side code, and are synchronised with
* each client on login via {@link Settings#sync(EntityPlayerMP)}. Changing these locally * each client on login via {@link Settings#sync(EntityPlayerMP)}. Changing these locally only has an effect if the
* only has an effect if the local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world. * local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world. Examples include discovery mode
* Examples include discovery mode and crafting recipes. <i> Note that as far as users are concerned, * and crafting recipes. <i> Note that as far as users are concerned, there is no difference in behaviour between
* there is no difference in behaviour between server-only and synchronised settings.</i> * server-only and synchronised settings.</i>
* <li>Client-only settings. These settings only affect client-side code and hence are not synced. Each client obeys * <li>Client-only settings. These settings only affect client-side code and hence are not synced. Each client obeys its
* its own values for these, and changing them on a dedicated server will have no effect. These are usually only display * own values for these, and changing them on a dedicated server will have no effect. These are usually only display and
* and controls settings.</li> * controls settings.</li>
* <p> * <p>
* Each of the settings fields in this class is marked with one of the above categories to indicate which it belongs * Each of the settings fields in this class is marked with one of the above categories to indicate which it belongs to.
* to. This in turn dictates which logical side it should be called from: client, server or both. <b> Do not access a * This in turn dictates which logical side it should be called from: client, server or both. <b> Do not access a config
* config setting from the wrong side, because it may cause unexpected or strange behaviour.</b> * setting from the wrong side, because it may cause unexpected or strange behaviour.</b>
*
* @since Wizardry 1.2 * @since Wizardry 1.2
* @author Electroblob */ * @author Electroblob
// NOTE: We could convert over to the @Config system IF it is sufficiently complete in this Forge version for my purposes. */
// (For one, I know that the LangKey annotation is not applicable to type declarations in 1.10.2, unlike in 1.11.2) // TODO: New plan: convert to the @Config system BUT separate the spells config out so it doesn't break stuff. (Maybe even
//@Config(modid = Wizardry.MODID) // make it a JSON instead? Either way, there's scope for then adding more options for adjusting the base attributes etc.)
// @Config(modid = Wizardry.MODID)
@SuppressWarnings("deprecation") // Used server I18n deliberately; we want to write the comments in english. @SuppressWarnings("deprecation") // Used server I18n deliberately; we want to write the comments in english.
public final class Settings { public final class Settings {
@@ -58,15 +63,15 @@ public final class Settings {
public static final String COMMANDS_CATEGORY = "commands"; public static final String COMMANDS_CATEGORY = "commands";
/** The unlocalised name of the worldgen config category. */ /** The unlocalised name of the worldgen config category. */
public static final String WORLDGEN_CATEGORY = "worldgen"; public static final String WORLDGEN_CATEGORY = "worldgen";
/** The unlocalised name of the global config category. */ /** The unlocalised name of the gameplay config category. */
public static final String GLOBAL_CATEGORY = "global"; public static final String GAMEPLAY_CATEGORY = "gameplay";
/** The wizardry config file. */ /** The wizardry config file. */
private Configuration config; private Configuration config;
// Server-only settings. These only affect server-side code and hence are not synced. Changing these locally only // Server-only settings. These only affect server-side code and hence are not synced. Changing these locally only
// has an effect if the local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world. // has an effect if the local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world.
// Worldgen // Worldgen
/** <b>[Server-only]</b> The rarity of wizard towers, used by the world generator. Larger numbers are rarer. */ /** <b>[Server-only]</b> The rarity of wizard towers, used by the world generator. Larger numbers are rarer. */
public int towerRarity = 8; public int towerRarity = 8;
@@ -76,33 +81,53 @@ public final class Settings {
public int[] flowerDimensions = {0}; public int[] flowerDimensions = {0};
/** <b>[Server-only]</b> List of dimension ids in which to generate crystal ore. */ /** <b>[Server-only]</b> List of dimension ids in which to generate crystal ore. */
public int[] towerDimensions = {0}; public int[] towerDimensions = {0};
/** <b>[Server-only]</b> Whether or not wizardry loot should generate in dungeon chests. Note that this does not /**
* affect the generation of loot in wizard towers. */ * <b>[Server-only]</b> Whether or not wizardry loot should generate in dungeon chests. Note that this does not
* affect the generation of loot in wizard towers.
*/
public boolean generateLoot = true; public boolean generateLoot = true;
// Entities' drops, targeting, damage, etc. // Entities' drops, targeting, damage, etc.
/** <b>[Server-only]</b> Chance (out of 200) for mobs to drop spell books. */ /** <b>[Server-only]</b> Chance (out of 200) for mobs to drop spell books. */
public int spellBookDropChance = 3; public int spellBookDropChance = 3;
/** <b>[Server-only]</b> Whether or not players can teleport through unbreakable blocks (e.g. bedrock) using the phase step spell. */ /**
* <b>[Server-only]</b> Whether or not players can teleport through unbreakable blocks (e.g. bedrock) using the
* phase step spell.
*/
public boolean teleportThroughUnbreakableBlocks = false; public boolean teleportThroughUnbreakableBlocks = false;
/** <b>[Server-only]</b> Whether to allow players to damage their designated allies using magic. */ /** <b>[Server-only]</b> Whether to allow players to damage their designated allies using magic. */
public boolean friendlyFire = true; public boolean friendlyFire = true;
/** <b>[Server-only]</b> Whether to allow players to disarm other players using the telekinesis spell. */ /** <b>[Server-only]</b> Whether to allow players to disarm other players using the telekinesis spell. */
public boolean telekineticDisarmament = true; public boolean telekineticDisarmament = true;
/** <b>[Server-only]</b> Whether summoned creatures can revenge attack their caster if their caster attacks them. */ /** <b>[Server-only]</b> Whether summoned creatures can revenge attack their caster if their caster attacks them. */
public boolean minionRevengeTargeting = true; public boolean minionRevengeTargeting = true;
/** <b>[Server-only]</b> List of names of entities which summoned creatures are allowed to attack, in addition to the defaults. */ /**
public String[] summonedCreatureTargetsWhitelist = {}; * <b>[Server-only]</b> List of registry names of entities which summoned creatures are allowed to attack, in addition
/** <b>[Server-only]</b> List of names of entities which summoned creatures are specifically not allowed to attack, overriding the defaults and the whitelist. */ * to the defaults.
public String[] summonedCreatureTargetsBlacklist = {"creeper"}; */
public ResourceLocation[] summonedCreatureTargetsWhitelist = {};
/**
* <b>[Server-only]</b> List of registry names of entities which summoned creatures are specifically not allowed to
* attack, overriding the defaults and the whitelist.
*/
public ResourceLocation[] summonedCreatureTargetsBlacklist = {new ResourceLocation("creeper")};
/**
* <b>[Server-only]</b> List of registry names of entities which are immune to the mind control spell, in addition to
* the defaults.
*/
public ResourceLocation[] mindControlTargetsBlacklist = {};
/** <b>[Server-only]</b> Global damage scaling factor for all player magic damage. */ /** <b>[Server-only]</b> Global damage scaling factor for all player magic damage. */
public double playerDamageScale = 1.0f; public double playerDamageScale = 1.0f;
/** <b>[Server-only]</b> Global damage scaling factor for all npc magic damage. */ /** <b>[Server-only]</b> Global damage scaling factor for all npc magic damage. */
public double npcDamageScale = 1.0f; public double npcDamageScale = 1.0f;
/** <b>[Server-only]</b> List of dimension ids in which evil wizards can spawn. */
public int[] evilWizardDimensions = {0};
// Commands (these don't need synchronising since typing a command always queries the server). // Commands (these don't need synchronising since typing a command always queries the server).
/** <b>[Server-only]</b> The maximum allowed multiplier for the /cast command. This limit is here to stop people from accidentally /**
* breaking their worlds! */ * <b>[Server-only]</b> The maximum allowed multiplier for the /cast command. This limit is here to stop people from
* accidentally breaking their worlds!
*/
public double maxSpellCommandMultiplier = 20d; public double maxSpellCommandMultiplier = 20d;
/** <b>[Server-only]</b> The name of the /cast command. */ /** <b>[Server-only]</b> The name of the /cast command. */
public String castCommandName = "cast"; public String castCommandName = "cast";
@@ -112,31 +137,26 @@ public final class Settings {
public String allyCommandName = "ally"; public String allyCommandName = "ally";
/** <b>[Server-only]</b> The name of the /allies command. */ /** <b>[Server-only]</b> The name of the /allies command. */
public String alliesCommandName = "allies"; public String alliesCommandName = "allies";
// Synchronised settings. These settings affect both client-side AND server-side code. Changing these locally // Synchronised settings. These settings affect both client-side AND server-side code. Changing these locally
// only has an effect if the local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world. // only has an effect if the local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world.
// Recipes (only need syncing for display in the wizard's handbook)
/** <b>[Synchronised]</b> Whether or not firebombs should be craftable. */
public boolean firebombIsCraftable = true;
/** <b>[Synchronised]</b> Whether or not poison bombs should be craftable. */
public boolean poisonBombIsCraftable = true;
/** <b>[Synchronised]</b> Whether or not poison bombs should be craftable. */
public boolean smokeBombIsCraftable = true;
/** <b>[Synchronised]</b> Whether to require a magic crystal in the blank scroll crafting recipe (in case it conflicts with another mod). */
public boolean useAlternateScrollRecipe = false;
// Gamemodes // Gamemodes
/** <b>[Synchronised]</b> When set to true, spells a player hasn't cast yet will be unreadable until they are cast (on a per-world basis). Has no effect when in creative mode. Spells of /**
* identification will be unobtainable in survival mode if this is false. */ * <b>[Synchronised]</b> When set to true, spells a player hasn't cast yet will be unreadable until they are cast
* (on a per-world basis). Has no effect when in creative mode. Spells of identification will be unobtainable in
* survival mode if this is false.
*/
public boolean discoveryMode = true; public boolean discoveryMode = true;
// Client-only settings. These settings only affect client-side code and hence are not synced. Each client obeys // Client-only settings. These settings only affect client-side code and hence are not synced. Each client obeys
// its own values for these, and changing them on a dedicated server will have no effect. // its own values for these, and changing them on a dedicated server will have no effect.
// Controls // Controls
/** <b>[Client-only]</b> Whether the player can switch between spells on a wand by scrolling with the mouse wheel while /**
* sneaking. */ * <b>[Client-only]</b> Whether the player can switch between spells on a wand by scrolling with the mouse wheel
* while sneaking.
*/
public boolean enableShiftScrolling = true; public boolean enableShiftScrolling = true;
// Display // Display
@@ -144,103 +164,119 @@ public final class Settings {
public boolean showSummonedCreatureNames = true; public boolean showSummonedCreatureNames = true;
/** <b>[Client-only]</b> The position of the spell HUD. */ /** <b>[Client-only]</b> The position of the spell HUD. */
public GuiPosition spellHUDPosition = GuiPosition.BOTTOM_LEFT; public GuiPosition spellHUDPosition = GuiPosition.BOTTOM_LEFT;
/** Set of constants for each of the four positions that the spell HUD can be in. */ /** Set of constants for each of the four positions that the spell HUD can be in. */
public enum GuiPosition { public enum GuiPosition {
BOTTOM_LEFT("Bottom left"), BOTTOM_LEFT("Bottom left"), TOP_LEFT("Top left"), TOP_RIGHT("Top right"), BOTTOM_RIGHT("Bottom right");
TOP_LEFT("Top left"),
TOP_RIGHT("Top right"),
BOTTOM_RIGHT("Bottom right");
/** Constant array storing the names of each of the constants, in the order they are declared. */ /** Constant array storing the names of each of the constants, in the order they are declared. */
public static final String[] names; public static final String[] names;
static { static{
names = new String[values().length]; names = new String[values().length];
for(GuiPosition position : values()){ for(GuiPosition position : values()){
names[position.ordinal()] = position.name; names[position.ordinal()] = position.name;
} }
} }
/** The readable name for this GUI position that will be displayed on the button in the config GUI. */ /** The readable name for this GUI position that will be displayed on the button in the config GUI. */
public final String name; public final String name;
GuiPosition(String name){ GuiPosition(String name){
this.name = name; this.name = name;
} }
/** Gets a GUI position from its string name (ignoring case), or BOTTOM_LEFT if the given name is not a valid position. */ /**
* Gets a GUI position from its string name (ignoring case), or BOTTOM_LEFT if the given name is not a valid
* position.
*/
public static GuiPosition fromName(String name){ public static GuiPosition fromName(String name){
for(GuiPosition position : values()){ for(GuiPosition position : values()){
if(position.name.equalsIgnoreCase(name)) return position; if(position.name.equalsIgnoreCase(name)) return position;
} }
Wizardry.logger.info("Invalid string for the spell HUD position. Using default (bottom left) instead."); Wizardry.logger.info("Invalid string for the spell HUD position. Using default (bottom left) instead.");
return BOTTOM_LEFT; return BOTTOM_LEFT;
} }
} }
// As of Wizardry 1.1, all keys used in the config file itself are now hardcoded, not localised. The localisations // As of Wizardry 1.1, all keys used in the config file itself are now hardcoded, not localised. The localisations
// are done in the config GUI. The config file has to be written in one language or it will end up with multiple // are done in the config GUI. The config file has to be written in one language or it will end up with multiple
// options for different languages. // options for different languages.
// These methods are package-protected to stop anyone else from calling them. // These methods are package-protected to stop anyone else from calling them.
/** Called from preInit to initialise the config file. The first part of the config file has to be done here (as is /**
* Called from preInit to initialise the config file. The first part of the config file has to be done here (as is
* conventional) so that the various registries can change what they do accordingly. The spell part of the config * conventional) so that the various registries can change what they do accordingly. The spell part of the config
* has to be done in the init method.*/ * and the resistance part of the config have to be done in the init method since they depend on the registry events.
*/
void initConfig(FMLPreInitializationEvent event){ void initConfig(FMLPreInitializationEvent event){
config = new Configuration(event.getSuggestedConfigurationFile()); config = new Configuration(event.getSuggestedConfigurationFile());
config.load(); config.load();
Wizardry.logger.info("Setting up main config"); Wizardry.logger.info("Setting up main config");
setupGeneralConfig(); setupGeneralConfig();
setupWorldgenConfig();
config.save(); setupClientConfig();
} setupCommandsConfig();
/** Called from init to initialise the parts of the config file that depend on other mods. For example, the spell
* config is done here and not in preInit because all spells must be registered before it is added, including
* those in other mods. */
void initConfigExtras(){
Wizardry.logger.info("Setting up spells config for " + Spell.getTotalSpellCount() + " spells");
setupSpellsConfig();
config.save(); config.save();
} }
/**
* Called from init to initialise the parts of the config file that have to be done after registry events are fired.
* For example, the spell config is done here and not in preInit because all spells must be registered before it is
* added, including those in other mods.
*/
void initConfigExtras(){
Wizardry.logger.info("Setting up spells config for " + Spell.getTotalSpellCount() + " spells");
setupSpellsConfig();
Wizardry.logger.info("Setting up resistances config");
setupResistancesConfig();
config.save();
}
/** Called to save changes to the config file after it has been edited in game from the menus. */ /** Called to save changes to the config file after it has been edited in game from the menus. */
void saveConfigChanges(){ void saveConfigChanges(){
Wizardry.logger.info("Saving in-game config changes"); Wizardry.logger.info("Saving in-game config changes");
setupGeneralConfig(); setupGeneralConfig();
setupWorldgenConfig();
setupClientConfig();
setupCommandsConfig();
setupSpellsConfig(); setupSpellsConfig();
setupResistancesConfig();
config.save(); config.save();
} }
/** Sends a packet to the specified player's client containing all the <b>synchronised</b> settings. */ /** Sends a packet to the specified player's client containing all the <b>synchronised</b> settings. */
public void sync(EntityPlayerMP player){ public void sync(EntityPlayerMP player){
Wizardry.logger.info("Synchronising config settings for " + player.getName()); Wizardry.logger.info("Synchronising config settings for " + player.getName());
IMessage message = new PacketSyncSettings.Message(this); IMessage message = new PacketSyncSettings.Message(this);
WizardryPacketHandler.net.sendTo(message, player); WizardryPacketHandler.net.sendTo(message, player);
} }
public ConfigCategory getConfigCategory(String name){ public ConfigCategory getConfigCategory(String name){
return config.getCategory(name); return config.getCategory(name);
} }
private void setupSpellsConfig(){ private void setupSpellsConfig(){
config.addCustomCategoryComment(SPELLS_CATEGORY, "Set a spell to false to disable it. Disabled spells will still have their associated spell book (mainly so the spell books don't all change) and can still be bound to wands, but cannot be cast in game, will not appear in any subsequently generated chests or wizard trades and will not drop from mobs. Disable a spell if it is causing problems, conflicts with another mod or creates an unintended exploit."); config.addCustomCategoryComment(SPELLS_CATEGORY,
"Set a spell to false to disable it. Disabled spells will still have their associated spell book (mainly so the spell books don't all change) and can still be bound to wands, but cannot be cast in game, will not appear in any subsequently generated chests or wizard trades and will not drop from mobs. Disable a spell if it is causing problems, conflicts with another mod or creates an unintended exploit.");
Property property; Property property;
@@ -261,247 +297,295 @@ public final class Settings {
Property property; Property property;
config.addCustomCategoryComment(Configuration.CATEGORY_GENERAL, "Please note that changing some of these settings may make the mod very difficult to play."); config.addCustomCategoryComment(GAMEPLAY_CATEGORY, "Global settings that affect game mechanics. In multiplayer, the server/LAN host settings will apply. Please note that changing some of these settings may make the mod very difficult to play.");
property = config.get(Configuration.CATEGORY_GENERAL, "towerRarity", 8, "Rarity of wizard towers. Higher numbers are rarer. Set to 0 to disable wizard towers completely.", 0, 50); property = config.get(GAMEPLAY_CATEGORY, "discoveryMode", true,
property.setLanguageKey("config.wizardry.tower_rarity"); "For those who like a sense of mystery! When set to true, spells you haven't cast yet will be unreadable until you cast them (on a per-world basis). Has no effect when in creative mode. Spells of identification will be unobtainable in survival mode if this is false.");
property.setLanguageKey("config." + Wizardry.MODID + ".discovery_mode");
property.setRequiresWorldRestart(true);
discoveryMode = property.getBoolean();
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "friendlyFire", true,
"Whether to allow players to damage their designated allies using magic.");
property.setLanguageKey("config." + Wizardry.MODID + ".friendly_fire");
friendlyFire = property.getBoolean();
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "spellBookDropChance", 3,
"The chance for mobs to drop a spell book when killed. The greater this number, the more often they will drop. Set to 0 to disable spell book drops. Set to 200 for guaranteed drops.",
0, 200);
property.setLanguageKey("config." + Wizardry.MODID + ".spell_book_drop_chance");
Wizardry.proxy.setToNumberSliderEntry(property);
spellBookDropChance = property.getInt();
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "evilWizardDimensions", new int[]{0},
"List of dimension ids in which evil wizards can spawn.");
property.setLanguageKey("config." + Wizardry.MODID + ".evil_wizard_dimensions");
property.setRequiresMcRestart(true);
evilWizardDimensions = property.getIntList();
propOrder.add(property.getName());
// These two aren't sliders because using a slider makes it difficult to fine-tune the numbers; the nature of a
// scaling factor means that 0.5 is as big a change as 2.0, so whilst a slider is fine for increasing the
// damage, it doesn't give fine enough control for values less than 1.
property = config.get(GAMEPLAY_CATEGORY, "playerDamageScaling", 1.0,
"Global damage scaling factor for the damage dealt by players casting spells, relative to 1.", 0, 20);
property.setLanguageKey("config." + Wizardry.MODID + ".player_damage_scaling");
playerDamageScale = property.getDouble();
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "npcDamageScaling", 1.0,
"Global damage scaling factor for the damage dealt by NPCs casting spells, relative to 1.", 0, 20);
property.setLanguageKey("config." + Wizardry.MODID + ".npc_damage_scaling");
npcDamageScale = property.getDouble();
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "minionRevengeTargeting", true,
"Whether summoned creatures can revenge attack their owner if their owner attacks them.");
property.setLanguageKey("config." + Wizardry.MODID + ".minion_revenge_targeting");
property.setRequiresWorldRestart(false);
minionRevengeTargeting = property.getBoolean();
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "summonedCreatureTargetsWhitelist", new String[0],
"List of names of entities which summoned creatures and wizards are allowed to attack, in addition to the defaults. Add mod creatures to this list if you want summoned creatures to attack them and they aren't already doing so. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
property.setLanguageKey("config." + Wizardry.MODID + ".summoned_creature_targets_whitelist");
property.setRequiresWorldRestart(true);
// Converts all strings in the list to a ResourceLocation.
summonedCreatureTargetsWhitelist = Arrays.stream(property.getStringList()).map(s -> new ResourceLocation(s.toLowerCase(Locale.ROOT).trim())).toArray(ResourceLocation[]::new);
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "summonedCreatureTargetsBlacklist",
new String[]{"creeper"},
"List of names of entities which summoned creatures and wizards are specifically not allowed to attack, overriding the defaults and the whitelist. Add creatures to this list if allowing them to be attacked causes problems or is too destructive (removing creepers from this list is done at your own risk!). Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
property.setLanguageKey("config." + Wizardry.MODID + ".summoned_creature_targets_blacklist");
property.setRequiresWorldRestart(true);
// Converts all strings in the list to a ResourceLocation.
summonedCreatureTargetsBlacklist = Arrays.stream(property.getStringList()).map(s -> new ResourceLocation(s.toLowerCase(Locale.ROOT).trim())).toArray(ResourceLocation[]::new);
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "telekineticDisarmament", true,
"Whether to allow players to disarm other players using the telekinesis spell. Set to false to prevent stealing of items.");
property.setLanguageKey("config." + Wizardry.MODID + ".telekinetic_disarmament");
telekineticDisarmament = property.getBoolean();
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "teleportThroughUnbreakableBlocks", false,
"Whether players are allowed to teleport through unbreakable blocks (e.g. bedrock) using the phase step spell.");
property.setLanguageKey("config." + Wizardry.MODID + ".teleport_through_unbreakable_blocks");
teleportThroughUnbreakableBlocks = property.getBoolean();
propOrder.add(property.getName());
property = config.get(GAMEPLAY_CATEGORY, "mindControlTargetsBlacklist", new String[]{},
"List of names of entities which cannot be mind controlled, in addition to the defaults. Add creatures to this list if allowing them to be mind-controlled causes problems or could be exploited. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
property.setLanguageKey("config." + Wizardry.MODID + ".mind_control_targets_blacklist");
property.setRequiresWorldRestart(true);
// Converts all strings in the list to a ResourceLocation.
mindControlTargetsBlacklist = Arrays.stream(property.getStringList()).map(s -> new ResourceLocation(s.toLowerCase(Locale.ROOT).trim())).toArray(ResourceLocation[]::new);
propOrder.add(property.getName());
config.setCategoryPropertyOrder(GAMEPLAY_CATEGORY, propOrder);
}
private void setupWorldgenConfig(){
// This trick is borrowed from forge; it sorts the config options into the order you want them.
List<String> propOrder = new ArrayList<String>();
Property property;
config.addCustomCategoryComment(WORLDGEN_CATEGORY, "Settings that affect world generation. In multiplayer, the server/LAN host settings will apply.");
property = config.get(WORLDGEN_CATEGORY, "towerRarity", 8, "Rarity of wizard towers. Higher numbers are rarer. Set to 0 to disable wizard towers completely.", 0, 50);
property.setLanguageKey("config." + Wizardry.MODID + ".tower_rarity");
property.setRequiresWorldRestart(true); property.setRequiresWorldRestart(true);
Wizardry.proxy.setToNumberSliderEntry(property); Wizardry.proxy.setToNumberSliderEntry(property);
towerRarity = property.getInt(); towerRarity = property.getInt();
propOrder.add(property.getName()); propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "spellBookDropChance", 3, "The chance for mobs to drop a spell book when killed. The greater this number, the more often they will drop. Set to 0 to disable spell book drops. Set to 200 for guaranteed drops.", 0, 200); property = config.get(WORLDGEN_CATEGORY, "towerDimensions", new int[]{0}, "List of dimension ids in which wizard towers will generate.");
property.setLanguageKey("config.wizardry.spell_book_drop_chance"); property.setLanguageKey("config." + Wizardry.MODID + ".tower_dimensions");
Wizardry.proxy.setToNumberSliderEntry(property);
spellBookDropChance = property.getInt();
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "oreDimensions", new int[]{0}, "List of dimension ids in which crystal ore will generate. Note that removing the overworld (id 0) from this list will make the mod VERY difficult to play!");
property.setLanguageKey("config.wizardry.ore_dimensions");
property.setRequiresWorldRestart(true);
oreDimensions = property.getIntList();
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "flowerDimensions", new int[]{0}, "List of dimension ids in which crystal flowers will generate.");
property.setLanguageKey("config.wizardry.flower_dimensions");
property.setRequiresWorldRestart(true);
flowerDimensions = property.getIntList();
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "towerDimensions", new int[]{0}, "List of dimension ids in which wizard towers will generate.");
property.setLanguageKey("config.wizardry.tower_dimensions");
property.setRequiresWorldRestart(true); property.setRequiresWorldRestart(true);
towerDimensions = property.getIntList(); towerDimensions = property.getIntList();
propOrder.add(property.getName()); propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "generateLoot", true, "Whether to generate wizardry loot in dungeon chests."); property = config.get(WORLDGEN_CATEGORY, "oreDimensions", new int[]{0}, "List of dimension ids in which crystal ore will generate. Note that removing the overworld (id 0) from this list will make the mod VERY difficult to play!");
property.setLanguageKey("config.wizardry.generate_loot"); property.setLanguageKey("config." + Wizardry.MODID + ".ore_dimensions");
property.setRequiresWorldRestart(true);
oreDimensions = property.getIntList();
propOrder.add(property.getName());
property = config.get(WORLDGEN_CATEGORY, "flowerDimensions", new int[]{0}, "List of dimension ids in which crystal flowers will generate.");
property.setLanguageKey("config." + Wizardry.MODID + ".flower_dimensions");
property.setRequiresWorldRestart(true);
flowerDimensions = property.getIntList();
propOrder.add(property.getName());
property = config.get(WORLDGEN_CATEGORY, "generateLoot", true, "Whether to inject wizardry loot (as specified in loot_tables/chests/dungeon_additions.json) into the loot tables for vanilla dungeon chests.");
property.setLanguageKey("config." + Wizardry.MODID + ".generate_loot");
property.setRequiresWorldRestart(true); property.setRequiresWorldRestart(true);
generateLoot = property.getBoolean(); generateLoot = property.getBoolean();
propOrder.add(property.getName()); propOrder.add(property.getName());
config.setCategoryPropertyOrder(WORLDGEN_CATEGORY, propOrder);
}
private void setupClientConfig(){
property = config.get(Configuration.CATEGORY_GENERAL, "firebombIsCraftable", true, "Whether firebombs can be crafted or not."); // This trick is borrowed from forge; it sorts the config options into the order you want them.
property.setLanguageKey("config.wizardry.firebomb_is_craftable"); List<String> propOrder = new ArrayList<String>();
property.setRequiresMcRestart(true);
firebombIsCraftable = property.getBoolean();
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "poisonBombIsCraftable", true, "Whether poison bombs can be crafted or not."); Property property;
property.setLanguageKey("config.wizardry.poison_bomb_is_craftable");
property.setRequiresMcRestart(true);
poisonBombIsCraftable = property.getBoolean();
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "smokeBombIsCraftable", true, "Whether smoke bombs can be crafted or not."); config.addCustomCategoryComment(CLIENT_CATEGORY, "Client-side settings that only affect the local minecraft game. If this file is on a dedicated server, these settings will have no effect; in multiplayer, each player obeys their own settings.");
property.setLanguageKey("config.wizardry.smoke_bomb_is_craftable");
property.setRequiresMcRestart(true);
smokeBombIsCraftable = property.getBoolean();
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "useAlternateScrollRecipe", false, "Whether to require a magic crystal in the shapeless crafting recipe for blank scrolls. Set to true if another mod adds a conflicting recipe."); property = config.get(CLIENT_CATEGORY, "enableShiftScrolling", true,
property.setLanguageKey("config.wizardry.use_alternate_scroll_recipe"); "Whether you can switch between spells on a wand by scrolling with the mouse wheel while sneaking. Note that this will only affect you; other players connected to the same server obey their own settings.");
property.setRequiresMcRestart(true); property.setLanguageKey("config." + Wizardry.MODID + ".enable_shift_scrolling");
useAlternateScrollRecipe = property.getBoolean();
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "teleportThroughUnbreakableBlocks", false, "Whether players are allowed to teleport through unbreakable blocks (e.g. bedrock) using the phase step spell.");
property.setLanguageKey("config.wizardry.teleport_through_unbreakable_blocks");
teleportThroughUnbreakableBlocks = property.getBoolean();
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "showSummonedCreatureNames", true, "Whether to show summoned creatures' names and owners above their heads.");
property.setLanguageKey("config.wizardry.show_summoned_creature_names");
showSummonedCreatureNames = property.getBoolean();
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "friendlyFire", true, "Whether to allow players to damage their designated allies using magic.");
property.setLanguageKey("config.wizardry.friendly_fire");
friendlyFire = property.getBoolean();
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "telekineticDisarmament", true, "Whether to allow players to disarm other players using the telekinesis spell. Set to false to prevent stealing of items.");
property.setLanguageKey("config.wizardry.telekinetic_disarmament");
telekineticDisarmament = property.getBoolean();
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "discoveryMode", true, "For those who like a sense of mystery! When set to true, spells you haven't cast yet will be unreadable until you cast them (on a per-world basis). Has no effect when in creative mode. Spells of identification will be unobtainable in survival mode if this is false.");
property.setLanguageKey("config.wizardry.discovery_mode");
property.setRequiresWorldRestart(true);
discoveryMode = property.getBoolean();
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "enableShiftScrolling", true, "Whether you can switch between spells on a wand by scrolling with the mouse wheel while sneaking. Note that this will only affect you; other players connected to the same server obey their own settings.");
property.setLanguageKey("config.wizardry.enable_shift_scrolling");
property.setRequiresWorldRestart(false); property.setRequiresWorldRestart(false);
enableShiftScrolling = property.getBoolean(); enableShiftScrolling = property.getBoolean();
propOrder.add(property.getName()); propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "minionRevengeTargeting", true, "Whether summoned creatures can revenge attack their owner if their owner attacks them."); property = config.get(CLIENT_CATEGORY, "spellHUDPosition", GuiPosition.BOTTOM_LEFT.name, "The position of the spell HUD.", GuiPosition.names);
property.setLanguageKey("config.wizardry.minion_revenge_targeting"); property.setLanguageKey("config." + Wizardry.MODID + ".spell_hud_position");
property.setRequiresWorldRestart(false);
minionRevengeTargeting = property.getBoolean();
propOrder.add(property.getName());
// These two aren't sliders because using a slider makes it difficult to fine-tune the numbers; the nature of a
// scaling factor means that 0.5 is as big a change as 2.0, so whilst a slider is fine for increasing the damage,
// it doesn't give fine enough control for values less than 1.
property = config.get(Configuration.CATEGORY_GENERAL, "playerDamageScaling", 1.0, "Global damage scaling factor for the damage dealt by players casting spells, relative to 1.", 0, 20);
property.setLanguageKey("config.wizardry.player_damage_scaling");
playerDamageScale = property.getDouble();
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "npcDamageScaling", 1.0, "Global damage scaling factor for the damage dealt by NPCs casting spells, relative to 1.", 0, 20);
property.setLanguageKey("config.wizardry.npc_damage_scaling");
npcDamageScale = property.getDouble();
propOrder.add(property.getName());
// This one isn't a slider either because people are likely to want exact values ("it must be at most 50.3" is a bit strange!).
property = config.get(Configuration.CATEGORY_GENERAL, "castCommandMultiplierLimit", 20.0, "Upper limit for the multipliers passed into the /cast command. This is here to stop players from accidentally breaking a world/server. Large blast mutipliers can cause extreme lag - you have been warned!", 1, 255);
property.setLanguageKey("config.wizardry.cast_command_multiplier_limit");
maxSpellCommandMultiplier = property.getDouble();
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "summonedCreatureTargetsWhitelist", new String[0], "List of names of entities which summoned creatures and wizards are allowed to attack, in addition to the defaults. Add mod creatures to this list if you want summoned creatures to attack them and they aren't already doing so. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard).");
property.setLanguageKey("config.wizardry.summoned_creature_targets_whitelist");
property.setRequiresWorldRestart(true);
//Wizardry.proxy.setToEntityNameEntry(property);
summonedCreatureTargetsWhitelist = property.getStringList();
// Converts all strings in the list to lower case, to ignore case sensitivity, and trims them.
for(int i=0; i<summonedCreatureTargetsWhitelist.length; i++){
summonedCreatureTargetsWhitelist[i] = summonedCreatureTargetsWhitelist[i].toLowerCase(Locale.ROOT).trim();
}
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "summonedCreatureTargetsBlacklist", new String[]{"creeper"}, "List of names of entities which summoned creatures and wizards are specifically not allowed to attack, overriding the defaults and the whitelist. Add creatures to this list if allowing them to be attacked causes problems or is too destructive (removing creepers from this list is done at your own risk!). Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard).");
property.setLanguageKey("config.wizardry.summoned_creature_targets_blacklist");
property.setRequiresWorldRestart(true);
//Wizardry.proxy.setToEntityNameEntry(property);
summonedCreatureTargetsBlacklist = property.getStringList();
// Converts all strings in the list to lower case, to ignore case sensitivity, and trims them.
for(int i=0; i<summonedCreatureTargetsBlacklist.length; i++){
summonedCreatureTargetsBlacklist[i] = summonedCreatureTargetsBlacklist[i].toLowerCase(Locale.ROOT).trim();
}
propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "spellHUDPosition", GuiPosition.BOTTOM_LEFT.name, "The position of the spell HUD.", GuiPosition.names);
property.setLanguageKey("config.wizardry.spell_hud_position");
spellHUDPosition = GuiPosition.fromName(property.getString()); spellHUDPosition = GuiPosition.fromName(property.getString());
propOrder.add(property.getName()); propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "castCommandName", "cast", "The name of the /cast command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /cast you would type /magic instead."); property = config.get(CLIENT_CATEGORY, "showSummonedCreatureNames", true, "Whether to show summoned creatures' names and owners above their heads.");
property.setLanguageKey("config.wizardry.cast_command_name"); property.setLanguageKey("config." + Wizardry.MODID + ".show_summoned_creature_names");
showSummonedCreatureNames = property.getBoolean();
propOrder.add(property.getName());
config.setCategoryPropertyOrder(CLIENT_CATEGORY, propOrder);
}
private void setupCommandsConfig(){
// This trick is borrowed from forge; it sorts the config options into the order you want them.
List<String> propOrder = new ArrayList<String>();
Property property;
config.addCustomCategoryComment(COMMANDS_CATEGORY, "Settings for the commands added by Wizardry. In multiplayer, the server/LAN host settings will apply.");
// This one isn't a slider either because people are likely to want exact values ("it must be at most 50.3" is a
// bit strange!).
property = config.get(COMMANDS_CATEGORY, "castCommandMultiplierLimit", 20.0,
"Upper limit for the multipliers passed into the /cast command. This is here to stop players from accidentally breaking a world/server. Large blast mutipliers can cause extreme lag - you have been warned!",
1, 255);
property.setLanguageKey("config." + Wizardry.MODID + ".cast_command_multiplier_limit");
maxSpellCommandMultiplier = property.getDouble();
propOrder.add(property.getName());
property = config.get(COMMANDS_CATEGORY, "castCommandName", "cast",
"The name of the /cast command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /cast you would type /magic instead.");
property.setLanguageKey("config." + Wizardry.MODID + ".cast_command_name");
property.setRequiresWorldRestart(true); property.setRequiresWorldRestart(true);
castCommandName = property.getString(); castCommandName = property.getString();
propOrder.add(property.getName()); propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "discoverspellCommandName", "discoverspell", "The name of the /discoverspell command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /discoverspell you would type /magic instead."); property = config.get(COMMANDS_CATEGORY, "discoverspellCommandName", "discoverspell",
property.setLanguageKey("config.wizardry.discoverspell_command_name"); "The name of the /discoverspell command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /discoverspell you would type /magic instead.");
property.setLanguageKey("config." + Wizardry.MODID + ".discoverspell_command_name");
property.setRequiresWorldRestart(true); property.setRequiresWorldRestart(true);
discoverspellCommandName = property.getString(); discoverspellCommandName = property.getString();
propOrder.add(property.getName()); propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "allyCommandName", "ally", "The name of the /ally command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /ally you would type /magic instead."); property = config.get(COMMANDS_CATEGORY, "allyCommandName", "ally",
property.setLanguageKey("config.wizardry.ally_command_name"); "The name of the /ally command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /ally you would type /magic instead.");
property.setLanguageKey("config." + Wizardry.MODID + ".ally_command_name");
property.setRequiresWorldRestart(true); property.setRequiresWorldRestart(true);
allyCommandName = property.getString(); allyCommandName = property.getString();
propOrder.add(property.getName()); propOrder.add(property.getName());
property = config.get(Configuration.CATEGORY_GENERAL, "alliesCommandName", "allies", "The name of the /allies command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /allies you would type /magic instead."); property = config.get(COMMANDS_CATEGORY, "alliesCommandName", "allies",
property.setLanguageKey("config.wizardry.allies_command_name"); "The name of the /allies command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /allies you would type /magic instead.");
property.setLanguageKey("config." + Wizardry.MODID + ".allies_command_name");
property.setRequiresWorldRestart(true); property.setRequiresWorldRestart(true);
alliesCommandName = property.getString(); alliesCommandName = property.getString();
propOrder.add(property.getName()); propOrder.add(property.getName());
config.setCategoryPropertyOrder(COMMANDS_CATEGORY, propOrder);
}
config.setCategoryPropertyOrder(Configuration.CATEGORY_GENERAL, propOrder); private void setupResistancesConfig(){
// Resistances Property property;
List<String> propOrder1 = new ArrayList<String>(); List<String> propOrder = new ArrayList<String>();
config.addCustomCategoryComment(RESISTANCES_CATEGORY, "Settings which allow entities to be made immune to certain types of magic. In multiplayer, the server/LAN host settings will apply."); config.addCustomCategoryComment(RESISTANCES_CATEGORY,
"Settings which allow entities to be made immune to certain types of magic. In multiplayer, the server/LAN host settings will apply.");
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToFire", new String[]{}, "List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard)."); property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToFire", new String[]{},
property.setLanguageKey("config.wizardry.mobs_immune_to_fire"); "List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_fire");
property.setRequiresMcRestart(true); property.setRequiresMcRestart(true);
//Wizardry.proxy.setToEntityNameEntry(property); // Wizardry.proxy.setToEntityNameEntry(property);
// Converts all strings in the list to lower case, to ignore case sensitivity, and trims them. // Converts all strings in the list to lower case, to ignore case sensitivity, and trims them.
for(int i=0; i<property.getStringList().length; i++){ for(int i = 0; i < property.getStringList().length; i++){
property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim(); property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim();
MagicDamage.addEntityImmunity(EntityList.NAME_TO_CLASS.get(property.getStringList()[i]), DamageType.FIRE); MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
DamageType.FIRE);
} }
propOrder1.add(property.getName()); propOrder.add(property.getName());
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToIce", new String[]{}, "List of names of entities that are immune to ice, in addition to the defaults. Add mod creatures to this list if you want them to be immune to ice magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard)."); property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToIce", new String[]{},
property.setLanguageKey("config.wizardry.mobs_immune_to_ice"); "List of names of entities that are immune to ice, in addition to the defaults. Add mod creatures to this list if you want them to be immune to ice magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_ice");
property.setRequiresMcRestart(true); property.setRequiresMcRestart(true);
//Wizardry.proxy.setToEntityNameEntry(property); // Wizardry.proxy.setToEntityNameEntry(property);
// Converts all strings in the list to lower case, to ignore case sensitivity, and trims them. // Converts all strings in the list to lower case, to ignore case sensitivity, and trims them.
for(int i=0; i<property.getStringList().length; i++){ for(int i = 0; i < property.getStringList().length; i++){
property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim(); property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim();
MagicDamage.addEntityImmunity(EntityList.NAME_TO_CLASS.get(property.getStringList()[i]), DamageType.FROST); MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
DamageType.FROST);
} }
propOrder1.add(property.getName()); propOrder.add(property.getName());
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToLightning", new String[]{}, "List of names of entities that are immune to lightning, in addition to the defaults. Add mod creatures to this list if you want them to be immune to lightning magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard)."); property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToLightning", new String[]{},
property.setLanguageKey("config.wizardry.mobs_immune_to_lightning"); "List of names of entities that are immune to lightning, in addition to the defaults. Add mod creatures to this list if you want them to be immune to lightning magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_lightning");
property.setRequiresMcRestart(true); property.setRequiresMcRestart(true);
//Wizardry.proxy.setToEntityNameEntry(property); // Wizardry.proxy.setToEntityNameEntry(property);
// Converts all strings in the list to lower case, to ignore case sensitivity, and trims them. // Converts all strings in the list to lower case, to ignore case sensitivity, and trims them.
for(int i=0; i<property.getStringList().length; i++){ for(int i = 0; i < property.getStringList().length; i++){
property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim(); property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim();
MagicDamage.addEntityImmunity(EntityList.NAME_TO_CLASS.get(property.getStringList()[i]), DamageType.SHOCK); MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
DamageType.SHOCK);
} }
propOrder1.add(property.getName()); propOrder.add(property.getName());
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToWither", new String[]{}, "List of names of entities that are immune to wither effects, in addition to the defaults. Add mod creatures to this list if you want them to be immune to withering magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard)."); property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToWither", new String[]{},
property.setLanguageKey("config.wizardry.mobs_immune_to_wither"); "List of names of entities that are immune to wither effects, in addition to the defaults. Add mod creatures to this list if you want them to be immune to withering magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_wither");
property.setRequiresMcRestart(true); property.setRequiresMcRestart(true);
//Wizardry.proxy.setToEntityNameEntry(property); // Wizardry.proxy.setToEntityNameEntry(property);
// Converts all strings in the list to lower case, to ignore case sensitivity, and trims them. // Converts all strings in the list to lower case, to ignore case sensitivity, and trims them.
for(int i=0; i<property.getStringList().length; i++){ for(int i = 0; i < property.getStringList().length; i++){
property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim(); property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim();
MagicDamage.addEntityImmunity(EntityList.NAME_TO_CLASS.get(property.getStringList()[i]), DamageType.WITHER); MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
DamageType.WITHER);
} }
propOrder1.add(property.getName()); propOrder.add(property.getName());
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToPoison", new String[]{}, "List of names of entities that are immune to poison, in addition to the defaults. Add mod creatures to this list if you want them to be immune to poison magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. wizardry:Wizard)."); property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToPoison", new String[]{},
property.setLanguageKey("config.wizardry.mobs_immune_to_poison"); "List of names of entities that are immune to poison, in addition to the defaults. Add mod creatures to this list if you want them to be immune to poison magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_poison");
property.setRequiresMcRestart(true); property.setRequiresMcRestart(true);
//Wizardry.proxy.setToEntityNameEntry(property); // Wizardry.proxy.setToEntityNameEntry(property);
// Converts all strings in the list to lower case, to ignore case sensitivity, and trims them. // Converts all strings in the list to lower case, to ignore case sensitivity, and trims them.
for(int i=0; i<property.getStringList().length; i++){ for(int i = 0; i < property.getStringList().length; i++){
property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim(); property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim();
MagicDamage.addEntityImmunity(EntityList.NAME_TO_CLASS.get(property.getStringList()[i]), DamageType.POISON); MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
DamageType.POISON);
} }
propOrder1.add(property.getName()); propOrder.add(property.getName());
config.setCategoryPropertyOrder(RESISTANCES_CATEGORY, propOrder1);
// config.addCustomCategoryComment(CLIENT_CATEGORY, "Client-side settings that only affect the local minecraft game. They have no effect on a server; each player obeys their own settings.");
// config.addCustomCategoryComment(COMMANDS_CATEGORY, "Settings for the commands added by Wizardry. In multiplayer, the server/LAN host settings will apply.");
// config.addCustomCategoryComment(WORLDGEN_CATEGORY, "Settings that affect world generation. In multiplayer, the server/LAN host settings will apply.");
// config.addCustomCategoryComment(GLOBAL_CATEGORY, "Global settings that affect game mechanics. In multiplayer, the server/LAN host settings will apply.");
config.setCategoryPropertyOrder(RESISTANCES_CATEGORY, propOrder);
} }
} }
@@ -15,116 +15,127 @@ import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldSavedData; import net.minecraft.world.storage.WorldSavedData;
import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
/** Class responsible for generating and storing the randomised spell names and descriptions for each world, which are /**
* Class responsible for generating and storing the randomised spell names and descriptions for each world, which are
* displayed as glyphs using the SGA font renderer. * displayed as glyphs using the SGA font renderer.
* @since Wizardry 1.1 */ *
* @since Wizardry 1.1
*/
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
public class SpellGlyphData extends WorldSavedData { public class SpellGlyphData extends WorldSavedData {
public static final String NAME = Wizardry.MODID + "_glyphData"; public static final String NAME = Wizardry.MODID + "_glyphData";
public Map<Spell, String> randomNames = new HashMap<Spell, String>(Spell.getTotalSpellCount()); public Map<Spell, String> randomNames = new HashMap<Spell, String>(Spell.getTotalSpellCount());
public Map<Spell, String> randomDescriptions = new HashMap<Spell, String>(Spell.getTotalSpellCount()); public Map<Spell, String> randomDescriptions = new HashMap<Spell, String>(Spell.getTotalSpellCount());
// Required constructors // Required constructors
public SpellGlyphData() { public SpellGlyphData(){
this(NAME); this(NAME);
} }
public SpellGlyphData(String name){ public SpellGlyphData(String name){
super(name); super(name);
} }
/** Generates random names and descriptions for any spells which don't already have them. */ /** Generates random names and descriptions for any spells which don't already have them. */
public void generateGlyphNames(World world){ public void generateGlyphNames(World world){
for(Spell spell : Spell.getSpells(Spell.allSpells)){ for(Spell spell : Spell.getSpells(Spell.allSpells)){
if(!randomNames.containsKey(spell)) randomNames.put(spell, generateRandomName(world.rand)); if(!randomNames.containsKey(spell)) randomNames.put(spell, generateRandomName(world.rand));
} }
for(Spell spell : Spell.getSpells(Spell.allSpells)){ for(Spell spell : Spell.getSpells(Spell.allSpells)){
if(!randomDescriptions.containsKey(spell)) randomDescriptions.put(spell, generateRandomDescription(world.rand)); if(!randomDescriptions.containsKey(spell))
randomDescriptions.put(spell, generateRandomDescription(world.rand));
} }
this.markDirty(); this.markDirty();
} }
private String generateRandomName(Random random){ private String generateRandomName(Random random){
String name = ""; String name = "";
for(int i=0; i<random.nextInt(2)+2; i++){ for(int i = 0; i < random.nextInt(2) + 2; i++){
name = name + RandomStringUtils.random(3 + random.nextInt(5), "abcdefghijklmnopqrstuvwxyz") + " "; name = name + RandomStringUtils.random(3 + random.nextInt(5), "abcdefghijklmnopqrstuvwxyz") + " ";
} }
return name.trim(); return name.trim();
} }
private String generateRandomDescription(Random random){ private String generateRandomDescription(Random random){
String name = ""; String name = "";
for(int i=0; i<random.nextInt(16)+8; i++){ for(int i = 0; i < random.nextInt(16) + 8; i++){
name = name + RandomStringUtils.random(2 + random.nextInt(7), "abcdefghijklmnopqrstuvwxyz") + " "; name = name + RandomStringUtils.random(2 + random.nextInt(7), "abcdefghijklmnopqrstuvwxyz") + " ";
} }
return name.trim(); return name.trim();
} }
/** Returns the spell glyph data for this world, or creates a new instance if it doesn't exist yet. Also checks /**
* for any spells that are missing glyph data and adds it accordingly. */ * Returns the spell glyph data for this world, or creates a new instance if it doesn't exist yet. Also checks for
public static SpellGlyphData get(World world) { * any spells that are missing glyph data and adds it accordingly.
*/
public static SpellGlyphData get(World world){
SpellGlyphData instance = (SpellGlyphData) world.loadItemData(SpellGlyphData.class, NAME); SpellGlyphData instance = (SpellGlyphData)world.loadData(SpellGlyphData.class, NAME);
if(instance == null){ if(instance == null){
instance = new SpellGlyphData(); instance = new SpellGlyphData();
} }
// These two conditions are a bit of backwards compatibility from when I added the descriptions to the // These two conditions are a bit of backwards compatibility from when I added the descriptions to the
// glyph data. Shouldn't be needed in normal operation, but I might as well leave it here. // glyph data. Shouldn't be needed in normal operation, but I might as well leave it here.
// Edit: More backwards compatibility, this time for the future - should any new spells be added, this now ensures // Edit: More backwards compatibility, this time for the future - should any new spells be added, this now
// ensures
// existing worlds will generate random names and descriptions for any new spells whilst keeping the old ones. // existing worlds will generate random names and descriptions for any new spells whilst keeping the old ones.
if(instance.randomNames.size() < Spell.getTotalSpellCount() || instance.randomDescriptions.size() < Spell.getTotalSpellCount()){ if(instance.randomNames.size() < Spell.getTotalSpellCount()
|| instance.randomDescriptions.size() < Spell.getTotalSpellCount()){
instance.generateGlyphNames(world); instance.generateGlyphNames(world);
world.setItemData(NAME, instance); world.setData(NAME, instance);
} }
return instance; return instance;
} }
/** Sends the random spell names for this world to the specified player's client. */ /** Sends the random spell names for this world to the specified player's client. */
public void sync(EntityPlayerMP player){ public void sync(EntityPlayerMP player){
List<String> names = new ArrayList<String>(); List<String> names = new ArrayList<String>();
List<String> descriptions = new ArrayList<String>(); List<String> descriptions = new ArrayList<String>();
for(Spell spell : Spell.getSpells(Spell.allSpells)){ for(Spell spell : Spell.getSpells(Spell.allSpells)){
names.add(this.randomNames.get(spell)); names.add(this.randomNames.get(spell));
descriptions.add(this.randomDescriptions.get(spell)); descriptions.add(this.randomDescriptions.get(spell));
} }
PacketGlyphData.Message msg = new PacketGlyphData.Message(names, descriptions); PacketGlyphData.Message msg = new PacketGlyphData.Message(names, descriptions);
WizardryPacketHandler.net.sendTo(msg, player); WizardryPacketHandler.net.sendTo(msg, player);
Wizardry.logger.info("Synchronising spell glyph data for " + player.getName()); Wizardry.logger.info("Synchronising spell glyph data for " + player.getName());
} }
/** Helper method to retrieve the random glyph name for the given spell from the map stored in the given world. */ /** Helper method to retrieve the random glyph name for the given spell from the map stored in the given world. */
public static String getGlyphName(Spell spell, World world){ public static String getGlyphName(Spell spell, World world){
Map<Spell, String> names = SpellGlyphData.get(world).randomNames; Map<Spell, String> names = SpellGlyphData.get(world).randomNames;
return names == null ? "" : names.get(spell); return names == null ? "" : names.get(spell);
} }
/** Helper method to retrieve the random glyph description for the given spell from the map stored in the given world. */ /**
* Helper method to retrieve the random glyph description for the given spell from the map stored in the given
* world.
*/
public static String getGlyphDescription(Spell spell, World world){ public static String getGlyphDescription(Spell spell, World world){
Map<Spell, String> descriptions = SpellGlyphData.get(world).randomDescriptions; Map<Spell, String> descriptions = SpellGlyphData.get(world).randomDescriptions;
return descriptions == null ? "" : descriptions.get(spell); return descriptions == null ? "" : descriptions.get(spell);
@@ -132,13 +143,13 @@ public class SpellGlyphData extends WorldSavedData {
@Override @Override
public void readFromNBT(NBTTagCompound nbt){ public void readFromNBT(NBTTagCompound nbt){
this.randomNames = new HashMap<Spell, String>(); this.randomNames = new HashMap<Spell, String>();
this.randomDescriptions = new HashMap<Spell, String>(); this.randomDescriptions = new HashMap<Spell, String>();
NBTTagList tagList = nbt.getTagList("spellGlyphData", NBT.TAG_COMPOUND); NBTTagList tagList = nbt.getTagList("spellGlyphData", NBT.TAG_COMPOUND);
for(int i=0; i<tagList.tagCount(); i++){ for(int i = 0; i < tagList.tagCount(); i++){
NBTTagCompound tag = tagList.getCompoundTagAt(i); NBTTagCompound tag = tagList.getCompoundTagAt(i);
randomNames.put(Spell.get(tag.getInteger("spell")), tag.getString("name")); randomNames.put(Spell.get(tag.getInteger("spell")), tag.getString("name"));
randomDescriptions.put(Spell.get(tag.getInteger("spell")), tag.getString("description")); randomDescriptions.put(Spell.get(tag.getInteger("spell")), tag.getString("description"));
@@ -149,7 +160,7 @@ public class SpellGlyphData extends WorldSavedData {
public NBTTagCompound writeToNBT(NBTTagCompound nbt){ public NBTTagCompound writeToNBT(NBTTagCompound nbt){
NBTTagList tagList = new NBTTagList(); NBTTagList tagList = new NBTTagList();
for(Spell spell : Spell.getSpells(Spell.allSpells)){ for(Spell spell : Spell.getSpells(Spell.allSpells)){
// Much like the enchantments tag for items, this stores a list of spell-id-to-name tag pairs // Much like the enchantments tag for items, this stores a list of spell-id-to-name tag pairs
// The description is now also included; there's no point in making a second compound tag! // The description is now also included; there's no point in making a second compound tag!
@@ -159,9 +170,9 @@ public class SpellGlyphData extends WorldSavedData {
tag.setString("description", this.randomDescriptions.get(spell)); tag.setString("description", this.randomDescriptions.get(spell));
tagList.appendTag(tag); tagList.appendTag(tag);
} }
nbt.setTag("spellGlyphData", tagList); nbt.setTag("spellGlyphData", tagList);
return nbt; return nbt;
} }
+197 -142
View File
@@ -20,7 +20,7 @@ import electroblob.wizardry.packet.PacketPlayerSync;
import electroblob.wizardry.packet.PacketTransportation; import electroblob.wizardry.packet.PacketTransportation;
import electroblob.wizardry.packet.WizardryPacketHandler; import electroblob.wizardry.packet.WizardryPacketHandler;
import electroblob.wizardry.registry.Spells; import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardryAchievements; import electroblob.wizardry.registry.WizardryAdvancementTriggers;
import electroblob.wizardry.spell.None; import electroblob.wizardry.spell.None;
import electroblob.wizardry.spell.Spell; import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.MagicDamage; import electroblob.wizardry.util.MagicDamage;
@@ -49,24 +49,27 @@ import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.ICapabilitySerializable; import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.entity.EntityJoinWorldEvent; import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
/** Capability-based replacement for the old ExtendedPlayer class from 1.7.10. This has been reworked to leave /**
* minimum external changes (for my own sanity, mainly!). Turns out the only major difference between an internal * Capability-based replacement for the old ExtendedPlayer class from 1.7.10. This has been reworked to leave minimum
* capability and an IEEP is a couple of redundant classes and a different way of registering it. * external changes (for my own sanity, mainly!). Turns out the only major difference between an internal capability and
* an IEEP is a couple of redundant classes and a different way of registering it.
* <p> * <p>
* Forge seems to have separate classes to hold the Capability<...> instance ('key') and * Forge seems to have separate classes to hold the Capability<...> instance ('key') and methods for getting the
* methods for getting the capability, but in my opinion there are already too many classes to deal with, so I'm not * capability, but in my opinion there are already too many classes to deal with, so I'm not adding any more than are
* adding any more than are necessary, meaning those constants and values are kept here instead. * necessary, meaning those constants and values are kept here instead.
* @since Wizardry 1.2 *
* @author Electroblob */ * @since Wizardry 2.1
* @author Electroblob
*/
// On the plus side, having to rethink this class allowed me to clean it up a lot. // On the plus side, having to rethink this class allowed me to clean it up a lot.
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
public class WizardData implements INBTSerializable<NBTTagCompound> { public class WizardData implements INBTSerializable<NBTTagCompound> {
@@ -85,14 +88,20 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
public boolean hasSpiritWolf; public boolean hasSpiritWolf;
public boolean hasSpiritHorse; public boolean hasSpiritHorse;
/** Whether this player is currently casting a continuous spell via commands. Not saved over world reload /**
* and reset on player death. */ * Whether this player is currently casting a continuous spell via commands. Not saved over world reload and reset
* on player death.
*/
private Spell currentlyCasting; private Spell currentlyCasting;
/** The time for which this player has been casting a continuous spell via commands. Increments by 1 each tick. /**
* Not saved over world reload and reset on player death. */ * The time for which this player has been casting a continuous spell via commands. Increments by 1 each tick. Not
* saved over world reload and reset on player death.
*/
private int castingTick; private int castingTick;
/** SpellModifiers object for the current continuous spell cast via commands. Not saved over world reload and /**
* reset on player death. */ * SpellModifiers object for the current continuous spell cast via commands. Not saved over world reload and reset
* on player death.
*/
private SpellModifiers spellModifiers; private SpellModifiers spellModifiers;
/** Coordinates for the saved transportation stone circle location. Will be null if no location is saved. */ /** Coordinates for the saved transportation stone circle location. Will be null if no location is saved. */
private BlockPos stoneCircleLocation; private BlockPos stoneCircleLocation;
@@ -110,17 +119,25 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
public WeakReference<ISummonedCreature> selectedMinion; public WeakReference<ISummonedCreature> selectedMinion;
/** Set of this player's discovered spells. <b>Do not write to this list directly</b>, use /**
* {@link WizardData#discoverSpell(Spell)} instead. */ * Set of this player's discovered spells. <b>Do not write to this list directly</b>, use
* {@link WizardData#discoverSpell(Spell)} instead.
*/
public Set<Spell> spellsDiscovered; public Set<Spell> spellsDiscovered;
private Set<UUID> allies; private Set<UUID> allies;
/** List of usernames of this player's allies. May not be accurate 100% of the time. This is here so that a player /**
* can view the usernames of their allies even when those allies are not online. * List of usernames of this player's allies. May not be accurate 100% of the time. This is here so that a player
* <b> Do not use this for any other purpose than displaying the names! */ * can view the usernames of their allies even when those allies are not online. <b> Do not use this for any other
* purpose than displaying the names!
*/
public Set<String> allyNames; public Set<String> allyNames;
private Set<UUID> soulboundCreatures; private Set<UUID> soulboundCreatures;
public WizardData(){
this(null); // Nullary constructor for the registration method factory parameter
}
public WizardData(EntityPlayer player){ public WizardData(EntityPlayer player){
this.player = player; this.player = player;
@@ -147,9 +164,10 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
} }
/** /**
* Adds the given spell to the list of discovered spells for this player. Automatically takes into account * Adds the given spell to the list of discovered spells for this player. Automatically takes into account whether
* whether the spell has been discovered. Use this method rather than adding directly to the list because it * the spell has been discovered. Use this method rather than adding directly to the list because it handles
* handles achievements. * achievements.
*
* @param spell The spell to be discovered * @param spell The spell to be discovered
* @return True if the spell had not already been discovered; false otherwise. * @return True if the spell had not already been discovered; false otherwise.
*/ */
@@ -164,12 +182,13 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
if(!spellsDiscovered.add(spell)) return false; if(!spellsDiscovered.add(spell)) return false;
// If the spell had not already been discovered, achievements can be triggered and the method returns true // If the spell had not already been discovered, achievements can be triggered and the method returns true
if(spellsDiscovered.containsAll(Spell.getSpells(Spell::isEnabled))){ if(spellsDiscovered.containsAll(Spell.getSpells(Spell::isEnabled))){
this.player.addStat(WizardryAchievements.all_spells); WizardryAdvancementTriggers.all_spells.triggerFor(this.player);
} }
for(Element element : Element.values()){ for(Element element : Element.values()){
if(element != Element.MAGIC && spellsDiscovered.containsAll(Spell.getSpells(new Spell.TierElementFilter(null, element)))){ if(element != Element.MAGIC
this.player.addStat(WizardryAchievements.element_master); && spellsDiscovered.containsAll(Spell.getSpells(new Spell.TierElementFilter(null, element)))){
WizardryAdvancementTriggers.element_master.triggerFor(this.player);
} }
} }
@@ -183,13 +202,22 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
} }
/** Returns the coordinates of the associated player's saved transportation stone circle. */ /** Returns the coordinates of the associated player's saved transportation stone circle. */
public BlockPos getStoneCircleLocation(){ return stoneCircleLocation; } public BlockPos getStoneCircleLocation(){
return stoneCircleLocation;
}
/** Returns the dimension ID of the associated player's saved transportation stone circle. */ /** Returns the dimension ID of the associated player's saved transportation stone circle. */
public int getStoneCircleDimension(){ return stoneCircleDimension; } public int getStoneCircleDimension(){
return stoneCircleDimension;
}
public int getTpCountdown() { return tpCountdown; } public int getTpCountdown(){
return tpCountdown;
}
public void setTpCountdown(int tpCountdown) { this.tpCountdown = tpCountdown; } public void setTpCountdown(int tpCountdown){
this.tpCountdown = tpCountdown;
}
/** Sets the player's saved clairvoyance location. */ /** Sets the player's saved clairvoyance location. */
public void setClairvoyancePoint(BlockPos pos, int dimensionID){ public void setClairvoyancePoint(BlockPos pos, int dimensionID){
@@ -198,46 +226,60 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
} }
/** Returns the coordinates for the saved clairvoyance location. Will be null if no location is saved. */ /** Returns the coordinates for the saved clairvoyance location. Will be null if no location is saved. */
public BlockPos getClairvoyanceLocation(){ return clairvoyanceLocation; } public BlockPos getClairvoyanceLocation(){
return clairvoyanceLocation;
}
/** Returns the dimension ID for the saved clairvoyance location. Will be null if no location is saved. */ /** Returns the dimension ID for the saved clairvoyance location. Will be null if no location is saved. */
public int getClairvoyanceDimension(){ return clairvoyanceDimension; } public int getClairvoyanceDimension(){
return clairvoyanceDimension;
}
/** Overwrites the imbuement duration associated with the given imubement for this player, or creates it if there /**
* was none previously. * Overwrites the imbuement duration associated with the given imubement for this player, or creates it if there was
* @throws IllegalArgumentException if the given {@link Enchantment} is not an {@link Imbuement}. */ * none previously.
*
* @throws IllegalArgumentException if the given {@link Enchantment} is not an {@link Imbuement}.
*/
public void setImbuementDuration(Enchantment enchantment, int duration){ public void setImbuementDuration(Enchantment enchantment, int duration){
// It is best to throw an exception here, because otherwise the error would either go unnoticed (if non-imbuements // It is best to throw an exception here, because otherwise the error would either go unnoticed (if
// non-imbuements
// were ignored) or cause a ClassCastException later (if non-imbuements were allowed to be added). // were ignored) or cause a ClassCastException later (if non-imbuements were allowed to be added).
if(enchantment instanceof Imbuement){ if(enchantment instanceof Imbuement){
this.imbuementDurations.put((Imbuement) enchantment, duration); this.imbuementDurations.put((Imbuement)enchantment, duration);
}else{ }else{
throw new IllegalArgumentException("Attempted to set an imbuement duration for something that isn't an Imbuement! (This exception has been thrown now to prevent a ClassCastException from occurring later.)"); throw new IllegalArgumentException(
"Attempted to set an imbuement duration for something that isn't an Imbuement! (This exception has been thrown now to prevent a ClassCastException from occurring later.)");
} }
} }
/** Returns the imbuement duration associated with the given imbuement for this player, or 0 if it does not exist. */ /**
* Returns the imbuement duration associated with the given imbuement for this player, or 0 if it does not exist.
*/
@SuppressWarnings("unlikely-arg-type") @SuppressWarnings("unlikely-arg-type")
public int getImbuementDuration(Enchantment enchantment){ public int getImbuementDuration(Enchantment enchantment){
// Need to check that i is not null, otherwise it throws an NPE when Java auto-unboxes it. // Need to check that i is not null, otherwise it throws an NPE when Java auto-unboxes it.
// What's nice here is that the map simply accepts objects as keys, so there's no need to cast or throw exceptions. // What's nice here is that the map simply accepts objects as keys, so there's no need to cast or throw
// exceptions.
Integer i = this.imbuementDurations.get(enchantment); Integer i = this.imbuementDurations.get(enchantment);
// If i is null, returns 0; otherwise returns i, auto-unboxed to an int. // If i is null, returns 0; otherwise returns i, auto-unboxed to an int.
return i == null ? 0 : i; return i == null ? 0 : i;
} }
/** Decrements the duration for each conjured item by 1, and removes from the map any that are 0 or less or that /**
* the player no longer has. Also deletes the item from the player's inventory if it runs out of time. */ * Decrements the duration for each conjured item by 1, and removes from the map any that are 0 or less or that the
* player no longer has. Also deletes the item from the player's inventory if it runs out of time.
*/
private void updateImbuedItems(){ private void updateImbuedItems(){
Set<Imbuement> activeImbuements = new HashSet<Imbuement>(); Set<Imbuement> activeImbuements = new HashSet<Imbuement>();
// For each item in the player's inventory // For each item in the player's inventory
for(ItemStack stack : player.inventory.mainInventory){ for(ItemStack stack : player.inventory.mainInventory){
if(stack != null && stack.isItemEnchanted()){ if(stack.isItemEnchanted()){
Map<Enchantment, Integer> enchantments = EnchantmentHelper.getEnchantments(stack); Map<Enchantment, Integer> enchantments = EnchantmentHelper.getEnchantments(stack);
Iterator<Entry<Enchantment, Integer>> iterator = enchantments.entrySet().iterator(); Iterator<Entry<Enchantment, Integer>> iterator = enchantments.entrySet().iterator();
// For each of the item's enchantments // For each of the item's enchantments
while(iterator.hasNext()){ while(iterator.hasNext()){
@@ -248,10 +290,10 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
// If the imbuement is still active: // If the imbuement is still active:
if(duration > 0){ if(duration > 0){
// Decrements the timer // Decrements the timer
this.imbuementDurations.put((Imbuement)enchantment, duration-1); this.imbuementDurations.put((Imbuement)enchantment, duration - 1);
// Adds this imbuement to the set of imbuements that need to be kept // Adds this imbuement to the set of imbuements that need to be kept
activeImbuements.add((Imbuement)enchantment); activeImbuements.add((Imbuement)enchantment);
// Otherwise: // Otherwise:
}else{ }else{
// Removes the enchantment from the enchantment map // Removes the enchantment from the enchantment map
iterator.remove(); iterator.remove();
@@ -266,8 +308,10 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
this.imbuementDurations.keySet().retainAll(activeImbuements); this.imbuementDurations.keySet().retainAll(activeImbuements);
} }
/** Adds the given player to the list of allies belonging to the associated player, or removes the player if /**
* they are already in the list of allies. Returns true if the player was added, false if they were removed. */ * Adds the given player to the list of allies belonging to the associated player, or removes the player if they are
* already in the list of allies. Returns true if the player was added, false if they were removed.
*/
public boolean toggleAlly(EntityPlayer player){ public boolean toggleAlly(EntityPlayer player){
if(this.isPlayerAlly(player)){ if(this.isPlayerAlly(player)){
this.allies.remove(player.getUniqueID()); this.allies.remove(player.getUniqueID());
@@ -296,21 +340,24 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
return this.soulboundCreatures.contains(target.getUniqueID()); return this.soulboundCreatures.contains(target.getUniqueID());
} }
/** Damages all creatures soulbound to this player by the given amount, and removes from the list any that no /**
* longer exist. */ * Damages all creatures soulbound to this player by the given amount, and removes from the list any that no longer
* exist.
*/
public void damageAllSoulboundCreatures(float damage){ public void damageAllSoulboundCreatures(float damage){
for(Iterator<UUID> iterator = this.soulboundCreatures.iterator(); iterator.hasNext();){ for(Iterator<UUID> iterator = this.soulboundCreatures.iterator(); iterator.hasNext();){
Entity entity = WizardryUtilities.getEntityByUUID(this.player.worldObj, iterator.next()); Entity entity = WizardryUtilities.getEntityByUUID(this.player.world, iterator.next());
if(entity == null) iterator.remove(); if(entity == null) iterator.remove();
if(entity instanceof EntityLivingBase){ if(entity instanceof EntityLivingBase){
// Retaliatory effect // Retaliatory effect
if(entity.attackEntityFrom(MagicDamage.causeDirectMagicDamage(this.player, DamageType.MAGIC, true), damage)){ if(entity.attackEntityFrom(MagicDamage.causeDirectMagicDamage(this.player, DamageType.MAGIC, true),
damage)){
// Sound only plays if the damage succeeds // Sound only plays if the damage succeeds
player.playSound(SoundEvents.ENTITY_WITHER_HURT, 1.0F, player.worldObj.rand.nextFloat() * 0.2F + 1.0F); player.playSound(SoundEvents.ENTITY_WITHER_HURT, 1.0F, player.world.rand.nextFloat() * 0.2F + 1.0F);
} }
} }
} }
@@ -322,10 +369,10 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
this.currentlyCasting = spell; this.currentlyCasting = spell;
this.spellModifiers = modifiers; this.spellModifiers = modifiers;
if(!this.player.worldObj.isRemote){ if(!this.player.world.isRemote){
PacketCastContinuousSpell.Message message = new PacketCastContinuousSpell.Message(this.player.getEntityId(), PacketCastContinuousSpell.Message message = new PacketCastContinuousSpell.Message(this.player.getEntityId(),
spell.id(), this.spellModifiers); spell.id(), this.spellModifiers);
WizardryPacketHandler.net.sendToDimension(message, this.player.worldObj.provider.getDimension()); WizardryPacketHandler.net.sendToDimension(message, this.player.world.provider.getDimension());
} }
} }
@@ -336,31 +383,33 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
this.castingTick = 0; this.castingTick = 0;
this.spellModifiers.reset(); this.spellModifiers.reset();
if(!this.player.worldObj.isRemote){ if(!this.player.world.isRemote){
PacketCastContinuousSpell.Message message = new PacketCastContinuousSpell.Message(this.player.getEntityId(), PacketCastContinuousSpell.Message message = new PacketCastContinuousSpell.Message(this.player.getEntityId(),
Spells.none.id(), this.spellModifiers); Spells.none.id(), this.spellModifiers);
WizardryPacketHandler.net.sendToDimension(message, this.player.worldObj.provider.getDimension()); WizardryPacketHandler.net.sendToDimension(message, this.player.world.provider.getDimension());
} }
} }
/** Casts the current continuous spell, fires relevant events and updates the castingTick field. */ /** Casts the current continuous spell, fires relevant events and updates the castingTick field. */
public void updateContinuousSpellCasting(){ public void updateContinuousSpellCasting(){
if(this.currentlyCasting != null && this.currentlyCasting.isContinuous){ if(this.currentlyCasting != null && this.currentlyCasting.isContinuous){
if(MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Tick(player, currentlyCasting, spellModifiers, Source.COMMAND, castingTick))){ if(MinecraftForge.EVENT_BUS.post(
new SpellCastEvent.Tick(player, currentlyCasting, spellModifiers, Source.COMMAND, castingTick))){
this.stopCastingContinuousSpell(); this.stopCastingContinuousSpell();
return; return;
} }
if(this.currentlyCasting.cast(player.worldObj, player, EnumHand.MAIN_HAND, castingTick, this.spellModifiers) if(this.currentlyCasting.cast(player.world, player, EnumHand.MAIN_HAND, castingTick, this.spellModifiers)
&& this.castingTick == 0){ && this.castingTick == 0){
// On the first tick casting a continuous spell via commands, SpellCastEvent.Post is fired. // On the first tick casting a continuous spell via commands, SpellCastEvent.Post is fired.
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(player, currentlyCasting, spellModifiers, Source.COMMAND)); MinecraftForge.EVENT_BUS
.post(new SpellCastEvent.Post(player, currentlyCasting, spellModifiers, Source.COMMAND));
} }
castingTick++; castingTick++;
}else{ }else{
// Why is this here? Surely castingTick will always be 0 if currentlyCasting is null? // Why is this here? Surely castingTick will always be 0 if currentlyCasting is null?
this.castingTick = 0; this.castingTick = 0;
@@ -372,8 +421,10 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
return this.currentlyCasting != null && this.currentlyCasting != Spells.none; return this.currentlyCasting != null && this.currentlyCasting != Spells.none;
} }
/** Returns the continuous spell this player is currently casting via commands, or the 'none' spell if they aren't /**
* casting anything. */ * Returns the continuous spell this player is currently casting via commands, or the 'none' spell if they aren't
* casting anything.
*/
public Spell currentlyCasting(){ public Spell currentlyCasting(){
return currentlyCasting; return currentlyCasting;
} }
@@ -387,20 +438,20 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
// functions, just for different enchantments. // functions, just for different enchantments.
updateImbuedItems(); updateImbuedItems();
if(!player.worldObj.isRemote){ if(!player.world.isRemote){
if(getTpCountdown() == 1){ if(getTpCountdown() == 1){
player.setPositionAndUpdate(this.stoneCircleLocation.getX() + 0.5, this.stoneCircleLocation.getY(), player.setPositionAndUpdate(this.stoneCircleLocation.getX() + 0.5, this.stoneCircleLocation.getY(),
this.stoneCircleLocation.getZ() + 0.5); this.stoneCircleLocation.getZ() + 0.5);
player.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, 50, 0)); player.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, 50, 0));
IMessage msg = new PacketTransportation.Message(player.getEntityId()); IMessage msg = new PacketTransportation.Message(player.getEntityId());
WizardryPacketHandler.net.sendToDimension(msg, player.worldObj.provider.getDimension()); WizardryPacketHandler.net.sendToDimension(msg, player.world.provider.getDimension());
} }
if(getTpCountdown() > 0){ if(getTpCountdown() > 0){
setTpCountdown(getTpCountdown() - 1); setTpCountdown(getTpCountdown() - 1);
} }
} }
updateContinuousSpellCasting(); updateContinuousSpellCasting();
} }
@@ -411,11 +462,14 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
return player.getCapability(WIZARD_DATA_CAPABILITY, null); return player.getCapability(WIZARD_DATA_CAPABILITY, null);
} }
/** Called from the event handler each time the associated player entity is cloned, i.e. on respawn or when /**
* travelling to a different dimension. Used to copy over any variables that should persist over player death. * Called from the event handler each time the associated player entity is cloned, i.e. on respawn or when
* This is the inverse of the old onPlayerDeath method, which reset the variables that shouldn't persist. * travelling to a different dimension. Used to copy over any variables that should persist over player death. This
* is the inverse of the old onPlayerDeath method, which reset the variables that shouldn't persist.
*
* @param data The old WizardData whose variables are to be copied over. * @param data The old WizardData whose variables are to be copied over.
* @param respawn True if the player died and is respawning, false if they are just travelling between dimensions. */ * @param respawn True if the player died and is respawning, false if they are just travelling between dimensions.
*/
public void copyFrom(WizardData data, boolean respawn){ public void copyFrom(WizardData data, boolean respawn){
// TODO: What happens with spirit wolf and spirit horse? // TODO: What happens with spirit wolf and spirit horse?
this.hasSpiritHorse = data.hasSpiritHorse; this.hasSpiritHorse = data.hasSpiritHorse;
@@ -441,14 +495,15 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
public void sync(){ public void sync(){
if(this.player instanceof EntityPlayerMP){ if(this.player instanceof EntityPlayerMP){
int id = -1; int id = -1;
if(this.selectedMinion != null && this.selectedMinion.get() instanceof Entity) id = ((Entity)this.selectedMinion.get()).getEntityId(); if(this.selectedMinion != null && this.selectedMinion.get() instanceof Entity)
id = ((Entity)this.selectedMinion.get()).getEntityId();
IMessage msg = new PacketPlayerSync.Message(this.spellsDiscovered, id); IMessage msg = new PacketPlayerSync.Message(this.spellsDiscovered, id);
WizardryPacketHandler.net.sendTo(msg, (EntityPlayerMP)this.player); WizardryPacketHandler.net.sendTo(msg, (EntityPlayerMP)this.player);
} }
} }
@Override @Override
public NBTTagCompound serializeNBT() { public NBTTagCompound serializeNBT(){
NBTTagCompound properties = new NBTTagCompound(); NBTTagCompound properties = new NBTTagCompound();
@@ -459,21 +514,24 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
properties.setBoolean("hasSpiritWolf", this.hasSpiritWolf); properties.setBoolean("hasSpiritWolf", this.hasSpiritWolf);
properties.setBoolean("hasSpiritHorse", this.hasSpiritHorse); properties.setBoolean("hasSpiritHorse", this.hasSpiritHorse);
if(this.stoneCircleLocation != null) properties.setLong("stoneCircleLocation", this.stoneCircleLocation.toLong()); if(this.stoneCircleLocation != null)
properties.setLong("stoneCircleLocation", this.stoneCircleLocation.toLong());
properties.setInteger("stoneCircleDimension", this.stoneCircleDimension); properties.setInteger("stoneCircleDimension", this.stoneCircleDimension);
properties.setInteger("tpCountdown", this.tpCountdown); properties.setInteger("tpCountdown", this.tpCountdown);
if(this.clairvoyanceLocation != null) properties.setLong("clairvoyanceLocation", this.clairvoyanceLocation.toLong()); if(this.clairvoyanceLocation != null)
properties.setLong("clairvoyanceLocation", this.clairvoyanceLocation.toLong());
properties.setInteger("clairvoyanceDimension", this.getClairvoyanceDimension()); properties.setInteger("clairvoyanceDimension", this.getClairvoyanceDimension());
// THIS is why I wrote the list/map <-> NBT methods. Look how neat this is! // THIS is why I wrote the list/map <-> NBT methods. Look how neat this is!
properties.setTag("allies", WizardryUtilities.listToNBT(this.allies, WizardryUtilities::UUIDtoTagCompound)); properties.setTag("allies", WizardryUtilities.listToNBT(this.allies, WizardryUtilities::UUIDtoTagCompound));
properties.setTag("allyNames", WizardryUtilities.listToNBT(this.allyNames, NBTTagString::new)); properties.setTag("allyNames", WizardryUtilities.listToNBT(this.allyNames, NBTTagString::new));
properties.setTag("soulboundCreatures", WizardryUtilities.listToNBT(this.soulboundCreatures, WizardryUtilities::UUIDtoTagCompound)); properties.setTag("soulboundCreatures",
WizardryUtilities.listToNBT(this.soulboundCreatures, WizardryUtilities::UUIDtoTagCompound));
// Might be worth converting this over to WizardryUtilities.listToNBT. // Might be worth converting this over to WizardryUtilities.listToNBT.
int[] spells = new int[this.spellsDiscovered.size()]; int[] spells = new int[this.spellsDiscovered.size()];
int i=0; int i = 0;
for(Spell spell : this.spellsDiscovered){ for(Spell spell : this.spellsDiscovered){
spells[i] = spell.id(); spells[i] = spell.id();
i++; i++;
@@ -484,7 +542,7 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
} }
@Override @Override
public void deserializeNBT(NBTTagCompound nbt) { public void deserializeNBT(NBTTagCompound nbt){
if(nbt != null){ if(nbt != null){
@@ -504,11 +562,11 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
this.allies = new HashSet<UUID>(WizardryUtilities.NBTToList(nbt.getTagList("allies", NBT.TAG_COMPOUND), this.allies = new HashSet<UUID>(WizardryUtilities.NBTToList(nbt.getTagList("allies", NBT.TAG_COMPOUND),
WizardryUtilities::tagCompoundToUUID)); WizardryUtilities::tagCompoundToUUID));
this.allyNames = new HashSet<String>(WizardryUtilities.NBTToList(nbt.getTagList("allyNames", NBT.TAG_STRING), this.allyNames = new HashSet<String>(
NBTTagString::getString)); WizardryUtilities.NBTToList(nbt.getTagList("allyNames", NBT.TAG_STRING), NBTTagString::getString));
this.soulboundCreatures = new HashSet<UUID>(WizardryUtilities.NBTToList(nbt.getTagList("soulboundCreatures", NBT.TAG_COMPOUND), this.soulboundCreatures = new HashSet<UUID>(WizardryUtilities.NBTToList(
WizardryUtilities::tagCompoundToUUID)); nbt.getTagList("soulboundCreatures", NBT.TAG_COMPOUND), WizardryUtilities::tagCompoundToUUID));
this.spellsDiscovered = new HashSet<Spell>(); this.spellsDiscovered = new HashSet<Spell>();
for(int id : nbt.getIntArray("discoveredSpells")){ for(int id : nbt.getIntArray("discoveredSpells")){
@@ -516,20 +574,21 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
} }
} }
} }
// Event handlers // Event handlers
@SubscribeEvent @SubscribeEvent
// The type parameter here has to be Entity, not EntityPlayer, or the event won't get fired. // The type parameter here has to be Entity, not EntityPlayer, or the event won't get fired.
public static void onCapabilityLoad(AttachCapabilitiesEvent<Entity> event){ public static void onCapabilityLoad(AttachCapabilitiesEvent<Entity> event){
if(event.getObject() instanceof EntityPlayer) if(event.getObject() instanceof EntityPlayer)
event.addCapability(new ResourceLocation(Wizardry.MODID, "WizardData"), new WizardData.Provider((EntityPlayer)event.getObject())); event.addCapability(new ResourceLocation(Wizardry.MODID, "WizardData"),
new WizardData.Provider((EntityPlayer)event.getObject()));
// This demonstrates why capabilities are badly structured: The following code compiles, but what it does is put // This demonstrates why capabilities are badly structured: The following code compiles, but what it does is put
// a player into a CapabilityDispatcher, which is in turn stored in that very same player, which makes no sense // a player into a CapabilityDispatcher, which is in turn stored in that very same player, which makes no sense
// at all! // at all!
//event.addCapability(new ResourceLocation(Wizardry.MODID, "WizardData"), event.getObject()); // event.addCapability(new ResourceLocation(Wizardry.MODID, "WizardData"), event.getObject());
} }
@SubscribeEvent @SubscribeEvent
@@ -540,32 +599,34 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
newData.copyFrom(oldData, event.isWasDeath()); newData.copyFrom(oldData, event.isWasDeath());
} }
@SubscribeEvent @SubscribeEvent
public static void onEntityJoinWorld(EntityJoinWorldEvent event){ public static void onEntityJoinWorld(EntityJoinWorldEvent event){
if(!event.getEntity().worldObj.isRemote && event.getEntity() instanceof EntityPlayerMP){ if(!event.getEntity().world.isRemote && event.getEntity() instanceof EntityPlayerMP){
// Synchronises wizard data after loading. // Synchronises wizard data after loading.
WizardData data = WizardData.get((EntityPlayer)event.getEntity()); WizardData data = WizardData.get((EntityPlayer)event.getEntity());
if(data != null) data.sync(); if(data != null) data.sync();
} }
} }
@SubscribeEvent @SubscribeEvent
public static void onLivingUpdateEvent(LivingUpdateEvent event){ public static void onLivingUpdateEvent(LivingUpdateEvent event){
if(event.getEntityLiving() instanceof EntityPlayer){ if(event.getEntityLiving() instanceof EntityPlayer){
EntityPlayer player = (EntityPlayer)event.getEntityLiving(); EntityPlayer player = (EntityPlayer)event.getEntityLiving();
if(WizardData.get(player) != null){ if(WizardData.get(player) != null){
WizardData.get(player).update(); WizardData.get(player).update();
} }
} }
} }
/** This is a nested class for a few reasons: firstly, it makes sense because instances of this and WizardData go /**
* This is a nested class for a few reasons: firstly, it makes sense because instances of this and WizardData go
* hand-in-hand; secondly, it's too short to be worth a separate file; and thirdly (and most importantly) it allows * hand-in-hand; secondly, it's too short to be worth a separate file; and thirdly (and most importantly) it allows
* me to access WIZARD_DATA_CAPABILITY while keeping it private. */ * me to access WIZARD_DATA_CAPABILITY while keeping it private.
*/
public static class Provider implements ICapabilitySerializable<NBTTagCompound> { public static class Provider implements ICapabilitySerializable<NBTTagCompound> {
private final WizardData data; private final WizardData data;
@@ -575,12 +636,12 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
} }
@Override @Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing) { public boolean hasCapability(Capability<?> capability, EnumFacing facing){
return capability == WIZARD_DATA_CAPABILITY; return capability == WIZARD_DATA_CAPABILITY;
} }
@Override @Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing) { public <T> T getCapability(Capability<T> capability, EnumFacing facing){
if(capability == WIZARD_DATA_CAPABILITY){ if(capability == WIZARD_DATA_CAPABILITY){
return WIZARD_DATA_CAPABILITY.cast(data); return WIZARD_DATA_CAPABILITY.cast(data);
@@ -590,12 +651,12 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
} }
@Override @Override
public NBTTagCompound serializeNBT() { public NBTTagCompound serializeNBT(){
return data.serializeNBT(); return data.serializeNBT();
} }
@Override @Override
public void deserializeNBT(NBTTagCompound nbt) { public void deserializeNBT(NBTTagCompound nbt){
data.deserializeNBT(nbt); data.deserializeNBT(nbt);
} }
@@ -611,50 +672,44 @@ public class WizardData implements INBTSerializable<NBTTagCompound> {
* "...without having to directly implement many interfaces." - Forge Docs. I still can't see what's wrong with * "...without having to directly implement many interfaces." - Forge Docs. I still can't see what's wrong with
* implementing many interfaces; surely that's what Java interfaces are designed for? * implementing many interfaces; surely that's what Java interfaces are designed for?
* *
* Other things I find annoying: * Other things I find annoying: - IStorage. It's completely redundant in the majority of cases, and I don't
* - IStorage. It's completely redundant in the majority of cases, and I don't understand why we need yet another * understand why we need yet another separate class. - Making an interface, only to implement it once and once
* separate class. * only. This completely defeats the point of interfaces. - The EnumFacing parameter, which is again redundant for
* - Making an interface, only to implement it once and once only. This completely defeats the point of interfaces. * everything that isn't a tile entity. So much for a clean, neat system.
* - The EnumFacing parameter, which is again redundant for everything that isn't a tile entity. So much for a clean,
* neat system.
* *
* What Forge has effectively done is conflated two different functions: attaching data to stuff and cross-mod * What Forge has effectively done is conflated two different functions: attaching data to stuff and cross-mod
* integration/soft dependencies. I think this is bad design; it would have been better to keep the two features separate. * integration/soft dependencies. I think this is bad design; it would have been better to keep the two features
* separate.
* *
* Here's my current understanding of how the capability system works: * Here's my current understanding of how the capability system works: - You make an interface which defines the
* - You make an interface which defines the things your capability can do (this class). I will call this the TEMPLATE. * things your capability can do (this class). I will call this the TEMPLATE. - You implement that interface with
* - You implement that interface with your default implementation (WizardData). This is the closest analog to your old * your default implementation (WizardData). This is the closest analog to your old IEEP implementation class. THIS
* IEEP implementation class. THIS CLASS STORES ALL THE VARIABLES, and hence has one instance for each instance of whatever * CLASS STORES ALL THE VARIABLES, and hence has one instance for each instance of whatever it is attached to. I
* it is attached to. I will call this the DATA. * will call this the DATA. - The DATA class implements INBTSerializable (assuming you want it to be saved, which is
* - The DATA class implements INBTSerializable (assuming you want it to be saved, which is nearly always the case) * nearly always the case) - Despite its name, Capability<T> does NOT represent a capability itself. Instead, it
* - Despite its name, Capability<T> does NOT represent a capability itself. Instead, it acts as a sort of identifier/key, * acts as a sort of identifier/key, the idea being that you can access a particular instance of your DATA given the
* the idea being that you can access a particular instance of your DATA given the key (which tells forge that you want a * key (which tells forge that you want a capability of type TEMPLATE) and the object you want the DATA for. This is
* capability of type TEMPLATE) and the object you want the DATA for. This is what Entity.getCapability(...) does. * what Entity.getCapability(...) does.
* *
* To really understand what's going on though, you need to sift through Forge's verbose data structures and find where * To really understand what's going on though, you need to sift through Forge's verbose data structures and find
* capabilities are actually hooked into vanilla: * where capabilities are actually hooked into vanilla: - Anything that implements ICapabilityProvider will have a
* - Anything that implements ICapabilityProvider will have a private CapabilityDispatcher field. This holds other * private CapabilityDispatcher field. This holds other ICapabilityProviders. (I know. This inheritance pattern DOES
* ICapabilityProviders. (I know. This inheritance pattern DOES NOT MAKE SENSE, because these could, in theory, be OTHER * NOT MAKE SENSE, because these could, in theory, be OTHER ENTITIES!) - This field is assigned a value through
* ENTITIES!) * Forge's event factory, which, as we are all familiar with, calls all the methods marked with @SubscribeEvent.
* - This field is assigned a value through Forge's event factory, which, as we are all familiar with, calls all the * These methods add individual ICapabilityProviders to a Map stored in the event, which the event factory then
* methods marked with @SubscribeEvent. These methods add individual ICapabilityProviders to a Map stored in the event, * wraps in a CapabilityDispatcher (which is itself an ICapabilityProvider) for the object that called it. - In your
* which the event factory then wraps in a CapabilityDispatcher (which is itself an ICapabilityProvider) for the object * event handler, you return a custom ICapabilityProvider which is effectively bolted on to the player, and
* that called it. * duplicates the ICapabilityProvider methods so you can hook into them and return an instance of your DATA class. -
* - In your event handler, you return a custom ICapabilityProvider which is effectively bolted on to the player, and * Where before there was a simple collection of IEEPs stored in the player, there is now a tree of
* duplicates the ICapabilityProvider methods so you can hook into them and return an instance of your DATA class. * ICapabilityProviders:
* - Where before there was a simple collection of IEEPs stored in the player, there is now a tree of ICapabilityProviders:
* *
* - Entity/TileEntity/ItemStack * - Entity/TileEntity/ItemStack - Vanilla ICapabilityProviders, mostly IItemHandlers, stored as fields. -
* - Vanilla ICapabilityProviders, mostly IItemHandlers, stored as fields. * CapabilityDispatcher, stored as a field. - Custom ICapabilityProviders - Custom CapabilityDispatchers - ...
* - CapabilityDispatcher, stored as a field.
* - Custom ICapabilityProviders
* - Custom CapabilityDispatchers
* - ...
* *
* Most importantly, EACH PLAYER HOLDS THEIR OWN INSTANCE OF THIS TREE. * Most importantly, EACH PLAYER HOLDS THEIR OWN INSTANCE OF THIS TREE.
* *
* When a capability is retrieved, the following process happens: * When a capability is retrieved, the following process happens: 1. For the Entity/TileEntity/ItemStack instance,
* 1. For the Entity/TileEntity/ItemStack instance, ICapabilityProvider.getCapability(...) is called. * ICapabilityProvider.getCapability(...) is called. 2. The request propogates through the tree and finds the
* 2. The request propogates through the tree and finds the requested capability. */ * requested capability. */
} }
@@ -7,80 +7,65 @@ import electroblob.wizardry.command.CommandDiscoverSpell;
import electroblob.wizardry.command.CommandSetAlly; import electroblob.wizardry.command.CommandSetAlly;
import electroblob.wizardry.command.CommandViewAllies; import electroblob.wizardry.command.CommandViewAllies;
import electroblob.wizardry.packet.WizardryPacketHandler; import electroblob.wizardry.packet.WizardryPacketHandler;
import electroblob.wizardry.registry.WizardryAchievements; import electroblob.wizardry.registry.WizardryAdvancementTriggers;
import electroblob.wizardry.registry.WizardryItems; import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryRegistry; import electroblob.wizardry.registry.WizardryRegistry;
import electroblob.wizardry.registry.WizardryTabs; import electroblob.wizardry.registry.WizardryTabs;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTBase;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.AchievementPage;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.Capability.IStorage; import net.minecraftforge.common.capabilities.Capability.IStorage;
import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.Instance; import net.minecraftforge.fml.common.Mod.Instance;
import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLMissingMappingsEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLServerStartingEvent; import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry; import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry.Type;
@Mod(modid = Wizardry.MODID, name = Wizardry.NAME, version = Wizardry.VERSION, guiFactory = "electroblob." + Wizardry.MODID + ".WizardryGuiFactory") @Mod(modid = Wizardry.MODID, name = Wizardry.NAME, version = Wizardry.VERSION, guiFactory = "electroblob.wizardry.WizardryGuiFactory")
public class Wizardry { public class Wizardry {
/** Wizardry's mod ID. */ /** Wizardry's mod ID. */
public static final String MODID = "wizardry"; public static final String MODID = "ebwizardry";
/** Wizardry's mod name, in readable form. */ /** Wizardry's mod name, in readable form. */
public static final String NAME = "Electroblob's Wizardry"; public static final String NAME = "Electroblob's Wizardry";
/** The version number for this version of wizardry. The following system is used for version numbers: /**
* <p><center><b>[major Minecraft version].[major mod version].[minor mod version/patch]<p></center></b> * The version number for this version of wizardry. The following system is used for version numbers:
* The major mod version is consistent across Minecraft versions, i.e. Wizardry 1.1 has the same features as * <p>
* Wizardry 2.1, but they are for different versions of Minecraft and have separate minor versioning. 1.x.x * <center><b>[major Minecraft version].[major mod version].[minor mod version/patch]
* represents Minecraft 1.7.x versions, 2.x.x represents Minecraft 1.10.x versions, 3.x.x represents Minecraft * <p>
* 1.11.x versions, and so on. */ * </center></b> The major mod version is consistent across Minecraft versions, i.e. Wizardry 1.1 has the same
public static final String VERSION = "2.1.0"; * features as Wizardry 2.1, but they are for different versions of Minecraft and have separate minor versioning.
* 1.x.x represents Minecraft 1.7.x versions, 2.x.x represents Minecraft 1.10.x versions, 3.x.x represents Minecraft
* 1.11.x versions, and so on.
*/
public static final String VERSION = "4.1.2";
// IDEA: Improve the algorithm that finds a place to summon creatures to take walls into account. // IDEA: Improve the algorithm that finds a place to summon creatures to take walls into account.
// IDEA: Replace all uses of Math.cos and Math.sin with MathHelper versions // IDEA: Replace all uses of Math.cos and Math.sin with MathHelper versions
// IDEA: API feature that automatically injects custom wand upgrades into wizardry's loot tables // IDEA: Triggering of inbuilt Forge events in relevant places?
// IDEA: Support for the @e selector in the /cast command (the methods already exist, just plug them in)
// IDEA: Dispensers shooting spells from scrolls! Imagine the possibilities!
// == Rendering overhaul! ==
// IDEA: Make spirit animals fade away when dispelled
// IDEA: Use your newfound knowledge of OpenGL to render animated boxes around entities being buffed, similar to creeper charge
// IDEA: Redo RenderArc so it looks like lightning (it's literally a load of translucent boxes inside each other)
// IDEA: The arcane workbench could use a few particles
// IDEA: Add a box to the wizard armour model so that the robes bend when the wearer is sneaking
// IDEA: Flash particle (I think it exists in vanilla somewhere) on spell impact
// IDEA: Dust particles spray out from projectiles as they move
// IDEA: Colour fading for particles
// IDEA: Make lightning and other effects particles. There's no reason why you can't pass in a player argument and have the particles move with them!
/* Minor bugs that need fixing at some point: /* Minor bugs that need fixing at some point:
* - Player skin hat layer shows through wizard hats * - Player skin hat layer shows through wizard hats - Wizard armour breaks rather than just running out of mana (I
* - Wizard armour breaks rather than just running out of mana (I can't seem to replicate this bug, but I have had * can't seem to replicate this bug, but I have had it happen to me before...)
* it happen to me before...)
* - Shift-clicking a stack of special upgrades when in the arcane workbench causes the whole stack to be * - Shift-clicking a stack of special upgrades when in the arcane workbench causes the whole stack to be
* transferred when it should be just one (this is a bug with vanilla as well - try putting a stack of bottles into * transferred when it should be just one (this is a bug with vanilla as well - try putting a stack of bottles into
* a brewing stand). I have at least made it so only one gets used now, so it has no impact on the game. * a brewing stand). I have at least made it so only one gets used now, so it has no impact on the game.
* - When a spell is on cooldown, you can't break blocks when holding a wand. */ * - When a spell is on cooldown, you can't break blocks when holding a wand. */
// TODO: So somehow I have managed to overlook the fact that health is actually a float. What this means is that // TODO: So somehow I have managed to overlook the fact that health is actually a float. What this means is that
// I can make the healing spells use damage multipliers - hurrah! // I can make the healing spells use damage multipliers - hurrah!
// TODO: Switch from IInventory to IItemHandler (Or don't. It's only useful for automation really.) // TODO: Switch from IInventory to IItemHandler (Or don't. It's only useful for automation really.)
// TODO: Triggering of inbuilt Forge events in relevant places?
// TODO: Implement custom events
// TODO: Rearrange the config gui and file
// TODO: Have particles obey Minecraft's particle setting where appropriate // TODO: Have particles obey Minecraft's particle setting where appropriate
// (see https://github.com/RootsTeam/Embers/blob/master/src/main/java/teamroots/embers/particle/ParticleUtil.java) // (see https://github.com/RootsTeam/Embers/blob/master/src/main/java/teamroots/embers/particle/ParticleUtil.java)
@@ -88,12 +73,12 @@ public class Wizardry {
/** Static instance of the {@link Settings} object for Wizardry. */ /** Static instance of the {@link Settings} object for Wizardry. */
public static final Settings settings = new Settings(); public static final Settings settings = new Settings();
/** Static instance of the {@link Logger} object for Wizardry. */ /** Static instance of the {@link Logger} object for Wizardry. */
public static Logger logger; public static Logger logger;
//private static Pattern entityNamePattern; // private static Pattern entityNamePattern;
// EventManager // EventManager
WizardryWorldGenerator generator = new WizardryWorldGenerator(); WizardryWorldGenerator generator = new WizardryWorldGenerator();
@@ -102,19 +87,16 @@ public class Wizardry {
public static Wizardry instance; public static Wizardry instance;
// Location of the proxy code, used by Forge. // Location of the proxy code, used by Forge.
@SidedProxy(clientSide="electroblob.wizardry.client.ClientProxy", serverSide="electroblob.wizardry.CommonProxy") @SidedProxy(clientSide = "electroblob.wizardry.client.ClientProxy", serverSide = "electroblob.wizardry.CommonProxy")
public static CommonProxy proxy; public static CommonProxy proxy;
@EventHandler @EventHandler
public void preInit(FMLPreInitializationEvent event){ public void preInit(FMLPreInitializationEvent event){
logger = event.getModLog(); logger = event.getModLog();
// The array in question no longer exists, so I'm pretty sure this isn't necessary any more.
// expandPotionTypesArray();
settings.initConfig(event); settings.initConfig(event);
// Yes - by the looks of it, having an interface is completely unnecessary in this case. // Yes - by the looks of it, having an interface is completely unnecessary in this case.
CapabilityManager.INSTANCE.register(WizardData.class, new IStorage<WizardData>(){ CapabilityManager.INSTANCE.register(WizardData.class, new IStorage<WizardData>(){
// These methods are only called by Capability.writeNBT() or Capability.readNBT(), which in turn are // These methods are only called by Capability.writeNBT() or Capability.readNBT(), which in turn are
@@ -122,21 +104,28 @@ public class Wizardry {
// to allow capabilities to be saved and loaded manually. What that would be useful for I don't know. // to allow capabilities to be saved and loaded manually. What that would be useful for I don't know.
// (If an API forces most users to write redundant code for no reason, it's not user friendly, is it?) // (If an API forces most users to write redundant code for no reason, it's not user friendly, is it?)
// ... well, that's my rant for today! // ... well, that's my rant for today!
@Override public NBTBase writeNBT(Capability<WizardData> capability, WizardData instance, EnumFacing side){ return null; } @Override
@Override public void readNBT(Capability<WizardData> capability, WizardData instance, EnumFacing side, NBTBase nbt){} public NBTBase writeNBT(Capability<WizardData> capability, WizardData instance, EnumFacing side){
}, WizardData.class); return null;
}
@Override
public void readNBT(Capability<WizardData> capability, WizardData instance, EnumFacing side, NBTBase nbt){
}
}, WizardData::new);
WizardryRegistry.registerTileEntities(); WizardryRegistry.registerTileEntities();
WizardryRegistry.registerEntities(this); WizardryRegistry.registerEntities();
// The check for the generateLoot setting is now done within this method. // The check for the generateLoot setting is now done within this method.
WizardryRegistry.registerLoot(); WizardryRegistry.registerLoot();
// NOTE: Will need to be moved to init for 1.12, as will anything that needs to be after the registry events. WizardryAdvancementTriggers.register();
WizardryTabs.sort();
// Moved to preInit, because apparently it has to be here now. // Moved to preInit, because apparently it has to be here now.
proxy.registerRenderers(); proxy.registerRenderers();
// It seems this also has to be here
proxy.registerKeyBindings();
} }
@@ -145,8 +134,6 @@ public class Wizardry {
settings.initConfigExtras(); settings.initConfigExtras();
proxy.registerKeyBindings();
// Event Handlers // Event Handlers
GameRegistry.registerWorldGenerator(generator, 0); GameRegistry.registerWorldGenerator(generator, 0);
MinecraftForge.EVENT_BUS.register(new WizardryKeyHandler()); MinecraftForge.EVENT_BUS.register(new WizardryKeyHandler());
@@ -155,40 +142,28 @@ public class Wizardry {
NetworkRegistry.INSTANCE.registerGuiHandler(this, new WizardryGuiHandler()); NetworkRegistry.INSTANCE.registerGuiHandler(this, new WizardryGuiHandler());
WizardryPacketHandler.initPackets(); WizardryPacketHandler.initPackets();
// Achievements proxy.initGuiBits();
AchievementPage.registerAchievementPage(WizardryAchievements.WIZARDRY_ACHIEVEMENT_PAGE);
// Recipes
WizardryRegistry.registerRecipes();
proxy.initMixedFontRenderer();
} }
@EventHandler @EventHandler
public void postInit(FMLPostInitializationEvent event){ public void postInit(FMLPostInitializationEvent event){
// This needs to be here or it won't necessarily include all the mods' entities. // This needs to be here or it won't necessarily include all the mods' entities.
// TODO: Re-implement this when the Forge bug is fixed. // TODO: Re-implement this when the Forge bug is fixed.
/* Doesn't seem to be doing anything... /* Doesn't seem to be doing anything... String entityNames = ""; for(Object name :
String entityNames = ""; * EntityList.classToStringMapping.values()){ if(name instanceof String){ entityNames = entityNames + name +
for(Object name : EntityList.classToStringMapping.values()){ * '|'; } } // Cuts off the last '|' entityNames = entityNames.substring(0, entityNames.length()-1);
if(name instanceof String){ * entityNamePattern = Pattern.compile(entityNames); */
entityNames = entityNames + name + '|';
}
}
// Cuts off the last '|'
entityNames = entityNames.substring(0, entityNames.length()-1);
entityNamePattern = Pattern.compile(entityNames);
*/
proxy.initialiseLayers(); proxy.initialiseLayers();
WizardryTabs.sort();
} }
@EventHandler @EventHandler
public void serverStarting(FMLServerStartingEvent event){ public void serverStarting(FMLServerStartingEvent event){
event.registerServerCommand(new CommandCastSpell()); event.registerServerCommand(new CommandCastSpell());
event.registerServerCommand(new CommandSetAlly()); event.registerServerCommand(new CommandSetAlly());
event.registerServerCommand(new CommandViewAllies()); event.registerServerCommand(new CommandViewAllies());
event.registerServerCommand(new CommandDiscoverSpell()); event.registerServerCommand(new CommandDiscoverSpell());
} }
@SubscribeEvent @SubscribeEvent
public void onConfigChanged(net.minecraftforge.fml.client.event.ConfigChangedEvent.OnConfigChangedEvent event){ public void onConfigChanged(net.minecraftforge.fml.client.event.ConfigChangedEvent.OnConfigChangedEvent event){
@@ -199,18 +174,17 @@ public class Wizardry {
} }
// 2.1 changed some item ids, so this fixes them for existing worlds // 2.1 changed some item ids, so this fixes them for existing worlds
// NOTE: Needs changing to RegistryEvent.MissingMapping in 1.12, or just removing since nobody updates minecraft // Nobody updates minecraft versions when using mods, but I may as well leave this here just in case.
// versions when using mods. @SubscribeEvent
@EventHandler public static void onMissingMappingEvent(RegistryEvent.MissingMappings<Item> event){
public static void onMissingMappingEvent(FMLMissingMappingsEvent event){
// Just get, not getAll, since the mod id didn't change! // Just get, not getAll, since the mod id didn't change!
for(FMLMissingMappingsEvent.MissingMapping mapping : event.get()){ for(RegistryEvent.MissingMappings.Mapping<Item> mapping : event.getAllMappings()){
if(mapping.type == Type.ITEM && mapping.resourceLocation.getResourceDomain().equals(Wizardry.MODID)){ if(mapping.key.getResourceDomain().equals(Wizardry.MODID)){
Item replacement = null; Item replacement = null;
switch(mapping.resourceLocation.getResourcePath()){ switch(mapping.key.getResourcePath()){
case "wand_basic": replacement = WizardryItems.magic_wand; break; case "wand_basic": replacement = WizardryItems.magic_wand; break;
case "wand_basic_fire": replacement = WizardryItems.basic_fire_wand; break; case "wand_basic_fire": replacement = WizardryItems.basic_fire_wand; break;
case "wand_basic_ice": replacement = WizardryItems.basic_ice_wand; break; case "wand_basic_ice": replacement = WizardryItems.basic_ice_wand; break;
@@ -252,12 +226,13 @@ public class Wizardry {
case "upgrade_blast": replacement = WizardryItems.blast_upgrade; break; case "upgrade_blast": replacement = WizardryItems.blast_upgrade; break;
case "upgrade_attunement": replacement = WizardryItems.attunement_upgrade; break; case "upgrade_attunement": replacement = WizardryItems.attunement_upgrade; break;
// If it didn't match any of the ones that changed, do nothing. // If it didn't match any of the ones that changed, do nothing.
default: return; default:
return;
} }
// No need to log, Forge does that. // No need to log, Forge does that.
mapping.remap(replacement); mapping.remap(replacement);
} }
} }
} }
} }
@@ -10,7 +10,7 @@ import electroblob.wizardry.event.SpellCastEvent;
import electroblob.wizardry.item.ItemWand; import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.item.ItemWizardArmour; import electroblob.wizardry.item.ItemWizardArmour;
import electroblob.wizardry.registry.Spells; import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardryAchievements; import electroblob.wizardry.registry.WizardryAdvancementTriggers;
import electroblob.wizardry.registry.WizardryEnchantments; import electroblob.wizardry.registry.WizardryEnchantments;
import electroblob.wizardry.registry.WizardryItems; import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryPotions; import electroblob.wizardry.registry.WizardryPotions;
@@ -56,28 +56,15 @@ import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.event.entity.living.LivingDropsEvent; import net.minecraftforge.event.entity.living.LivingDropsEvent;
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent; import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
import net.minecraftforge.event.entity.living.LivingHurtEvent; import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.event.entity.player.EntityItemPickupEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent;
// Better ways of organising event handling:
// - Split it into several separate handlers, each with a logical area to deal with (see Astral Sorcery)
// - Remove most of the stuff, and have individual spell, item, block, entity, etc. classes handle their own events
// (see Botania)
// - Keep all the methods, but delegate near-repeated behaviours to their individual spell/potion/whatever classes
// (TGG does this, apparently)
// Incidentally, Twilight Forest still has one big event handler class - and a comment about how it's so long...!
// In the end, I decided the most pragmatic solution was to either use the second option or keep things how they were,
// whichever will result in more readable/easily maintainable code in each case. To keep in line with the modularity
// of the spell system, the goal is to have nothing in here which relates to a specific spell (mostly done, but a few
// things remain).
/** /**
* As of Wizardry 2.1, most of the code in this class has been relocated somewhere sensible, leaving only a few * As of Wizardry 2.1, most of the code in this class has been relocated somewhere sensible, leaving only a few
* miscellaneous things that don't make much sense anywhere else, or that are better kept together. Previously, this was * miscellaneous things that don't make much sense anywhere else, or that are better kept together. Previously, this was
* a gigantic class with about half of the entire mod's logic in it! * a gigantic class with about half of the entire mod's logic in it!
*
* @author Electroblob * @author Electroblob
* @since Wizardry 1.0 * @since Wizardry 1.0
*/ */
@@ -85,84 +72,83 @@ import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent;
public final class WizardryEventHandler { public final class WizardryEventHandler {
// IDEA: Config option allowing users to specify loot locations // IDEA: Config option allowing users to specify loot locations
private static final String[] LOOT_INJECTION_LOCATIONS = { private static final String[] LOOT_INJECTION_LOCATIONS = {"minecraft:chests/simple_dungeon",
"minecraft:chests/simple_dungeon", "minecraft:chests/abandoned_mineshaft", "minecraft:chests/desert_pyramid", "minecraft:chests/jungle_temple",
"minecraft:chests/abandoned_mineshaft", "minecraft:chests/stronghold_corridor", "minecraft:chests/stronghold_crossing",
"minecraft:chests/desert_pyramid", "minecraft:chests/stronghold_library", "minecraft:chests/igloo_chest", "minecraft:chests/woodland_mansion",
"minecraft:chests/jungle_temple", "minecraft:chests/end_city_treasure"};
"minecraft:chests/stronghold_corridor",
"minecraft:chests/stronghold_crossing",
"minecraft:chests/stronghold_library",
"minecraft:chests/igloo_chest"
};
@SubscribeEvent @SubscribeEvent
public static void onLootTableLoadEvent(LootTableLoadEvent event){ public static void onLootTableLoadEvent(LootTableLoadEvent event){
if(Wizardry.settings.generateLoot){ if(Wizardry.settings.generateLoot){
for(String location : LOOT_INJECTION_LOCATIONS){ for(String location : LOOT_INJECTION_LOCATIONS){
if(event.getName().toString().matches(location)){ if(event.getName().toString().matches(location)){
event.getTable().addPool(getAdditive("wizardry:chests/dungeon_additions")); event.getTable().addPool(getAdditive(Wizardry.MODID + ":chests/dungeon_additions"));
} }
} }
} }
} }
private static LootPool getAdditive(String entryName){ private static LootPool getAdditive(String entryName){
return new LootPool(new LootEntry[] { getAdditiveEntry(entryName, 1) }, new LootCondition[0], new RandomValueRange(1), new RandomValueRange(0, 1), Wizardry.MODID + "_additive_pool"); return new LootPool(new LootEntry[]{getAdditiveEntry(entryName, 1)}, new LootCondition[0],
new RandomValueRange(1), new RandomValueRange(0, 1), Wizardry.MODID + "_additive_pool");
} }
private static LootEntryTable getAdditiveEntry(String name, int weight){ private static LootEntryTable getAdditiveEntry(String name, int weight){
return new LootEntryTable(new ResourceLocation(name), weight, 0, new LootCondition[0], Wizardry.MODID + "_additive_entry"); return new LootEntryTable(new ResourceLocation(name), weight, 0, new LootCondition[0],
Wizardry.MODID + "_additive_entry");
} }
@SubscribeEvent @SubscribeEvent
public static void onPlayerLoggedInEvent(PlayerLoggedInEvent event){ public static void onPlayerLoggedInEvent(PlayerLoggedInEvent event){
// When a player logs in, they are sent the glyph data and the server's settings. // When a player logs in, they are sent the glyph data and the server's settings.
if(event.player instanceof EntityPlayerMP){ if(event.player instanceof EntityPlayerMP){
SpellGlyphData.get(event.player.worldObj).sync((EntityPlayerMP)event.player); SpellGlyphData.get(event.player.world).sync((EntityPlayerMP)event.player);
Wizardry.settings.sync((EntityPlayerMP)event.player); Wizardry.settings.sync((EntityPlayerMP)event.player);
} }
} }
@SubscribeEvent @SubscribeEvent
public static void onSpellCastPreEvent(SpellCastEvent.Pre event){ public static void onSpellCastPreEvent(SpellCastEvent.Pre event){
// If a spell is disabled in the config, it will not work. // If a spell is disabled in the config, it will not work.
if(!event.getSpell().isEnabled()){ if(!event.getSpell().isEnabled()){
if(!event.getEntityLiving().worldObj.isRemote) if(!event.getEntityLiving().world.isRemote) event.getEntity().sendMessage(
event.getEntity().addChatMessage(new TextComponentTranslation("spell.disabled", event.getSpell().getNameForTranslationFormatted())); new TextComponentTranslation("spell.disabled", event.getSpell().getNameForTranslationFormatted()));
event.setCanceled(true); event.setCanceled(true);
} }
} }
@SubscribeEvent @SubscribeEvent
public static void onSpellCastPostEvent(SpellCastEvent.Post event){ public static void onSpellCastPostEvent(SpellCastEvent.Post event){
// Spell discovery (only players can discover spells, obviously) // Spell discovery (only players can discover spells, obviously)
if(event.getEntity() instanceof EntityPlayer){ if(event.getEntity() instanceof EntityPlayer){
EntityPlayer player = (EntityPlayer)event.getEntity(); EntityPlayer player = (EntityPlayer)event.getEntity();
WizardData data = WizardData.get(player); WizardData data = WizardData.get(player);
if(data != null){ if(data != null){
// Data is updated on both sides (This line was added client-side to fix a bug back in 1.1.3, so now // Data is updated on both sides (This line was added client-side to fix a bug back in 1.1.3, so now
// it's in common code, which is nice!) // it's in common code, which is nice!)
// Short-circuiting AND means that discoverSpell is only called if the event isn't cancelled. // Short-circuiting AND means that discoverSpell is only called if the event isn't cancelled.
if(!MinecraftForge.EVENT_BUS.post(new DiscoverSpellEvent(player, event.getSpell(), if(!MinecraftForge.EVENT_BUS
DiscoverSpellEvent.Source.CASTING)) && data.discoverSpell(event.getSpell())){ .post(new DiscoverSpellEvent(player, event.getSpell(), DiscoverSpellEvent.Source.CASTING))
&& data.discoverSpell(event.getSpell())){
// If the spell wasn't already discovered, other stuff happens: // If the spell wasn't already discovered, other stuff happens:
if(event.getSource() == SpellCastEvent.Source.COMMAND){ if(event.getSource() == SpellCastEvent.Source.COMMAND){
// If the spell didn't send a packet itself, the extended player needs to be synced so the // If the spell didn't send a packet itself, the extended player needs to be synced so the
// spell discovery updates on the client. // spell discovery updates on the client.
if(!event.getSpell().doesSpellRequirePacket()) data.sync(); if(!event.getSpell().doesSpellRequirePacket()) data.sync();
}else if(!event.getEntity().worldObj.isRemote && !player.capabilities.isCreativeMode }else if(!event.getEntity().world.isRemote && !player.capabilities.isCreativeMode
&& Wizardry.settings.discoveryMode){ && Wizardry.settings.discoveryMode){
// Sound and text only happen server-side, in survival, with discovery mode on, and only when // Sound and text only happen server-side, in survival, with discovery mode on, and only when
// the spell wasn't cast using commands. // the spell wasn't cast using commands.
WizardryUtilities.playSoundAtPlayer(player, SoundEvents.ENTITY_PLAYER_LEVELUP, 1.25f, 1); WizardryUtilities.playSoundAtPlayer(player, SoundEvents.ENTITY_PLAYER_LEVELUP, 1.25f, 1);
player.addChatMessage(new TextComponentTranslation("spell.discover", event.getSpell().getNameForTranslationFormatted())); player.sendMessage(new TextComponentTranslation("spell.discover",
event.getSpell().getNameForTranslationFormatted()));
} }
} }
} }
@@ -172,32 +158,24 @@ public final class WizardryEventHandler {
/* There is a subtle but important difference between LivingAttackEvent and LivingHurtEvent - LivingAttackEvent /* There is a subtle but important difference between LivingAttackEvent and LivingHurtEvent - LivingAttackEvent
* fires immediately when attackEntityFrom is called, whereas LivingHurtEvent only fires if the attack actually * fires immediately when attackEntityFrom is called, whereas LivingHurtEvent only fires if the attack actually
* succeeded, i.e. if the entity in question takes damage (though the event is fired before that so you can cancel * succeeded, i.e. if the entity in question takes damage (though the event is fired before that so you can cancel
* the damage). Things are processed in the following order: * the damage). Things are processed in the following order: * LivingAttackEvent * - Invulnerability -
* * LivingAttackEvent * * Already-dead-ness - Fire resistance - Helmets vs. falling things - Hurt resistant time - Invulnerability (again)
* - Invulnerability * * LivingHurtEvent * - Armour - Potions - Health is finally changed Of course, there are no guarantees that other
* - Already-dead-ness * mods hooking into these two events will be called before or after yours, but you can have some degree of control
* - Fire resistance * by choosing which event to use. EDIT: Actually, there are. Firstly, you can set a priority in the @SubscribeEvent
* - Helmets vs. falling things * annotation which defines how early (higher priority) or late (lower priority) the method is called. Methods with
* - Hurt resistant time * the same priority are sorted alphabetically by mod id (so it's safe to assume wizardry would be fairly late on!).
* - Invulnerability (again) * I wonder if there are any conventions for what sort of things take what priority...? */
* * LivingHurtEvent *
* - Armour
* - Potions
* - Health is finally changed
* Of course, there are no guarantees that other mods hooking into these two events will be called before or after
* yours, but you can have some degree of control by choosing which event to use.
* EDIT: Actually, there are. Firstly, you can set a priority in the @SubscribeEvent annotation which defines how
* early (higher priority) or late (lower priority) the method is called. Methods with the same priority are sorted
* alphabetically by mod id (so it's safe to assume wizardry would be fairly late on!). I wonder if there are any
* conventions for what sort of things take what priority...? */
@SubscribeEvent @SubscribeEvent
public static void onLivingAttackEvent(LivingAttackEvent event){ public static void onLivingAttackEvent(LivingAttackEvent event){
// Prevents any damage to allies from magic if friendly fire is enabled // Prevents any damage to allies from magic if friendly fire is disabled
if(!Wizardry.settings.friendlyFire && event.getSource() != null && event.getSource().getEntity() instanceof EntityPlayer if(!Wizardry.settings.friendlyFire && event.getSource() != null
&& event.getEntity() instanceof EntityPlayer && event.getSource() instanceof IElementalDamage){ && event.getSource().getTrueSource() instanceof EntityPlayer && event.getEntity() instanceof EntityPlayer
if(WizardryUtilities.isPlayerAlly((EntityPlayer)event.getSource().getEntity(), (EntityPlayer)event.getEntity())){ && event.getSource() instanceof IElementalDamage){
if(WizardryUtilities.isPlayerAlly((EntityPlayer)event.getSource().getTrueSource(),
(EntityPlayer)event.getEntity())){
event.setCanceled(true); event.setCanceled(true);
// This needs to be here, since if the event is cancelled nothing else needs to happen. // This needs to be here, since if the event is cancelled nothing else needs to happen.
return; return;
@@ -207,12 +185,12 @@ public final class WizardryEventHandler {
// Retaliatory effects // Retaliatory effects
// These are better off here because the revenge effects are pretty similar, and I'd rather keep the (lengthy) // These are better off here because the revenge effects are pretty similar, and I'd rather keep the (lengthy)
// if statement in one place. // if statement in one place.
if(event.getSource() != null && event.getSource().getEntity() instanceof EntityLivingBase if(event.getSource() != null && event.getSource().getTrueSource() instanceof EntityLivingBase
&& !event.getSource().isProjectile() && !(event.getSource() instanceof IElementalDamage && && !event.getSource().isProjectile() && !(event.getSource() instanceof IElementalDamage
((IElementalDamage)event.getSource()).isRetaliatory())){ && ((IElementalDamage)event.getSource()).isRetaliatory())){
EntityLivingBase attacker = (EntityLivingBase)event.getSource().getEntity(); EntityLivingBase attacker = (EntityLivingBase)event.getSource().getTrueSource();
World world = event.getEntityLiving().worldObj; World world = event.getEntityLiving().world;
// Fireskin // Fireskin
if(event.getEntityLiving().isPotionActive(WizardryPotions.fireskin) if(event.getEntityLiving().isPotionActive(WizardryPotions.fireskin)
@@ -220,8 +198,8 @@ public final class WizardryEventHandler {
attacker.setFire(5); attacker.setFire(5);
// Ice Shroud // Ice Shroud
if(event.getEntityLiving().isPotionActive(WizardryPotions.ice_shroud) && if(event.getEntityLiving().isPotionActive(WizardryPotions.ice_shroud)
!MagicDamage.isEntityImmune(DamageType.FROST, event.getEntityLiving())) && !MagicDamage.isEntityImmune(DamageType.FROST, event.getEntityLiving()))
attacker.addPotionEffect(new PotionEffect(WizardryPotions.frost, 100, 0)); attacker.addPotionEffect(new PotionEffect(WizardryPotions.frost, 100, 0));
// Static Aura // Static Aura
@@ -229,17 +207,25 @@ public final class WizardryEventHandler {
if(!world.isRemote){ if(!world.isRemote){
EntityArc arc = new EntityArc(world); EntityArc arc = new EntityArc(world);
arc.setEndpointCoords(event.getEntityLiving().posX, event.getEntityLiving().posY + 1, event.getEntityLiving().posZ, arc.setEndpointCoords(event.getEntityLiving().posX, event.getEntityLiving().posY + 1,
attacker.posX, attacker.posY + attacker.height/2, attacker.posZ); event.getEntityLiving().posZ, attacker.posX, attacker.posY + attacker.height / 2,
world.spawnEntityInWorld(arc); attacker.posZ);
world.spawnEntity(arc);
}else{ }else{
for(int i=0;i<8;i++){ for(int i = 0; i < 8; i++){
Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world, attacker.posX + world.rand.nextFloat() - 0.5, attacker.getEntityBoundingBox().minY + attacker.height/2 + world.rand.nextFloat()*2 - 1, attacker.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3); Wizardry.proxy.spawnParticle(WizardryParticleType.SPARK, world,
world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, attacker.posX + world.rand.nextFloat() - 0.5, attacker.getEntityBoundingBox().minY + attacker.height/2 + world.rand.nextFloat()*2 - 1, attacker.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0); attacker.posX + world.rand.nextFloat() - 0.5, attacker.getEntityBoundingBox().minY
+ attacker.height / 2 + world.rand.nextFloat() * 2 - 1,
attacker.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0, 3);
world.spawnParticle(EnumParticleTypes.SMOKE_LARGE, attacker.posX + world.rand.nextFloat() - 0.5,
attacker.getEntityBoundingBox().minY + attacker.height / 2 + world.rand.nextFloat() * 2
- 1,
attacker.posZ + world.rand.nextFloat() - 0.5, 0, 0, 0);
} }
} }
attacker.attackEntityFrom(MagicDamage.causeDirectMagicDamage(event.getEntityLiving(), DamageType.SHOCK, true), 4.0f); attacker.attackEntityFrom(
MagicDamage.causeDirectMagicDamage(event.getEntityLiving(), DamageType.SHOCK, true), 4.0f);
attacker.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.5F); attacker.playSound(WizardrySounds.SPELL_SPARK, 1.0F, world.rand.nextFloat() * 0.4F + 1.5F);
} }
} }
@@ -250,38 +236,42 @@ public final class WizardryEventHandler {
public static void onLivingHurtEvent(LivingHurtEvent event){ public static void onLivingHurtEvent(LivingHurtEvent event){
// Flaming and freezing swords // Flaming and freezing swords
if(event.getSource().getEntity() instanceof EntityLivingBase){ if(event.getSource().getTrueSource() instanceof EntityLivingBase){
EntityLivingBase attacker = (EntityLivingBase)event.getSource().getEntity(); EntityLivingBase attacker = (EntityLivingBase)event.getSource().getTrueSource();
// Players can only ever attack with their main hand, so this is the right method to use here. // Players can only ever attack with their main hand, so this is the right method to use here.
if(attacker.getHeldItemMainhand() != null && attacker.getHeldItemMainhand().getItem() instanceof ItemSword){ if(!attacker.getHeldItemMainhand().isEmpty() && attacker.getHeldItemMainhand().getItem() instanceof ItemSword){
int level = EnchantmentHelper.getEnchantmentLevel(WizardryEnchantments.flaming_weapon, attacker.getHeldItemMainhand()); int level = EnchantmentHelper.getEnchantmentLevel(WizardryEnchantments.flaming_weapon,
attacker.getHeldItemMainhand());
if(level > 0 && !MagicDamage.isEntityImmune(DamageType.FIRE, event.getEntityLiving())) if(level > 0 && !MagicDamage.isEntityImmune(DamageType.FIRE, event.getEntityLiving()))
event.getEntityLiving().setFire(level*4); event.getEntityLiving().setFire(level * 4);
level = EnchantmentHelper.getEnchantmentLevel(WizardryEnchantments.freezing_weapon, attacker.getHeldItemMainhand()); level = EnchantmentHelper.getEnchantmentLevel(WizardryEnchantments.freezing_weapon,
attacker.getHeldItemMainhand());
// Frost lasts for longer because it doesn't do any actual damage // Frost lasts for longer because it doesn't do any actual damage
if(level > 0 && !MagicDamage.isEntityImmune(DamageType.FROST, event.getEntityLiving())) if(level > 0 && !MagicDamage.isEntityImmune(DamageType.FROST, event.getEntityLiving()))
event.getEntityLiving().addPotionEffect(new PotionEffect(WizardryPotions.frost, level*200, 0)); event.getEntityLiving().addPotionEffect(new PotionEffect(WizardryPotions.frost, level * 200, 0));
} }
} }
// Freezing bow // Freezing bow
if(event.getSource().getSourceOfDamage() instanceof EntityArrow && event.getSource().getSourceOfDamage().getEntityData() != null){ if(event.getSource().getImmediateSource() instanceof EntityArrow
&& event.getSource().getImmediateSource().getEntityData() != null){
int level = event.getSource().getSourceOfDamage().getEntityData().getInteger(FreezingWeapon.FREEZING_ARROW_NBT_KEY); int level = event.getSource().getImmediateSource().getEntityData()
.getInteger(FreezingWeapon.FREEZING_ARROW_NBT_KEY);
if(level > 0 && !MagicDamage.isEntityImmune(DamageType.FROST, event.getEntityLiving())) if(level > 0 && !MagicDamage.isEntityImmune(DamageType.FROST, event.getEntityLiving()))
event.getEntityLiving().addPotionEffect(new PotionEffect(WizardryPotions.frost, level*150, 0)); event.getEntityLiving().addPotionEffect(new PotionEffect(WizardryPotions.frost, level * 150, 0));
} }
// Damage scaling // Damage scaling
if(event.getSource() != null && event.getSource() instanceof IElementalDamage){ if(event.getSource() != null && event.getSource() instanceof IElementalDamage){
if(event.getSource().getEntity() instanceof EntityPlayer){ if(event.getSource().getTrueSource() instanceof EntityPlayer){
event.setAmount((float)(event.getAmount() * Wizardry.settings.playerDamageScale)); event.setAmount((float)(event.getAmount() * Wizardry.settings.playerDamageScale));
}else{ }else{
event.setAmount((float)(event.getAmount() * Wizardry.settings.npcDamageScale)); event.setAmount((float)(event.getAmount() * Wizardry.settings.npcDamageScale));
@@ -296,31 +286,28 @@ public final class WizardryEventHandler {
EntityPlayer player = (EntityPlayer)event.getEntityLiving(); EntityPlayer player = (EntityPlayer)event.getEntityLiving();
if(player.worldObj.isRemote) hackilyFixContinuousSpellCasting(player); if(player.world.isRemote) hackilyFixContinuousSpellCasting(player);
// Mana flask crafting
if(player.openContainer instanceof ContainerWorkbench){ if(player.openContainer instanceof ContainerWorkbench){
craftingTableTick(player);
} IInventory craftMatrix = ((ContainerWorkbench)player.openContainer).craftMatrix;
ItemStack output = ((ContainerWorkbench)player.openContainer).craftResult.getStackInSlot(0);
if(player.openContainer instanceof ContainerPlayer){ processManaFlaskCrafting(craftMatrix, output);
}else if(player.openContainer instanceof ContainerPlayer){
IInventory craftMatrix = ((ContainerPlayer)player.openContainer).craftMatrix;
ItemStack output = ((ContainerPlayer)player.openContainer).craftResult.getStackInSlot(0);
// Unfortunately I have no choice but to call this method every tick when the player isn't using another // Unfortunately I have no choice but to call this method every tick when the player isn't using another
// inventory, since the only thing tracking whether the player is looking at their inventory is the GUI // inventory, since the only thing tracking whether the player is looking at their inventory is the GUI
// itself, which is client-side only. // itself, which is client-side only.
playerInventoryTick(player); processManaFlaskCrafting(craftMatrix, output);
}
testForArmourSet:{
for(ItemStack stack : player.getArmorInventoryList()){
if(stack == null || !(stack.getItem() instanceof ItemWizardArmour)){
break testForArmourSet;
}
}
player.addStat(WizardryAchievements.armour_set);
} }
} }
if(event.getEntityLiving().worldObj.isRemote){ if(event.getEntityLiving().world.isRemote){
// Client-side continuous spell casting for NPCs // Client-side continuous spell casting for NPCs
@@ -330,11 +317,11 @@ public final class WizardryEventHandler {
SpellModifiers modifiers = ((ISpellCaster)event.getEntity()).getModifiers(); SpellModifiers modifiers = ((ISpellCaster)event.getEntity()).getModifiers();
if(spell != null && spell != Spells.none){ if(spell != null && spell != Spells.none){
if(!MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Tick(event.getEntityLiving(), spell, modifiers, if(!MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Tick(event.getEntityLiving(), spell, modifiers,
SpellCastEvent.Source.NPC, 0))){ SpellCastEvent.Source.NPC, 0))){
spell.cast(event.getEntity().worldObj, (EntityLiving)event.getEntity(), EnumHand.MAIN_HAND, 0, spell.cast(event.getEntity().world, (EntityLiving)event.getEntity(), EnumHand.MAIN_HAND, 0,
// TODO: This implementation of modifiers relies on them being accessible client-side. // TODO: This implementation of modifiers relies on them being accessible client-side.
((EntityLiving)event.getEntity()).getAttackTarget(), modifiers); ((EntityLiving)event.getEntity()).getAttackTarget(), modifiers);
} }
@@ -346,14 +333,18 @@ public final class WizardryEventHandler {
@SubscribeEvent @SubscribeEvent
public static void onLivingDeathEvent(LivingDeathEvent event){ public static void onLivingDeathEvent(LivingDeathEvent event){
if(event.getSource().getEntity() instanceof EntityPlayer){ if(event.getSource().getTrueSource() instanceof EntityPlayer){
EntityPlayer player = (EntityPlayer)event.getSource().getEntity(); EntityPlayer player = (EntityPlayer)event.getSource().getTrueSource();
for(ItemStack stack : WizardryUtilities.getPrioritisedHotbarAndOffhand(player)){ for(ItemStack stack : WizardryUtilities.getPrioritisedHotbarAndOffhand(player)){
if(stack != null && stack.getItem() instanceof ItemWand && stack.isItemDamaged() && WandHelper.getUpgradeLevel(stack, WizardryItems.siphon_upgrade) > 0){ if(stack.getItem() instanceof ItemWand && stack.isItemDamaged()
int damage = stack.getItemDamage() - Constants.SIPHON_MANA_PER_LEVEL*WandHelper.getUpgradeLevel(stack, WizardryItems.siphon_upgrade) - player.worldObj.rand.nextInt(Constants.SIPHON_MANA_PER_LEVEL); && WandHelper.getUpgradeLevel(stack, WizardryItems.siphon_upgrade) > 0){
int damage = stack.getItemDamage()
- Constants.SIPHON_MANA_PER_LEVEL
* WandHelper.getUpgradeLevel(stack, WizardryItems.siphon_upgrade)
- player.world.rand.nextInt(Constants.SIPHON_MANA_PER_LEVEL);
if(damage < 0) damage = 0; if(damage < 0) damage = 0;
stack.setItemDamage(damage); stack.setItemDamage(damage);
break; break;
@@ -361,7 +352,7 @@ public final class WizardryEventHandler {
} }
if(event.getEntityLiving() == player && event.getSource() instanceof IElementalDamage){ if(event.getEntityLiving() == player && event.getSource() instanceof IElementalDamage){
player.addStat(WizardryAchievements.self_destruct); WizardryAdvancementTriggers.self_destruct.triggerFor(player);
} }
} }
} }
@@ -373,40 +364,35 @@ public final class WizardryEventHandler {
// Evil wizards drop spell books themselves // Evil wizards drop spell books themselves
if(event.getEntityLiving() instanceof IMob && !(event.getEntityLiving() instanceof EntityEvilWizard) if(event.getEntityLiving() instanceof IMob && !(event.getEntityLiving() instanceof EntityEvilWizard)
// TODO: Backport when you backport the new summoned creature system. // TODO: Backport when you backport the new summoned creature system.
&& !(event.getEntityLiving() instanceof ISummonedCreature) && event.getSource().getEntity() instanceof EntityPlayer && !(event.getEntityLiving() instanceof ISummonedCreature)
&& Wizardry.settings.spellBookDropChance > 0){ && event.getSource().getTrueSource() instanceof EntityPlayer && Wizardry.settings.spellBookDropChance > 0){
// This does exactly what the entity drop method does, but with a different random number so that the // This does exactly what the entity drop method does, but with a different random number so that the
// spell book doesn't always drop with other rare drops. // spell book doesn't always drop with other rare drops.
int rareDropNumber = event.getEntity().worldObj.rand.nextInt(200) - event.getLootingLevel(); int rareDropNumber = event.getEntity().world.rand.nextInt(200) - event.getLootingLevel();
if(rareDropNumber < Wizardry.settings.spellBookDropChance){ if(rareDropNumber < Wizardry.settings.spellBookDropChance){
// Drops a spell book // Drops a spell book
int id = WizardryUtilities.getStandardWeightedRandomSpellId(event.getEntity().worldObj.rand); int id = WizardryUtilities.getStandardWeightedRandomSpellId(event.getEntity().world.rand);
event.getDrops().add(new EntityItem(event.getEntityLiving().worldObj, event.getEntityLiving().posX, event.getEntityLiving().posY, event.getEntityLiving().posZ, event.getDrops()
.add(new EntityItem(event.getEntityLiving().world, event.getEntityLiving().posX,
event.getEntityLiving().posY, event.getEntityLiving().posZ,
new ItemStack(WizardryItems.spell_book, 1, id))); new ItemStack(WizardryItems.spell_book, 1, id)));
} }
} }
} }
@SubscribeEvent
public static void onItemPickupEvent(EntityItemPickupEvent event){
if(event.getItem().getEntityItem().getItem() == WizardryItems.magic_crystal){
event.getEntityPlayer().addStat(WizardryAchievements.crystal, 1);
}
}
// Private helper methods // Private helper methods
// ================================================================================================================ // ================================================================================================================
/** /**
* Detects inconsistencies between player.getActiveItemStack and the actual itemstack and forces them to be equal. * Detects inconsistencies between player.getActiveItemStack and the actual itemstack and forces them to be equal.
* Fixes issue #25. * Fixes issue #25.
*
* @param player * @param player
*/ */
private static void hackilyFixContinuousSpellCasting(EntityPlayer player){ private static void hackilyFixContinuousSpellCasting(EntityPlayer player){
if(player.isHandActive() && player.getHeldItem(player.getActiveHand()) != null if(player.isHandActive() && player.getHeldItem(player.getActiveHand()).getItem() instanceof ItemWand
&& player.getHeldItem(player.getActiveHand()).getItem() instanceof ItemWand
&& WandHelper.getCurrentSpell(player.getHeldItem(player.getActiveHand())).isContinuous){ && WandHelper.getCurrentSpell(player.getHeldItem(player.getActiveHand())).isContinuous){
if(player.getActiveItemStack() != player.getHeldItem(player.getActiveHand())){ if(player.getActiveItemStack() != player.getHeldItem(player.getActiveHand())){
player.setHeldItem(player.getActiveHand(), player.getActiveItemStack()); player.setHeldItem(player.getActiveHand(), player.getActiveItemStack());
@@ -414,97 +400,47 @@ public final class WizardryEventHandler {
} }
} }
private static void playerInventoryTick(EntityPlayer player){ private static void processManaFlaskCrafting(IInventory craftMatrix, ItemStack output){
// Charges wand using mana flask. It is here rather than in the crafting handler so the result displays // Charges wand using mana flask. It is here rather than in the crafting handler so the result displays
// the proper damage before it is actually crafted. // the proper damage before it is actually crafted.
boolean flag = false; boolean flag = false;
ItemStack wand = null; ItemStack wand = ItemStack.EMPTY;
ItemStack armour = null; ItemStack armour = ItemStack.EMPTY;
IInventory craftMatrix = ((ContainerPlayer)player.openContainer).craftMatrix;
ItemStack outputItem = ((ContainerPlayer)player.openContainer).craftResult.getStackInSlot(0);
for(int i = 0; i < craftMatrix.getSizeInventory(); i++){ for(int i = 0; i < craftMatrix.getSizeInventory(); i++){
if(craftMatrix.getStackInSlot(i) != null){
ItemStack itemstack = craftMatrix.getStackInSlot(i); ItemStack itemstack = craftMatrix.getStackInSlot(i);
if(itemstack.getItem() == WizardryItems.mana_flask){ if(itemstack.getItem() == WizardryItems.mana_flask){
flag = true; flag = true;
} }
if(itemstack.getItem() instanceof ItemWand){ if(itemstack.getItem() instanceof ItemWand){
wand = itemstack; wand = itemstack;
} }
if(itemstack.getItem() instanceof ItemWizardArmour){ if(itemstack.getItem() instanceof ItemWizardArmour){
armour = itemstack; armour = itemstack;
}
} }
} }
if(outputItem != null && outputItem.getItem() instanceof ItemWand && flag && wand != null){ if(output.getItem() instanceof ItemWand && flag && !wand.isEmpty()){
outputItem.setTagCompound((wand.getTagCompound())); output.setTagCompound((wand.getTagCompound()));
if(wand.getItemDamage()-Constants.MANA_PER_FLASK < 0){ if(wand.getItemDamage() - Constants.MANA_PER_FLASK < 0){
outputItem.setItemDamage(0); output.setItemDamage(0);
}else{ }else{
outputItem.setItemDamage(wand.getItemDamage()-Constants.MANA_PER_FLASK); output.setItemDamage(wand.getItemDamage() - Constants.MANA_PER_FLASK);
} }
} }
if(outputItem != null && outputItem.getItem() instanceof ItemWizardArmour && flag && armour != null){ if(output.getItem() instanceof ItemWizardArmour && flag && !armour.isEmpty()){
outputItem.setTagCompound((armour.getTagCompound())); output.setTagCompound((armour.getTagCompound()));
if(armour.getItemDamage()-Constants.MANA_PER_FLASK < 0){ if(armour.getItemDamage() - Constants.MANA_PER_FLASK < 0){
outputItem.setItemDamage(0); output.setItemDamage(0);
}else{ }else{
outputItem.setItemDamage(wand.getItemDamage()-Constants.MANA_PER_FLASK); output.setItemDamage(wand.getItemDamage() - Constants.MANA_PER_FLASK);
}
}
}
private static void craftingTableTick(EntityPlayer player) {
// Charges wand using mana flask
boolean flag = false;
ItemStack wand = null;
ItemStack armour = null;
IInventory craftMatrix = ((ContainerWorkbench)player.openContainer).craftMatrix;
ItemStack outputItem = ((ContainerWorkbench)player.openContainer).craftResult.getStackInSlot(0);
for (int i = 0; i < craftMatrix.getSizeInventory(); i++){
if(craftMatrix.getStackInSlot(i) != null){
ItemStack itemstack = craftMatrix.getStackInSlot(i);
if(itemstack.getItem() == WizardryItems.mana_flask){
flag = true;
}
if(itemstack.getItem() instanceof ItemWand){
wand = itemstack;
}
if(itemstack.getItem() instanceof ItemWizardArmour){
armour = itemstack;
}
}
}
if(outputItem != null && outputItem.getItem() instanceof ItemWand && flag && wand != null){
outputItem.setTagCompound((wand.getTagCompound()));
if(wand.getItemDamage()-Constants.MANA_PER_FLASK < 0){
outputItem.setItemDamage(0);
}else{
outputItem.setItemDamage(wand.getItemDamage()-Constants.MANA_PER_FLASK);
}
}
if(outputItem != null && outputItem.getItem() instanceof ItemWizardArmour && flag && armour != null){
outputItem.setTagCompound((armour.getTagCompound()));
if(armour.getItemDamage()-Constants.MANA_PER_FLASK < 0){
outputItem.setItemDamage(0);
}else{
outputItem.setItemDamage(wand.getItemDamage()-Constants.MANA_PER_FLASK);
} }
} }
} }
@@ -8,29 +8,23 @@ import net.minecraft.client.gui.GuiScreen;
import net.minecraftforge.fml.client.IModGuiFactory; import net.minecraftforge.fml.client.IModGuiFactory;
public class WizardryGuiFactory implements IModGuiFactory { public class WizardryGuiFactory implements IModGuiFactory {
@Override
public void initialize(Minecraft minecraftInstance)
{
}
@Override
public Class<? extends GuiScreen> mainConfigGuiClass()
{
return GuiConfigWizardry.class;
}
@Override
public Set<RuntimeOptionCategoryElement> runtimeGuiCategories()
{
return null;
}
@SuppressWarnings("deprecation") // It's a bit of Forge that hasn't been tidied up, but we have to implement it.
@Override @Override
public RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement element) public void initialize(Minecraft minecraftInstance){
{ }
return null;
} @Override
public Set<RuntimeOptionCategoryElement> runtimeGuiCategories(){
return null;
}
@Override
public boolean hasConfigGui(){
return true;
}
@Override
public GuiScreen createConfigGui(GuiScreen parentScreen){
return new GuiConfigWizardry(parentScreen);
}
} }
@@ -16,49 +16,43 @@ public class WizardryGuiHandler implements IGuiHandler {
/** Incrementable index for the gui ID */ /** Incrementable index for the gui ID */
private static int nextGuiId = 0; private static int nextGuiId = 0;
public static final int SPELL_BOOK = nextGuiId++; public static final int SPELL_BOOK = nextGuiId++;
public static final int ARCANE_WORKBENCH = nextGuiId++; public static final int ARCANE_WORKBENCH = nextGuiId++;
public static final int WIZARD_HANDBOOK = nextGuiId++; public static final int WIZARD_HANDBOOK = nextGuiId++;
public static final int PORTABLE_CRAFTING = nextGuiId++; public static final int PORTABLE_CRAFTING = nextGuiId++;
@Override @Override
public Object getServerGuiElement(int id, EntityPlayer player, World world, public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z){
int x, int y, int z) {
if(id == ARCANE_WORKBENCH){ if(id == ARCANE_WORKBENCH){
TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z)); TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z));
if(tileEntity instanceof TileEntityArcaneWorkbench){ if(tileEntity instanceof TileEntityArcaneWorkbench){
return new ContainerArcaneWorkbench(player.inventory, (TileEntityArcaneWorkbench) tileEntity); return new ContainerArcaneWorkbench(player.inventory, (TileEntityArcaneWorkbench)tileEntity);
} }
} }else if(id == PORTABLE_CRAFTING){
else if(id == PORTABLE_CRAFTING){
return new ContainerPortableWorkbench(player.inventory, world, new BlockPos(x, y, z)); return new ContainerPortableWorkbench(player.inventory, world, new BlockPos(x, y, z));
} }
return null; return null;
} }
@Override @Override
public Object getClientGuiElement(int id, EntityPlayer player, World world, public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z){
int x, int y, int z) {
if(id == ARCANE_WORKBENCH){ if(id == ARCANE_WORKBENCH){
TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z)); TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z));
if(tileEntity instanceof TileEntityArcaneWorkbench){ if(tileEntity instanceof TileEntityArcaneWorkbench){
return new electroblob.wizardry.client.GuiArcaneWorkbench(player.inventory, (TileEntityArcaneWorkbench) tileEntity); return new electroblob.wizardry.client.GuiArcaneWorkbench(player.inventory,
(TileEntityArcaneWorkbench)tileEntity);
} }
} }else if(id == WIZARD_HANDBOOK && (player.getHeldItemMainhand().getItem() instanceof ItemWizardHandbook
else if(id == WIZARD_HANDBOOK || player.getHeldItemOffhand().getItem() instanceof ItemWizardHandbook)){
&& ((player.getHeldItemMainhand() != null && player.getHeldItemMainhand().getItem() instanceof ItemWizardHandbook)
|| (player.getHeldItemOffhand() != null && player.getHeldItemOffhand().getItem() instanceof ItemWizardHandbook))){
return new electroblob.wizardry.client.GuiWizardHandbook(); return new electroblob.wizardry.client.GuiWizardHandbook();
} }else if(id == SPELL_BOOK){
else if(id == SPELL_BOOK){ if(player.getHeldItemMainhand().getItem() instanceof ItemSpellBook){
if(player.getHeldItemMainhand() != null && player.getHeldItemMainhand().getItem() instanceof ItemSpellBook){
return new electroblob.wizardry.client.GuiSpellBook(Spell.get(player.getHeldItemMainhand().getItemDamage())); return new electroblob.wizardry.client.GuiSpellBook(Spell.get(player.getHeldItemMainhand().getItemDamage()));
}else if(player.getHeldItemOffhand() != null && player.getHeldItemOffhand().getItem() instanceof ItemSpellBook){ }else if(player.getHeldItemOffhand().getItem() instanceof ItemSpellBook){
return new electroblob.wizardry.client.GuiSpellBook(Spell.get(player.getHeldItemOffhand().getItemDamage())); return new electroblob.wizardry.client.GuiSpellBook(Spell.get(player.getHeldItemOffhand().getItemDamage()));
} }
} }else if(id == PORTABLE_CRAFTING){
else if(id == PORTABLE_CRAFTING){
return new electroblob.wizardry.client.GuiPortableCrafting(player.inventory, world, new BlockPos(x, y, z)); return new electroblob.wizardry.client.GuiPortableCrafting(player.inventory, world, new BlockPos(x, y, z));
} }
return null; return null;
@@ -12,47 +12,48 @@ import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
public class WizardryKeyHandler { public class WizardryKeyHandler {
boolean NkeyPressed = false; boolean NkeyPressed = false;
boolean BkeyPressed = false; boolean BkeyPressed = false;
boolean NkeyAlreadyPressed = false; boolean NkeyAlreadyPressed = false;
boolean BkeyAlreadyPressed = false; boolean BkeyAlreadyPressed = false;
@SubscribeEvent @SubscribeEvent
public void onKeyInput(InputEvent.KeyInputEvent event) { public void onKeyInput(InputEvent.KeyInputEvent event){
// Key pressed // Key pressed
if(Keyboard.getEventKeyState()){ if(Keyboard.getEventKeyState()){
if(Wizardry.proxy instanceof ClientProxy){ if(Wizardry.proxy instanceof ClientProxy){
if(ClientProxy.NEXT_SPELL.isPressed() && Minecraft.getMinecraft().inGameHasFocus){ if(ClientProxy.NEXT_SPELL.isPressed() && Minecraft.getMinecraft().inGameHasFocus){
if(!NkeyPressed){ if(!NkeyPressed){
NkeyPressed = true; NkeyPressed = true;
}else{ }else{
NkeyAlreadyPressed = true; NkeyAlreadyPressed = true;
} }
if(!NkeyAlreadyPressed){ if(!NkeyAlreadyPressed){
// Packet building // Packet building
IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.NEXT_SPELL_KEY); IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.NEXT_SPELL_KEY);
WizardryPacketHandler.net.sendToServer(msg); WizardryPacketHandler.net.sendToServer(msg);
} }
} }
if(ClientProxy.PREVIOUS_SPELL.isPressed() && Minecraft.getMinecraft().inGameHasFocus){ if(ClientProxy.PREVIOUS_SPELL.isPressed() && Minecraft.getMinecraft().inGameHasFocus){
if(!BkeyPressed){ if(!BkeyPressed){
BkeyPressed = true; BkeyPressed = true;
}else{ }else{
BkeyAlreadyPressed = true; BkeyAlreadyPressed = true;
} }
if(!BkeyAlreadyPressed){ if(!BkeyAlreadyPressed){
// Packet building // Packet building
IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.PREVIOUS_SPELL_KEY); IMessage msg = new PacketControlInput.Message(
WizardryPacketHandler.net.sendToServer(msg); PacketControlInput.ControlType.PREVIOUS_SPELL_KEY);
} WizardryPacketHandler.net.sendToServer(msg);
} }
}
} }
} }
// Key released // Key released
else{ else{
if(NkeyPressed){ if(NkeyPressed){
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,61 @@
package electroblob.wizardry.advancement;
import electroblob.wizardry.Wizardry;
import net.minecraft.advancements.Advancement;
import net.minecraft.advancements.AdvancementManager;
import net.minecraft.advancements.AdvancementProgress;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.ResourceLocation;
/**
* This is a provisory class for the transition to 1.12
* It contains an enum with all the advancements of this mod
* and an helper to grant advancements on the server side only (like the command)
* @author Corail31
* @since Wizardry 4.1
*/
public class AdvancementHelper {
public enum EnumAdvancement {
crystal,
arcane_initiate,
apprentice,
master,
all_spells,
wizard_trade,
buy_master_spell,
freeze_blaze,
charge_creeper,
frankenstein,
special_upgrade,
craft_flask,
elemental,
armour_set,
legendary,
self_destruct,
pig_tornado,
jam_wizard,
slime_skeleton,
anger_wizard,
defeat_evil_wizard,
max_out_wand,
element_master,
identify_spell;
}
public static boolean grantAdvancement(EntityPlayer player, EnumAdvancement advancementName) {
if (player == null) { return false; }
if (player.world.isRemote) { return true; }
EntityPlayerMP player_mp = player.getServer().getPlayerList().getPlayerByUUID(player.getUniqueID());
AdvancementManager am = player_mp.getServerWorld().getAdvancementManager();
Advancement advancement = am.getAdvancement(new ResourceLocation(Wizardry.MODID, advancementName.name()));
if (advancement == null) { return false; }
AdvancementProgress advancementprogress = player_mp.getAdvancements().getProgress(advancement);
if (!advancementprogress.isDone()) {
for (String criteria : advancementprogress.getRemaningCriteria()) {
player_mp.getAdvancements().grantCriterion(advancement, criteria);
}
}
return true;
}
}
@@ -1,17 +1,13 @@
package electroblob.wizardry.block; package electroblob.wizardry.block;
import java.util.Random;
import electroblob.wizardry.Wizardry; import electroblob.wizardry.Wizardry;
import electroblob.wizardry.WizardryGuiHandler; import electroblob.wizardry.WizardryGuiHandler;
import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench; import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench;
import net.minecraft.block.BlockContainer; import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack; import net.minecraft.inventory.InventoryHelper;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
@@ -22,99 +18,63 @@ import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
public class BlockArcaneWorkbench extends BlockContainer { public class BlockArcaneWorkbench extends BlockContainer {
private static final AxisAlignedBB AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.75D, 1.0D); private static final AxisAlignedBB AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.75D, 1.0D);
public BlockArcaneWorkbench(){ public BlockArcaneWorkbench(){
super(Material.ROCK); super(Material.ROCK);
this.setLightLevel(0.8f); this.setLightLevel(0.8f);
} }
@Override
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){
return AABB;
}
@Override @Override
public TileEntity createNewTileEntity(World world, int metadata) { public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){
return AABB;
}
@Override
public TileEntity createNewTileEntity(World world, int metadata){
return new TileEntityArcaneWorkbench(); return new TileEntityArcaneWorkbench();
} }
@Override @Override
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) { public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos){
return false; return false;
} }
@Override @Override
public EnumBlockRenderType getRenderType(IBlockState state) { public EnumBlockRenderType getRenderType(IBlockState state){
return EnumBlockRenderType.MODEL; return EnumBlockRenderType.MODEL;
} }
@Override @Override
public boolean isOpaqueCube(IBlockState state) { public boolean isOpaqueCube(IBlockState state){
return false; return false;
} }
@Override @Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState block, EntityPlayer player, public boolean onBlockActivated(World world, BlockPos pos, IBlockState block, EntityPlayer player, EnumHand hand,
EnumHand hand, ItemStack heldItem, EnumFacing side, float hitX, float hitY, float hitZ){ EnumFacing side, float hitX, float hitY, float hitZ){
TileEntity tileEntity = world.getTileEntity(pos); TileEntity tileEntity = world.getTileEntity(pos);
if(tileEntity == null || player.isSneaking()){ if(tileEntity == null || player.isSneaking()){
return false; return false;
} }
player.openGui(Wizardry.instance, WizardryGuiHandler.ARCANE_WORKBENCH, world, pos.getX(), pos.getY(), pos.getZ()); player.openGui(Wizardry.instance, WizardryGuiHandler.ARCANE_WORKBENCH, world, pos.getX(), pos.getY(), pos.getZ());
return true; return true;
} }
@Override @Override
public void breakBlock(World world, BlockPos pos, IBlockState block) public void breakBlock(World world, BlockPos pos, IBlockState block){
{
Random random = new Random(); TileEntity tileentity = world.getTileEntity(pos);
TileEntityArcaneWorkbench tileentityarcaneworkbench = (TileEntityArcaneWorkbench)world.getTileEntity(pos);
if (tileentityarcaneworkbench != null) if(tileentity instanceof TileEntityArcaneWorkbench){
{ InventoryHelper.dropInventoryItems(world, pos, (TileEntityArcaneWorkbench)tileentity);
for (int j1 = 0; j1 < tileentityarcaneworkbench.getSizeInventory(); ++j1)
{
ItemStack itemstack = tileentityarcaneworkbench.getStackInSlot(j1);
if (itemstack != null)
{
float f = random.nextFloat() * 0.8F + 0.1F;
float f1 = random.nextFloat() * 0.8F + 0.1F;
EntityItem entityitem;
for (float f2 = random.nextFloat() * 0.8F + 0.1F; itemstack.stackSize > 0; world.spawnEntityInWorld(entityitem))
{
int k1 = random.nextInt(21) + 10;
if (k1 > itemstack.stackSize)
{
k1 = itemstack.stackSize;
}
itemstack.stackSize -= k1;
entityitem = new EntityItem(world, (double)((float)pos.getX() + f), (double)((float)pos.getY() + f1), (double)((float)pos.getZ() + f2), new ItemStack(itemstack.getItem(), k1, itemstack.getItemDamage()));
float f3 = 0.05F;
entityitem.motionX = (double)((float)random.nextGaussian() * f3);
entityitem.motionY = (double)((float)random.nextGaussian() * f3 + 0.2F);
entityitem.motionZ = (double)((float)random.nextGaussian() * f3);
if (itemstack.hasTagCompound())
{
entityitem.getEntityItem().setTagCompound(((NBTTagCompound)itemstack.getTagCompound().copy()));
}
}
}
}
//par1World.func_96440_m(par2, par3, par4, block);
} }
super.breakBlock(world, pos, block); super.breakBlock(world, pos, block);
} }
} }
@@ -22,31 +22,34 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
// Extending BlockBush allows me to remove nearly everything from this class. // Extending BlockBush allows me to remove nearly everything from this class.
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
public class BlockCrystalFlower extends BlockBush { public class BlockCrystalFlower extends BlockBush {
private static final AxisAlignedBB AABB = new AxisAlignedBB(0.5F - 0.2f, 0.0F, 0.5F - 0.2f, 0.5F + 0.2f, 0.2f * 3.0F, 0.5F + 0.2f);
public BlockCrystalFlower(Material par2Material) { private static final AxisAlignedBB AABB = new AxisAlignedBB(0.5F - 0.2f, 0.0F, 0.5F - 0.2f, 0.5F + 0.2f,
0.2f * 3.0F, 0.5F + 0.2f);
public BlockCrystalFlower(Material par2Material){
super(par2Material); super(par2Material);
this.setLightLevel(0.5f); this.setLightLevel(0.5f);
this.setTickRandomly(true); this.setTickRandomly(true);
this.setSoundType(SoundType.PLANT); this.setSoundType(SoundType.PLANT);
} }
@Override @Override
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){
{ return AABB;
return AABB; }
}
@Override @Override
public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random){ public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random){
if(world.isRemote && random.nextBoolean()){ if(world.isRemote && random.nextBoolean()){
Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, pos.getX()+random.nextDouble(), pos.getY()+random.nextDouble()/2+0.5, pos.getZ()+random.nextDouble(), 0d, 0.01, 0d, 20 + random.nextInt(10), 0.5f + (random.nextFloat()/2), 0.5f + (random.nextFloat()/2), 0.5f + (random.nextFloat()/2)); Wizardry.proxy.spawnParticle(WizardryParticleType.SPARKLE, world, pos.getX() + random.nextDouble(),
pos.getY() + random.nextDouble() / 2 + 0.5, pos.getZ() + random.nextDouble(), 0d, 0.01, 0d,
20 + random.nextInt(10), 0.5f + (random.nextFloat() / 2), 0.5f + (random.nextFloat() / 2),
0.5f + (random.nextFloat() / 2));
} }
} }
@Override @Override
public EnumPlantType getPlantType(IBlockAccess world, BlockPos pos) { public EnumPlantType getPlantType(IBlockAccess world, BlockPos pos){
return EnumPlantType.Plains; return EnumPlantType.Plains;
} }
@@ -56,11 +59,12 @@ public class BlockCrystalFlower extends BlockBush {
if(event.getBlock().getBlock() == Blocks.GRASS){ if(event.getBlock().getBlock() == Blocks.GRASS){
BlockPos pos = event.getPos().add(event.getWorld().rand.nextInt(8) - event.getWorld().rand.nextInt(8), BlockPos pos = event.getPos().add(event.getWorld().rand.nextInt(8) - event.getWorld().rand.nextInt(8),
event.getWorld().rand.nextInt(4) - event.getWorld().rand.nextInt(4), event.getWorld().rand.nextInt(4) - event.getWorld().rand.nextInt(4),
event.getWorld().rand.nextInt(8) - event.getWorld().rand.nextInt(8)); event.getWorld().rand.nextInt(8) - event.getWorld().rand.nextInt(8));
if (event.getWorld().isAirBlock(new BlockPos(pos)) && (!event.getWorld().provider.getHasNoSky() || pos.getY() < 127) && WizardryBlocks.crystal_flower.canPlaceBlockAt(event.getWorld(), pos)) if(event.getWorld().isAirBlock(new BlockPos(pos))
{ && (!event.getWorld().provider.isNether() || pos.getY() < 127)
&& WizardryBlocks.crystal_flower.canPlaceBlockAt(event.getWorld(), pos)){
event.getWorld().setBlockState(pos, WizardryBlocks.crystal_flower.getDefaultState(), 2); event.getWorld().setBlockState(pos, WizardryBlocks.crystal_flower.getDefaultState(), 2);
} }
} }
@@ -8,28 +8,50 @@ import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public class BlockCrystalOre extends Block { public class BlockCrystalOre extends Block {
public BlockCrystalOre(Material material) { public BlockCrystalOre(Material material){
super(material); super(material);
this.setSoundType(SoundType.STONE); this.setSoundType(SoundType.STONE);
setResistance(5.0F); setResistance(5.0F);
setHarvestLevel("pickaxe", 2); setHarvestLevel("pickaxe", 2);
} }
@Override @Override
public int quantityDropped(IBlockState state, int fortune, Random random) public int quantityDropped(IBlockState state, int fortune, Random random){
{ // This now works the same way as vanilla ores
if(fortune > 0){ if(fortune > 0){
return random.nextInt(2) + 1 + random.nextInt(fortune);
int i = random.nextInt(fortune + 2) - 1;
if(i < 0) i = 0;
return (random.nextInt(3) + 1) * (i + 1);
}else{ }else{
return random.nextInt(2) + 1; return random.nextInt(3) + 1;
} }
} }
@Override @Override
public Item getItemDropped(IBlockState state, Random random, int fortune){ public Item getItemDropped(IBlockState state, Random random, int fortune){
return WizardryItems.magic_crystal; return WizardryItems.magic_crystal;
} }
@Override
public int getExpDrop(IBlockState state, IBlockAccess world, BlockPos pos, int fortune){
Random rand = world instanceof World ? ((World)world).rand : RANDOM;
if(this.getItemDropped(state, rand, fortune) != Item.getItemFromBlock(this)){
return MathHelper.getInt(rand, 1, 4);
}
return 0;
}
} }
@@ -12,47 +12,48 @@ import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
public class BlockMagicLight extends BlockContainer { public class BlockMagicLight extends BlockContainer {
private static final AxisAlignedBB AABB = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
public BlockMagicLight(Material par2Material) { private static final AxisAlignedBB AABB = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
public BlockMagicLight(Material par2Material){
super(par2Material); super(par2Material);
this.setLightLevel(1.0f); this.setLightLevel(1.0f);
} }
@Override @Override
public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, World worldIn, BlockPos pos){ public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, IBlockAccess worldIn, BlockPos pos){
// The other two bounding box methods in Block aren't nullable, so this is the only one that can return NULL_AABB. // The other two bounding box methods in Block aren't nullable, so this is the
// only one that can return NULL_AABB.
return NULL_AABB; return NULL_AABB;
} }
@Override @Override
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){ public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){
return AABB; return AABB;
} }
@Override @Override
public boolean isCollidable(){ public boolean isCollidable(){
return false; return false;
} }
@Override @Override
public TileEntity createNewTileEntity(World world, int metadata) { public TileEntity createNewTileEntity(World world, int metadata){
return new TileEntityMagicLight(600); return new TileEntityMagicLight(600);
} }
@Override @Override
public boolean isOpaqueCube(IBlockState state) { public boolean isOpaqueCube(IBlockState state){
return false; return false;
} }
@Override @Override
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) { public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos){
return false; return false;
} }
@Override @Override
public EnumBlockRenderType getRenderType(IBlockState state) { public EnumBlockRenderType getRenderType(IBlockState state){
return EnumBlockRenderType.ENTITYBLOCK_ANIMATED; return EnumBlockRenderType.ENTITYBLOCK_ANIMATED;
} }
} }
@@ -24,86 +24,88 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess; import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
// TODO: Apparently you shouldn't extend BlockContainer. I feel like BlockArcaneWorkbench should, but what about the rest? // TODO: Apparently you shouldn't extend BlockContainer. I feel like BlockArcaneWorkbench should, but what about the rest?
public class BlockSnare extends BlockContainer { public class BlockSnare extends BlockContainer {
private static final AxisAlignedBB AABB = new AxisAlignedBB(0.0f, 0.0f, 0.0f, 1.0f, 0.0625f, 1.0f); private static final AxisAlignedBB AABB = new AxisAlignedBB(0.0f, 0.0f, 0.0f, 1.0f, 0.0625f, 1.0f);
public BlockSnare(Material par2Material){ public BlockSnare(Material material){
super(par2Material); super(material);
this.setSoundType(SoundType.PLANT); this.setSoundType(SoundType.PLANT);
} }
@Override @Override
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){ public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){
return AABB; return AABB;
} }
@Override @Override
public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, World worldIn, BlockPos pos){ public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos){
return NULL_AABB; return NULL_AABB;
} }
@Override @Override
public boolean hasTileEntity(IBlockState state){ public boolean hasTileEntity(IBlockState state){
return true; return true;
} }
@Override @Override
public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity) { public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity){
if(!world.isRemote && entity instanceof EntityLivingBase){ if(!world.isRemote && entity instanceof EntityLivingBase){
if(world.getTileEntity(pos) instanceof TileEntityPlayerSave){ if(world.getTileEntity(pos) instanceof TileEntityPlayerSave){
TileEntityPlayerSave tileentity = (TileEntityPlayerSave)world.getTileEntity(pos); TileEntityPlayerSave tileentity = (TileEntityPlayerSave)world.getTileEntity(pos);
if(WizardryUtilities.isValidTarget(tileentity.getCaster(), entity)){ if(WizardryUtilities.isValidTarget(tileentity.getCaster(), entity)){
((EntityLivingBase)entity).attackEntityFrom(MagicDamage.causeDirectMagicDamage(tileentity.getCaster(), DamageType.MAGIC), 6); ((EntityLivingBase)entity).attackEntityFrom(
MagicDamage.causeDirectMagicDamage(tileentity.getCaster(), DamageType.MAGIC), 6);
((EntityLivingBase)entity).addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, 100, 2)); ((EntityLivingBase)entity).addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, 100, 2));
world.destroyBlock(pos, false); world.destroyBlock(pos, false);
} }
} }
} }
} }
// The similarly named onNeighborChange method does NOT do the same thing. // The similarly named onNeighborChange method does NOT do the same thing.
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn){ public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos fromPos){
super.neighborChanged(state, world, pos, blockIn); super.neighborChanged(state, world, pos, block, fromPos);
if(!world.isSideSolid(pos.down(), EnumFacing.UP, false)){ if(!world.isSideSolid(pos.down(), EnumFacing.UP, false)){
world.setBlockToAir(pos); world.setBlockToAir(pos);
} }
} }
@Override @Override
public BlockRenderLayer getBlockLayer(){ public BlockRenderLayer getBlockLayer(){
return BlockRenderLayer.CUTOUT; return BlockRenderLayer.CUTOUT;
} }
@Override @Override
public EnumBlockRenderType getRenderType(IBlockState state){ public EnumBlockRenderType getRenderType(IBlockState state){
return EnumBlockRenderType.MODEL; return EnumBlockRenderType.MODEL;
} }
@Override @Override
public boolean isOpaqueCube(IBlockState state){ public boolean isOpaqueCube(IBlockState state){
return false; return false;
} }
@Override @Override
public boolean isFullCube(IBlockState state){ public boolean isFullCube(IBlockState state){
return false; return false;
} }
@Override @Override
public Item getItemDropped(IBlockState state, Random rand, int fortune){ public Item getItemDropped(IBlockState state, Random rand, int fortune){
return null; return null;
} }
@Override @Override
public TileEntity createNewTileEntity(World world, int metadata) { public TileEntity createNewTileEntity(World world, int metadata){
return new TileEntityPlayerSave(); return new TileEntityPlayerSave();
} }
@@ -29,79 +29,87 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
public class BlockSpectral extends BlockContainer { public class BlockSpectral extends BlockContainer {
public BlockSpectral(Material material) { public BlockSpectral(Material material){
super(material); super(material);
this.setSoundType(SoundType.GLASS); this.setSoundType(SoundType.GLASS);
} }
// Replaces getRenderBlockPass // Replaces getRenderBlockPass
@Override @Override
public BlockRenderLayer getBlockLayer(){ public BlockRenderLayer getBlockLayer(){
return BlockRenderLayer.TRANSLUCENT; return BlockRenderLayer.TRANSLUCENT;
} }
@Override @Override
public EnumBlockRenderType getRenderType(IBlockState state) { public EnumBlockRenderType getRenderType(IBlockState state){
return EnumBlockRenderType.MODEL; return EnumBlockRenderType.MODEL;
} }
// Apparently it's OK to override this, despite it being deprecated. More importantly, it being deprecated is not // Apparently it's OK to override this, despite it being deprecated. More
// Forge's doing, rather it is Mojang themselves misusing the @Deprecated annotation to mean 'internal, don't call'. // importantly, it being deprecated is not
// Forge's doing, rather it is Mojang themselves misusing the @Deprecated
// annotation to mean 'internal, don't call'.
@Override @Override
public boolean isOpaqueCube(IBlockState state){ public boolean isOpaqueCube(IBlockState state){
return false;
}
@Override
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) {
return false; return false;
} }
@Override @Override
public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random) { public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos){
// Middle of block return false;
Wizardry.proxy.spawnParticle(WizardryParticleType.DUST, world, pos.getX()+random.nextDouble(), pos.getY()+random.nextDouble(), pos.getZ()+random.nextDouble(), 0, 0, 0, (int)(16.0D / (Math.random() * 0.8D + 0.2D)),
0.4f + random.nextFloat()*0.2f, 0.6f + random.nextFloat()*0.4f, 0.6f + random.nextFloat()*0.4f);
// Top surface
Wizardry.proxy.spawnParticle(WizardryParticleType.DUST, world, pos.getX()+random.nextDouble(), pos.getY()+1, pos.getZ()+random.nextDouble(), 0, 0, 0, (int)(16.0D / (Math.random() * 0.8D + 0.2D)),
0.4f + random.nextFloat()*0.2f, 0.6f + random.nextFloat()*0.4f, 0.6f + random.nextFloat()*0.4f);
Wizardry.proxy.spawnParticle(WizardryParticleType.DUST, world, pos.getX()+random.nextDouble(), pos.getY()+1, pos.getZ()+random.nextDouble(), 0, 0, 0, (int)(16.0D / (Math.random() * 0.8D + 0.2D)),
0.4f + random.nextFloat()*0.2f, 0.6f + random.nextFloat()*0.4f, 0.6f + random.nextFloat()*0.4f);
} }
// Overriden to make the block always look full brightness despite not emitting full light.
@Override @Override
public int getPackedLightmapCoords(IBlockState state, IBlockAccess source, BlockPos pos) { public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random){
// Middle of block
Wizardry.proxy.spawnParticle(WizardryParticleType.DUST, world, pos.getX() + random.nextDouble(),
pos.getY() + random.nextDouble(), pos.getZ() + random.nextDouble(), 0, 0, 0,
(int)(16.0D / (Math.random() * 0.8D + 0.2D)), 0.4f + random.nextFloat() * 0.2f,
0.6f + random.nextFloat() * 0.4f, 0.6f + random.nextFloat() * 0.4f);
// Top surface
Wizardry.proxy.spawnParticle(WizardryParticleType.DUST, world, pos.getX() + random.nextDouble(), pos.getY() + 1,
pos.getZ() + random.nextDouble(), 0, 0, 0, (int)(16.0D / (Math.random() * 0.8D + 0.2D)),
0.4f + random.nextFloat() * 0.2f, 0.6f + random.nextFloat() * 0.4f, 0.6f + random.nextFloat() * 0.4f);
Wizardry.proxy.spawnParticle(WizardryParticleType.DUST, world, pos.getX() + random.nextDouble(), pos.getY() + 1,
pos.getZ() + random.nextDouble(), 0, 0, 0, (int)(16.0D / (Math.random() * 0.8D + 0.2D)),
0.4f + random.nextFloat() * 0.2f, 0.6f + random.nextFloat() * 0.4f, 0.6f + random.nextFloat() * 0.4f);
}
// Overriden to make the block always look full brightness despite not emitting
// full light.
@Override
public int getPackedLightmapCoords(IBlockState state, IBlockAccess source, BlockPos pos){
return 15; return 15;
} }
@Override @Override
public TileEntity createNewTileEntity(World world, int metadata) { public TileEntity createNewTileEntity(World world, int metadata){
return new TileEntityTimer(1200); return new TileEntityTimer(1200);
} }
@Override @Override
public int quantityDropped(Random par1Random){ public int quantityDropped(Random par1Random){
return 0; return 0;
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@Override @Override
public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side){ public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos,
EnumFacing side){
IBlockState iblockstate = blockAccess.getBlockState(pos.offset(side));
Block block = iblockstate.getBlock();
return block == this ? false : super.shouldSideBeRendered(blockState, blockAccess, pos, side); IBlockState iblockstate = blockAccess.getBlockState(pos.offset(side));
} Block block = iblockstate.getBlock();
@SubscribeEvent return block == this ? false : super.shouldSideBeRendered(blockState, blockAccess, pos, side);
}
@SubscribeEvent
public static void onBlockPlaceEvent(BlockEvent.PlaceEvent event){ public static void onBlockPlaceEvent(BlockEvent.PlaceEvent event){
// Spectral blocks cannot be built on // Spectral blocks cannot be built on
if(event.getPlacedAgainst() == WizardryBlocks.spectral_block){ if(event.getPlacedAgainst() == WizardryBlocks.spectral_block){
event.setCanceled(true); event.setCanceled(true);
} }
} }
} }
@@ -24,15 +24,15 @@ public class BlockStatue extends BlockContainer {
private boolean isIce; private boolean isIce;
public BlockStatue(Material material) { public BlockStatue(Material material){
super(material); super(material);
this.isIce = material == Material.ICE; this.isIce = material == Material.ICE;
if(this.isIce){ if(this.isIce){
this.slipperiness = 0.98F; this.setDefaultSlipperiness(0.98f);
this.setSoundType(SoundType.GLASS); this.setSoundType(SoundType.GLASS);
} }
} }
@Override @Override
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos){ public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos){
// Not a good idea to call getBlockBoundsMinX() or whatever from in here, since this method changes those! // Not a good idea to call getBlockBoundsMinX() or whatever from in here, since this method changes those!
@@ -43,49 +43,71 @@ public class BlockStatue extends BlockContainer {
TileEntityStatue statue = (TileEntityStatue)world.getTileEntity(pos); TileEntityStatue statue = (TileEntityStatue)world.getTileEntity(pos);
if(statue.creature != null){ if(statue.creature != null){
// Block bounds are set to match the width and height of the entity, clamped to within 1 block. // Block bounds are set to match the width and height of the entity, clamped to within 1 block.
return new AxisAlignedBB((float)Math.max(0.5 - statue.creature.width/2, 0), 0, return new AxisAlignedBB((float)Math.max(0.5 - statue.creature.width / 2, 0), 0,
(float)Math.max(0.5 - statue.creature.width/2, 0), (float)Math.max(0.5 - statue.creature.width / 2, 0),
(float)Math.min(0.5 + statue.creature.width/2, 1), (float)Math.min(0.5 + statue.creature.width / 2, 1),
// This checks if the block is the top one and if so reduces its height so the top lines up with // This checks if the block is the top one and if so reduces its height so the top lines up
// with
// the top of the entity model. // the top of the entity model.
statue.position == statue.parts ? (float)Math.min(statue.creature.height - statue.parts + 1, 1) : 1, statue.position == statue.parts
(float)Math.min(0.5 + statue.creature.width/2, 1)); ? (float)Math.min(statue.creature.height - statue.parts + 1, 1)
: 1,
(float)Math.min(0.5 + statue.creature.width / 2, 1));
} }
} }
} }
return FULL_BLOCK_AABB; return FULL_BLOCK_AABB;
} }
// getCollisionBoundingBox eventually calls getBoundingBox anyway, and since I want the collision box and the block // getCollisionBoundingBox eventually calls getBoundingBox anyway, and since I want the collision box and the block
// outline to be the same here, I've removed that getCollisionBoundingBox entirely. // outline to be the same here, I've removed that getCollisionBoundingBox entirely.
// The number of these methods is quite simply ridiculous. This one seems to be for placement logic and block // The number of these methods is quite simply ridiculous. This one seems to be for placement logic and block
// connections (fences, glass panes, etc.)... // connections (fences, glass panes, etc.)...
@Override public boolean isFullCube(IBlockState state) { return false; } @Override
public boolean isFullCube(IBlockState state){
return false;
}
// ...this one isn't used much but has something to do with redstone... // ...this one isn't used much but has something to do with redstone...
@Override public boolean isBlockNormalCube(IBlockState state) { return false; } @Override
public boolean isBlockNormalCube(IBlockState state){
return false;
}
// ... this one is for most other game logic... // ... this one is for most other game logic...
@Override public boolean isNormalCube(IBlockState state) { return false; } @Override
public boolean isNormalCube(IBlockState state){
return false;
}
// Forge version of the above method. I still need to override both though because vanilla uses the other one. // Forge version of the above method. I still need to override both though because vanilla uses the other one.
@Override public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) { return false; } @Override
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos){
return false;
}
// ... and this one is for rendering. // ... and this one is for rendering.
@Override public boolean isOpaqueCube(IBlockState state){ return false; } @Override
public boolean isOpaqueCube(IBlockState state){
return false;
}
@Override @Override
public BlockRenderLayer getBlockLayer(){ public BlockRenderLayer getBlockLayer(){
return this.isIce ? BlockRenderLayer.TRANSLUCENT : BlockRenderLayer.SOLID; return this.isIce ? BlockRenderLayer.TRANSLUCENT : BlockRenderLayer.SOLID;
} }
@Override @Override
public EnumBlockRenderType getRenderType(IBlockState state){ public EnumBlockRenderType getRenderType(IBlockState state){
return this.isIce ? EnumBlockRenderType.MODEL : EnumBlockRenderType.ENTITYBLOCK_ANIMATED; return this.isIce ? EnumBlockRenderType.MODEL : EnumBlockRenderType.ENTITYBLOCK_ANIMATED;
} }
@Override @Override
public TileEntity createNewTileEntity(World world, int metadata) { public TileEntity createNewTileEntity(World world, int metadata){
return new TileEntityStatue(this.isIce); return new TileEntityStatue(this.isIce);
} }
@@ -93,14 +115,14 @@ public class BlockStatue extends BlockContainer {
public int quantityDropped(Random random){ public int quantityDropped(Random random){
return 0; return 0;
} }
@Override @Override
public void breakBlock(World world, BlockPos pos, IBlockState state){ public void breakBlock(World world, BlockPos pos, IBlockState state){
if(!world.isRemote){ if(!world.isRemote){
TileEntityStatue tileentity = (TileEntityStatue)world.getTileEntity(pos); TileEntityStatue tileentity = (TileEntityStatue)world.getTileEntity(pos);
if(tileentity != null){ if(tileentity != null){
if(tileentity.parts == 2){ if(tileentity.parts == 2){
if(tileentity.position == 2){ if(tileentity.position == 2){
@@ -126,21 +148,22 @@ public class BlockStatue extends BlockContainer {
if(tileentity != null && tileentity.position == 1 && tileentity.creature != null){ if(tileentity != null && tileentity.position == 1 && tileentity.creature != null){
tileentity.creature.getEntityData().removeTag(Petrify.NBT_KEY); tileentity.creature.getEntityData().removeTag(Petrify.NBT_KEY);
tileentity.creature.isDead = false; tileentity.creature.isDead = false;
world.spawnEntityInWorld(tileentity.creature); world.spawnEntity(tileentity.creature);
} }
} }
super.breakBlock(world, pos, state); super.breakBlock(world, pos, state);
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
@Override @Override
public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side){ public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos,
EnumFacing side){
IBlockState iblockstate = blockAccess.getBlockState(pos.offset(side));
Block block = iblockstate.getBlock();
return this.isIce && block == this ? false : super.shouldSideBeRendered(blockState, blockAccess, pos, side); IBlockState iblockstate = blockAccess.getBlockState(pos.offset(side));
} Block block = iblockstate.getBlock();
return this.isIce && block == this ? false : super.shouldSideBeRendered(blockState, blockAccess, pos, side);
}
} }
@@ -3,6 +3,7 @@ package electroblob.wizardry.block;
import java.util.Random; import java.util.Random;
import electroblob.wizardry.WizardData; import electroblob.wizardry.WizardData;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.item.ItemWand; import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.registry.Spells; import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardryBlocks; import electroblob.wizardry.registry.WizardryBlocks;
@@ -20,96 +21,122 @@ import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
public class BlockTransportationStone extends Block { public class BlockTransportationStone extends Block {
private static final AxisAlignedBB AABB = new AxisAlignedBB(0.0625f*5, 0, 0.0625f*5, 0.0625f*11, 0.0625f*6, 0.0625f*11); private static final AxisAlignedBB AABB = new AxisAlignedBB(0.0625f * 5, 0, 0.0625f * 5, 0.0625f * 11, 0.0625f * 6,
0.0625f * 11);
public BlockTransportationStone(Material material){ public BlockTransportationStone(Material material){
super(material); super(material);
this.setTickRandomly(true); this.setTickRandomly(true);
} }
@Override @Override
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){ public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){
return AABB; return AABB;
} }
// The number of these methods is quite simply ridiculous. This one seems to be for placement logic and block // The number of these methods is quite simply ridiculous. This one seems to be for placement logic and block
// connections (fences, glass panes, etc.)... // connections (fences, glass panes, etc.)...
@Override public boolean isFullCube(IBlockState state) { return false; }
// ...this one isn't used much but has something to do with redstone...
@Override public boolean isBlockNormalCube(IBlockState state) { return false; }
// ... this one is for most other game logic...
@Override public boolean isNormalCube(IBlockState state) { return false; }
// Forge version of the above method. I still need to override both though because vanilla uses the other one.
@Override public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos) { return false; }
// ... and this one is for rendering.
@Override public boolean isOpaqueCube(IBlockState state){ return false; }
@Override @Override
public void onNeighborChange(IBlockAccess world, BlockPos pos, BlockPos neighbor){ public boolean isFullCube(IBlockState state){
return false;
super.onNeighborChange(world, pos, neighbor);
if(!world.isSideSolid(pos.down(), EnumFacing.UP, false) && world instanceof World){
this.dropBlockAsItem((World) world, pos, world.getBlockState(pos), 0);
((World)world).setBlockToAir(pos);
}
} }
@Override
public void updateTick(World world, BlockPos pos, IBlockState state, Random random) {
if(!world.isSideSolid(pos.down(), EnumFacing.UP)){ // ...this one isn't used much but has something to do with redstone...
this.dropBlockAsItem(world, pos, world.getBlockState(pos), 0); @Override
world.setBlockToAir(pos); public boolean isBlockNormalCube(IBlockState state){
} return false;
} }
// ... this one is for most other game logic...
@Override
public boolean isNormalCube(IBlockState state){
return false;
}
// Forge version of the above method. I still need to override both though because vanilla uses the other one.
@Override
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos){
return false;
}
// ... and this one is for rendering.
@Override
public boolean isOpaqueCube(IBlockState state){
return false;
}
@SuppressWarnings("deprecation")
@Override
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos fromPos){
super.neighborChanged(state, world, pos, block, fromPos);
if(!world.isSideSolid(pos.down(), EnumFacing.UP, false)){
this.dropBlockAsItem(world, pos, world.getBlockState(pos), 0);
world.setBlockToAir(pos);
}
}
@Override
public void updateTick(World world, BlockPos pos, IBlockState state, Random random){
if(!world.isSideSolid(pos.down(), EnumFacing.UP)){
this.dropBlockAsItem(world, pos, world.getBlockState(pos), 0);
world.setBlockToAir(pos);
}
}
@Override @Override
public boolean canPlaceBlockAt(World world, BlockPos pos){ public boolean canPlaceBlockAt(World world, BlockPos pos){
return super.canPlaceBlockAt(world, pos) && world.isSideSolid(pos.down(), EnumFacing.UP); return super.canPlaceBlockAt(world, pos) && world.isSideSolid(pos.down(), EnumFacing.UP);
} }
@Override @Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand,
EnumHand hand, ItemStack stack, EnumFacing side, float hitX, float hitY, float hitZ) { EnumFacing side, float hitX, float hitY, float hitZ){
if(stack != null && stack.getItem() instanceof ItemWand){ ItemStack stack = player.getHeldItem(hand);
if(stack.getItem() instanceof ItemWand){
if(WizardData.get(player) != null){ if(WizardData.get(player) != null){
WizardData data = WizardData.get(player); WizardData data = WizardData.get(player);
for(int x=-1; x<=1; x++){ for(int x = -1; x <= 1; x++){
for(int z=-1; z<=1; z++){ for(int z = -1; z <= 1; z++){
BlockPos pos1 = pos.add(x, 0, z); BlockPos pos1 = pos.add(x, 0, z);
if(testForCircle(world, pos1)){ if(testForCircle(world, pos1)){
data.setStoneCircleLocation(pos1, world.provider.getDimension()); data.setStoneCircleLocation(pos1, world.provider.getDimension());
if(!world.isRemote) player.addChatMessage(new TextComponentTranslation("tile.wizardry:transportation_stone.confirm", Spells.transportation.getNameForTranslationFormatted())); if(!world.isRemote) player.sendMessage(
new TextComponentTranslation("tile." + Wizardry.MODID + ":transportation_stone.confirm",
Spells.transportation.getNameForTranslationFormatted()));
return true; return true;
} }
} }
} }
if(!world.isRemote) player.addChatMessage(new TextComponentTranslation("tile.wizardry:transportation_stone.invalid")); if(!world.isRemote)
player.sendMessage(new TextComponentTranslation("tile." + Wizardry.MODID + ":transportation_stone.invalid"));
return true; return true;
} }
} }
return false; return false;
} }
/** Returns whether the specified location is surrounded by a complete cicle of 8 transportation stones. */ /** Returns whether the specified location is surrounded by a complete cicle of 8 transportation stones. */
public static boolean testForCircle(World world, BlockPos pos){ public static boolean testForCircle(World world, BlockPos pos){
if(world.getBlockState(pos).getMaterial().blocksMovement()) return false; if(world.getBlockState(pos).getMaterial().blocksMovement()) return false;
for(int x=-1; x<=1; x++){ for(int x = -1; x <= 1; x++){
for(int z=-1; z<=1; z++){ for(int z = -1; z <= 1; z++){
if(world.getBlockState(pos.add(x, 0, z)).getBlock() != WizardryBlocks.transportation_stone){ if(world.getBlockState(pos.add(x, 0, z)).getBlock() != WizardryBlocks.transportation_stone){
if(x != 0 || z != 0) return false; if(x != 0 || z != 0) return false;
} }
} }
} }
return true; return true;
} }
} }
@@ -12,6 +12,7 @@ import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
@@ -19,52 +20,48 @@ import net.minecraftforge.fml.relauncher.SideOnly;
// For future reference - extend BlockContainer whenever possible because it has methods for removing tile entities on block break. // For future reference - extend BlockContainer whenever possible because it has methods for removing tile entities on block break.
public class BlockVanishingCobweb extends BlockContainer { public class BlockVanishingCobweb extends BlockContainer {
public BlockVanishingCobweb(Material material) { public BlockVanishingCobweb(Material material){
super(material); super(material);
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public BlockRenderLayer getBlockLayer() public BlockRenderLayer getBlockLayer(){
{ return BlockRenderLayer.CUTOUT;
return BlockRenderLayer.CUTOUT; }
}
@Override @Override
public EnumBlockRenderType getRenderType(IBlockState state){ public EnumBlockRenderType getRenderType(IBlockState state){
return EnumBlockRenderType.MODEL; return EnumBlockRenderType.MODEL;
} }
@Override
public boolean isOpaqueCube(IBlockState state)
{
return false;
}
@Override @Override
public AxisAlignedBB getCollisionBoundingBox(IBlockState blockState, World worldIn, BlockPos pos) public boolean isOpaqueCube(IBlockState state){
{ return false;
return NULL_AABB; }
}
@Override @Override
public boolean isFullCube(IBlockState state) public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos){
{ return NULL_AABB;
return false; }
}
@Override
@Override public boolean isFullCube(IBlockState state){
public TileEntity createNewTileEntity(World world, int metadata) { return false;
}
@Override
public TileEntity createNewTileEntity(World world, int metadata){
return new TileEntityTimer(400); return new TileEntityTimer(400);
} }
@Override @Override
public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity){ public void onEntityCollidedWithBlock(World world, BlockPos pos, IBlockState state, Entity entity){
entity.setInWeb(); entity.setInWeb();
} }
@Override @Override
public int quantityDropped(Random par1Random){ public int quantityDropped(Random par1Random){
return 0; return 0;
} }
} }
@@ -145,6 +145,7 @@ import net.minecraftforge.fml.client.registry.RenderingRegistry;
/** /**
* The client proxy for wizardry. * The client proxy for wizardry.
*
* @author Electroblob * @author Electroblob
* @since Wizardry 1.0 * @since Wizardry 1.0
*/ */
@@ -152,129 +153,130 @@ public class ClientProxy extends CommonProxy {
/** Static instance of the mixed font renderer */ /** Static instance of the mixed font renderer */
public static MixedFontRenderer mixedFontRenderer; public static MixedFontRenderer mixedFontRenderer;
// Key Bindings // Key Bindings
public static final KeyBinding NEXT_SPELL = new KeyBinding("key.wizardry:next_spell", Keyboard.KEY_N, "key.categories.wizardry"); public static final KeyBinding NEXT_SPELL = new KeyBinding("key." + Wizardry.MODID + ".next_spell", Keyboard.KEY_N, "key.categories." + Wizardry.MODID);
public static final KeyBinding PREVIOUS_SPELL = new KeyBinding("key.wizardry:previous_spell", Keyboard.KEY_B, "key.categories.wizardry"); public static final KeyBinding PREVIOUS_SPELL = new KeyBinding("key." + Wizardry.MODID + ".previous_spell", Keyboard.KEY_B, "key.categories." + Wizardry.MODID);
// Armour Model // Armour Model
public static final ModelBiped WIZARD_ARMOUR_MODEL = new ModelWizardArmour(0.75f); public static final ModelBiped WIZARD_ARMOUR_MODEL = new ModelWizardArmour(0.75f);
// SECTION Registry // SECTION Registry
// =============================================================================================================== // ===============================================================================================================
@Override @Override
public ModelBiped getWizardArmourModel(){ public ModelBiped getWizardArmourModel(){
return WIZARD_ARMOUR_MODEL; return WIZARD_ARMOUR_MODEL;
} }
@Override @Override
public void registerKeyBindings(){ public void registerKeyBindings(){
ClientRegistry.registerKeyBinding(NEXT_SPELL); ClientRegistry.registerKeyBinding(NEXT_SPELL);
ClientRegistry.registerKeyBinding(PREVIOUS_SPELL); ClientRegistry.registerKeyBinding(PREVIOUS_SPELL);
} }
@Override @Override
public void registerSpellHUD(){ public void registerSpellHUD(){
MinecraftForge.EVENT_BUS.register(new GuiSpellDisplay(Minecraft.getMinecraft())); MinecraftForge.EVENT_BUS.register(new GuiSpellDisplay(Minecraft.getMinecraft()));
} }
@Override @Override
public void initMixedFontRenderer(){ public void initGuiBits(){
mixedFontRenderer = new MixedFontRenderer(Minecraft.getMinecraft().gameSettings, mixedFontRenderer = new MixedFontRenderer(Minecraft.getMinecraft().gameSettings, new ResourceLocation("textures/font/ascii.png"),
new ResourceLocation("textures/font/ascii.png"), Minecraft.getMinecraft().renderEngine, false); Minecraft.getMinecraft().renderEngine, false);
GuiWizardHandbook.initDisplayRecipes();
} }
// SECTION Misc // SECTION Misc
// =============================================================================================================== // ===============================================================================================================
@Override @Override
public void setToNumberSliderEntry(Property property) { public void setToNumberSliderEntry(Property property){
property.setConfigEntryClass(NumberSliderEntry.class); property.setConfigEntryClass(NumberSliderEntry.class);
} }
@Override @Override
public World getTheWorld() { public World getTheWorld(){
return Minecraft.getMinecraft().theWorld; return Minecraft.getMinecraft().world;
} }
@Override @Override
public void playMovingSound(Entity entity, SoundEvent sound, float volume, float pitch, boolean repeat){ public void playMovingSound(Entity entity, SoundEvent sound, float volume, float pitch, boolean repeat){
Minecraft.getMinecraft().getSoundHandler().playSound(new MovingSoundEntity(entity, sound, volume, pitch, repeat)); Minecraft.getMinecraft().getSoundHandler().playSound(new MovingSoundEntity(entity, sound, volume, pitch, repeat));
} }
// SECTION Items // SECTION Items
// =============================================================================================================== // ===============================================================================================================
@Override @Override
public FontRenderer getFontRenderer(ItemStack stack){ public FontRenderer getFontRenderer(ItemStack stack){
Spell spell = Spells.none; Spell spell = Spells.none;
if(stack.getItem() instanceof ItemWand){ if(stack.getItem() instanceof ItemWand){
spell = WandHelper.getCurrentSpell(stack); spell = WandHelper.getCurrentSpell(stack);
}else if(stack.getItem() instanceof ItemSpellBook || stack.getItem() instanceof ItemScroll){ }else if(stack.getItem() instanceof ItemSpellBook || stack.getItem() instanceof ItemScroll){
spell = Spell.get(stack.getItemDamage()); spell = Spell.get(stack.getItemDamage());
} }
if(Minecraft.getMinecraft().thePlayer != null && Wizardry.settings.discoveryMode if(Minecraft.getMinecraft().player != null && Wizardry.settings.discoveryMode && WizardData.get(Minecraft.getMinecraft().player) != null
&& WizardData.get(Minecraft.getMinecraft().thePlayer) != null && !Minecraft.getMinecraft().player.capabilities.isCreativeMode
&& !Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode && !WizardData.get(Minecraft.getMinecraft().player).hasSpellBeenDiscovered(spell)){
&& !WizardData.get(Minecraft.getMinecraft().thePlayer).hasSpellBeenDiscovered(spell)){
return mixedFontRenderer; return mixedFontRenderer;
} }
return null; return null;
} }
@Override @Override
public String getScrollDisplayName(ItemStack scroll){ public String getScrollDisplayName(ItemStack scroll){
// Displays [Empty slot] if spell is continuous. // Displays [Empty slot] if spell is continuous.
Spell spell = Spell.get(scroll.getItemDamage()); Spell spell = Spell.get(scroll.getItemDamage());
if(spell.isContinuous) spell = Spells.none; if(spell.isContinuous) spell = Spells.none;
EntityPlayer player = Minecraft.getMinecraft().thePlayer; EntityPlayer player = Minecraft.getMinecraft().player;
boolean discovered = true; boolean discovered = true;
// It seems that this method is called when the world is loading, before thePlayer has been initialised. // It seems that this method is called when the world is loading, before thePlayer has been initialised.
// If the player is null, the spell is assumed to be discovered. // If the player is null, the spell is assumed to be discovered.
if(player != null && Wizardry.settings.discoveryMode && !player.capabilities.isCreativeMode if(player != null && Wizardry.settings.discoveryMode && !player.capabilities.isCreativeMode && WizardData.get(player) != null
&& WizardData.get(player) != null && !WizardData.get(player).hasSpellBeenDiscovered(spell)){ && !WizardData.get(player).hasSpellBeenDiscovered(spell)){
discovered = false; discovered = false;
} }
if(discovered){ if(discovered){
return I18n.format("item.wizardry:scroll.name", spell.getDisplayName()).trim(); return I18n.format("item." + Wizardry.MODID + ":scroll.name", spell.getDisplayName()).trim();
}else{ }else{
return I18n.format("item.wizardry:scroll.undiscovered.name", "#" + SpellGlyphData.getGlyphName(spell, player.worldObj) + "#").trim(); return I18n.format("item." + Wizardry.MODID + ":scroll.undiscovered.name", "#" + SpellGlyphData.getGlyphName(spell, player.world) + "#").trim();
} }
} }
@Override @Override
public double getConjuredBowDurability(ItemStack stack){ public double getConjuredBowDurability(ItemStack stack){
EntityPlayer player = Minecraft.getMinecraft().thePlayer; EntityPlayer player = Minecraft.getMinecraft().player;
if(player.getActiveItemStack() == stack){ if(player.getActiveItemStack() == stack){
return (double)(stack.getItemDamage() + (player.getItemInUseMaxCount()) ) / (double)stack.getMaxDamage(); return (double)(stack.getItemDamage() + (player.getItemInUseMaxCount())) / (double)stack.getMaxDamage();
} }
return super.getConjuredBowDurability(stack); return super.getConjuredBowDurability(stack);
} }
// SECTION Particles // SECTION Particles
// =============================================================================================================== // ===============================================================================================================
@Override @Override
public void spawnParticle(WizardryParticleType type, World world, double x, double y, double z, double velX, double velY, double velZ, int maxAge, float r, float g, float b, boolean doGravity, double radius){ public void spawnParticle(WizardryParticleType type, World world, double x, double y, double z, double velX, double velY, double velZ, int maxAge,
float r, float g, float b, boolean doGravity, double radius){
// Colour values are now automatically clamped to between 0 and 1, as values outside this range seem to // Colour values are now automatically clamped to between 0 and 1, as values outside this range seem to
// cause strange effects in 1.10 (or more specifically, particles that are bright pink!) // cause strange effects in 1.10 (or more specifically, particles that are bright pink!)
// TODO: This is a terrible dirty fix, but it'll do for now. Find a nicer way in future. // TODO: This is a terrible dirty fix, but it'll do for now. Find a nicer way in future.
if(type != WizardryParticleType.MAGIC_FIRE) r = MathHelper.clamp_float(r, 0, 1); if(type != WizardryParticleType.MAGIC_FIRE) r = MathHelper.clamp(r, 0, 1);
g = MathHelper.clamp_float(g, 0, 1); g = MathHelper.clamp(g, 0, 1);
b = MathHelper.clamp_float(b, 0, 1); b = MathHelper.clamp(b, 0, 1);
switch(type){ switch(type){
case BLIZZARD: case BLIZZARD:
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleBlizzard(world, maxAge, x, z, radius, y)); Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleBlizzard(world, maxAge, x, z, radius, y));
break; break;
@@ -318,90 +320,92 @@ public class ClientProxy extends CommonProxy {
break; break;
} }
} }
@Override @Override
public void spawnTornadoParticle(World world, double x, double y, double z, double velX, double velZ, double radius, int maxAge, IBlockState block, BlockPos pos){ public void spawnTornadoParticle(World world, double x, double y, double z, double velX, double velZ, double radius, int maxAge,
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleTornado(world, maxAge, x, z, radius, y, velX, velZ, block).setBlockPos(pos));//, world.rand.nextInt(6))); IBlockState block, BlockPos pos){
} Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleTornado(world, maxAge, x, z, radius, y, velX, velZ, block).setBlockPos(pos));// ,
// world.rand.nextInt(6)));
}
// SECTION Packet Handlers // SECTION Packet Handlers
// =============================================================================================================== // ===============================================================================================================
@Override @Override
public void handleCastSpellPacket(PacketCastSpell.Message message){ public void handleCastSpellPacket(PacketCastSpell.Message message){
World world = Minecraft.getMinecraft().theWorld; World world = Minecraft.getMinecraft().world;
Entity caster = world.getEntityByID(message.casterID); Entity caster = world.getEntityByID(message.casterID);
Spell spell = Spell.get(message.spellID); Spell spell = Spell.get(message.spellID);
// Should always be true // Should always be true
if(caster instanceof EntityPlayer){ if(caster instanceof EntityPlayer){
((EntityPlayer)caster).setActiveHand(message.hand); ((EntityPlayer)caster).setActiveHand(message.hand);
// Duration isn't needed because it only ever affects things server-side, and anything that is // Duration isn't needed because it only ever affects things server-side, and anything that is
// seen client-side gets synced elsewhere. // seen client-side gets synced elsewhere.
spell.cast(world, (EntityPlayer)caster, message.hand, 0, message.modifiers); spell.cast(world, (EntityPlayer)caster, message.hand, 0, message.modifiers);
Source source = Source.OTHER; Source source = Source.OTHER;
if(((EntityPlayer)caster).getHeldItem(message.hand) != null){ Item item = ((EntityPlayer)caster).getHeldItem(message.hand).getItem();
Item item = ((EntityPlayer)caster).getHeldItem(message.hand).getItem();
if(item instanceof ItemWand){ if(item instanceof ItemWand){
source = Source.WAND; source = Source.WAND;
}else if(item instanceof ItemScroll){ }else if(item instanceof ItemScroll){
source = Source.SCROLL; source = Source.SCROLL;
}
} }
// No need to check if the spell succeeded, because the packet is only ever sent when it succeeds. // No need to check if the spell succeeded, because the packet is only ever sent when it succeeds.
// The handler for this event now deals with discovery. // The handler for this event now deals with discovery.
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post((EntityPlayer)caster, spell, message.modifiers, source)); MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post((EntityPlayer)caster, spell, message.modifiers, source));
}else{ }else{
Wizardry.logger.warn("Recieved a PacketCastSpell, but the caster ID was not the ID of a player"); Wizardry.logger.warn("Recieved a PacketCastSpell, but the caster ID was not the ID of a player");
} }
} }
@Override @Override
public void handleCastContinuousSpellPacket(PacketCastContinuousSpell.Message message){ public void handleCastContinuousSpellPacket(PacketCastContinuousSpell.Message message){
World world = Minecraft.getMinecraft().theWorld; World world = Minecraft.getMinecraft().world;
Entity caster = world.getEntityByID(message.casterID); Entity caster = world.getEntityByID(message.casterID);
Spell spell = Spell.get(message.spellID); Spell spell = Spell.get(message.spellID);
// Should always be true // Should always be true
if(caster instanceof EntityPlayer){ if(caster instanceof EntityPlayer){
WizardData data = WizardData.get((EntityPlayer)caster); WizardData data = WizardData.get((EntityPlayer)caster);
if(data != null){ if(data != null){
if(data.isCasting()){ if(data.isCasting()){
WizardData.get((EntityPlayer)caster).stopCastingContinuousSpell(); WizardData.get((EntityPlayer)caster).stopCastingContinuousSpell();
}else{ }else{
WizardData.get((EntityPlayer)caster).startCastingContinuousSpell(spell, message.modifiers); WizardData.get((EntityPlayer)caster).startCastingContinuousSpell(spell, message.modifiers);
} }
} }
}else{ }else{
Wizardry.logger.warn("Recieved a PacketCastContinuousSpell, but the caster ID was not the ID of a player"); Wizardry.logger.warn("Recieved a PacketCastContinuousSpell, but the caster ID was not the ID of a player");
} }
} }
@Override @Override
public void handleNPCCastSpellPacket(PacketNPCCastSpell.Message message){ public void handleNPCCastSpellPacket(PacketNPCCastSpell.Message message){
World world = Minecraft.getMinecraft().theWorld; World world = Minecraft.getMinecraft().world;
Entity caster = world.getEntityByID(message.casterID); Entity caster = world.getEntityByID(message.casterID);
Entity target = message.targetID == -1 ? null : world.getEntityByID(message.targetID); Entity target = message.targetID == -1 ? null : world.getEntityByID(message.targetID);
Spell spell = Spell.get(message.spellID); Spell spell = Spell.get(message.spellID);
// Should always be true // Should always be true
if(caster instanceof EntityLiving){ if(caster instanceof EntityLiving){
if(target instanceof EntityLivingBase){ if(target instanceof EntityLivingBase){
spell.cast(world, (EntityLiving)caster, message.hand, 0, (EntityLivingBase)target, message.modifiers); spell.cast(world, (EntityLiving)caster, message.hand, 0, (EntityLivingBase)target, message.modifiers);
// Again, no need to check if the spell succeeded, because the packet is only ever sent when it succeeds. // Again, no need to check if the spell succeeded, because the packet is only ever sent when it
// succeeds.
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post((EntityLiving)caster, spell, message.modifiers, Source.NPC)); MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post((EntityLiving)caster, spell, message.modifiers, Source.NPC));
} }
if(caster instanceof ISpellCaster){ if(caster instanceof ISpellCaster){
if(spell.isContinuous || spell instanceof None){ if(spell.isContinuous || spell instanceof None){
((ISpellCaster)caster).setContinuousSpell(spell); ((ISpellCaster)caster).setContinuousSpell(spell);
@@ -412,55 +416,56 @@ public class ClientProxy extends CommonProxy {
Wizardry.logger.warn("Recieved a PacketNPCCastSpell, but the caster ID was not the ID of an EntityLiving"); Wizardry.logger.warn("Recieved a PacketNPCCastSpell, but the caster ID was not the ID of an EntityLiving");
} }
} }
@Override @Override
public void handleTransportationPacket(PacketTransportation.Message message){ public void handleTransportationPacket(PacketTransportation.Message message){
World world = Minecraft.getMinecraft().theWorld; World world = Minecraft.getMinecraft().world;
Entity caster = world.getEntityByID(message.casterID); Entity caster = world.getEntityByID(message.casterID);
// Moved from when the packet is sent to when it is received; fixes the sound not playing in first person. // Moved from when the packet is sent to when it is received; fixes the sound not playing in first person.
caster.playSound(SoundEvents.BLOCK_PORTAL_TRAVEL, 1, 1); caster.playSound(SoundEvents.BLOCK_PORTAL_TRAVEL, 1, 1);
for(int i=0; i<20; i++){ for(int i = 0; i < 20; i++){
double radius = 1; double radius = 1;
double angle = world.rand.nextDouble()*Math.PI*2; double angle = world.rand.nextDouble() * Math.PI * 2;
double x = caster.posX + radius*Math.cos(angle); double x = caster.posX + radius * Math.cos(angle);
double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble()*2; double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble() * 2;
double z = caster.posZ + radius*Math.sin(angle); double z = caster.posZ + radius * Math.sin(angle);
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleSparkle(world, x, y, z, 0, 0.02, 0, 0.6f, 1.0f, 0.6f, 80 + world.rand.nextInt(10))); Minecraft.getMinecraft().effectRenderer
.addEffect(new ParticleSparkle(world, x, y, z, 0, 0.02, 0, 0.6f, 1.0f, 0.6f, 80 + world.rand.nextInt(10)));
} }
for(int i=0; i<20; i++){ for(int i = 0; i < 20; i++){
double radius = 1; double radius = 1;
double angle = world.rand.nextDouble()*Math.PI*2; double angle = world.rand.nextDouble() * Math.PI * 2;
double x = caster.posX + radius*Math.cos(angle); double x = caster.posX + radius * Math.cos(angle);
double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble()*2; double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble() * 2;
double z = caster.posZ + radius*Math.sin(angle); double z = caster.posZ + radius * Math.sin(angle);
world.spawnParticle(EnumParticleTypes.VILLAGER_HAPPY, x, y, z, 0, 0.02, 0); world.spawnParticle(EnumParticleTypes.VILLAGER_HAPPY, x, y, z, 0, 0.02, 0);
} }
for(int i=0; i<20; i++){ for(int i = 0; i < 20; i++){
double radius = 1; double radius = 1;
double angle = world.rand.nextDouble()*Math.PI*2; double angle = world.rand.nextDouble() * Math.PI * 2;
double x = caster.posX + radius*Math.cos(angle); double x = caster.posX + radius * Math.cos(angle);
double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble()*2; double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble() * 2;
double z = caster.posZ + radius*Math.sin(angle); double z = caster.posZ + radius * Math.sin(angle);
world.spawnParticle(EnumParticleTypes.ENCHANTMENT_TABLE, x, y, z, 0, 0.02, 0); world.spawnParticle(EnumParticleTypes.ENCHANTMENT_TABLE, x, y, z, 0, 0.02, 0);
} }
} }
@Override @Override
public void handlePlayerSyncPacket(Message message){ public void handlePlayerSyncPacket(Message message){
WizardData properties = WizardData.get(Minecraft.getMinecraft().thePlayer); WizardData properties = WizardData.get(Minecraft.getMinecraft().player);
if(properties != null){ if(properties != null){
properties.spellsDiscovered = message.spellsDiscovered; properties.spellsDiscovered = message.spellsDiscovered;
if(message.selectedMinionID == -1){ if(message.selectedMinionID == -1){
properties.selectedMinion = null; properties.selectedMinion = null;
}else{ }else{
Entity entity = Minecraft.getMinecraft().theWorld.getEntityByID(message.selectedMinionID); Entity entity = Minecraft.getMinecraft().world.getEntityByID(message.selectedMinionID);
if(entity instanceof ISummonedCreature){ if(entity instanceof ISummonedCreature){
properties.selectedMinion = new WeakReference<ISummonedCreature>((ISummonedCreature)entity); properties.selectedMinion = new WeakReference<ISummonedCreature>((ISummonedCreature)entity);
}else{ }else{
@@ -469,47 +474,48 @@ public class ClientProxy extends CommonProxy {
} }
} }
} }
@Override @Override
public void handleGlyphDataPacket(electroblob.wizardry.packet.PacketGlyphData.Message message){ public void handleGlyphDataPacket(electroblob.wizardry.packet.PacketGlyphData.Message message){
SpellGlyphData data = SpellGlyphData.get(Minecraft.getMinecraft().theWorld); SpellGlyphData data = SpellGlyphData.get(Minecraft.getMinecraft().world);
data.randomNames = new HashMap<Spell, String>(); data.randomNames = new HashMap<Spell, String>();
data.randomDescriptions = new HashMap<Spell, String>(); data.randomDescriptions = new HashMap<Spell, String>();
for(Spell spell : Spell.getSpells(Spell.allSpells)){ for(Spell spell : Spell.getSpells(Spell.allSpells)){
// -1 because the none spell isn't included // -1 because the none spell isn't included
data.randomNames.put(spell, message.names.get(spell.id() - 1)); data.randomNames.put(spell, message.names.get(spell.id() - 1));
data.randomDescriptions.put(spell, message.descriptions.get(spell.id() - 1)); data.randomDescriptions.put(spell, message.descriptions.get(spell.id() - 1));
} }
} }
@Override @Override
public void handleClairvoyancePacket(electroblob.wizardry.packet.PacketClairvoyance.Message message) { public void handleClairvoyancePacket(electroblob.wizardry.packet.PacketClairvoyance.Message message){
Clairvoyance.spawnPathPaticles(Minecraft.getMinecraft().theWorld, message.path, message.durationMultiplier); Clairvoyance.spawnPathPaticles(Minecraft.getMinecraft().world, message.path, message.durationMultiplier);
} }
// SECTION Rendering // SECTION Rendering
// =============================================================================================================== // ===============================================================================================================
private static final ResourceLocation ICE_WRAITH_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/ice_wraith.png"); private static final ResourceLocation ICE_WRAITH_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/ice_wraith.png");
private static final ResourceLocation LIGHTNING_WRAITH_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_wraith.png"); private static final ResourceLocation LIGHTNING_WRAITH_TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_wraith.png");
/** Static instance of the statue renderer, used to access the block breaking texture. */ /** Static instance of the statue renderer, used to access the block breaking texture. */
public static RenderStatue renderStatue; public static RenderStatue renderStatue;
@Override @Override
public void initialiseLayers(){ public void initialiseLayers(){
LayerStone.initialiseLayers(); LayerStone.initialiseLayers();
} }
@Override @Override
public void registerRenderers(){ public void registerRenderers(){
// Minions // Minions
// Yet another advantage to the new system: turns out you don't even need to register the renderer if you // Yet another advantage to the new system: turns out you don't even need to register the renderer if you
// just want the vanilla one for the mob you're extending. // just want the vanilla one for the mob you're extending.
// An anonymous class in a lambda expression! No point writing a separate class really, is there? // An anonymous class in a lambda expression! No point writing a separate class really, is there?
RenderingRegistry.registerEntityRenderingHandler(EntityLightningWraith.class, manager -> new RenderBlaze(manager){ RenderingRegistry.registerEntityRenderingHandler(EntityLightningWraith.class, manager -> new RenderBlaze(manager){
@Override @Override
@@ -517,44 +523,59 @@ public class ClientProxy extends CommonProxy {
return LIGHTNING_WRAITH_TEXTURE; return LIGHTNING_WRAITH_TEXTURE;
} }
}); });
RenderingRegistry.registerEntityRenderingHandler(EntityIceWraith.class, manager -> new RenderBlaze(manager){ RenderingRegistry.registerEntityRenderingHandler(EntityIceWraith.class, manager -> new RenderBlaze(manager){
@Override @Override
protected ResourceLocation getEntityTexture(EntityBlaze entity){ protected ResourceLocation getEntityTexture(EntityBlaze entity){
return ICE_WRAITH_TEXTURE; return ICE_WRAITH_TEXTURE;
} }
}); });
RenderingRegistry.registerEntityRenderingHandler(EntityIceGiant.class, RenderIceGiant::new); RenderingRegistry.registerEntityRenderingHandler(EntityIceGiant.class, RenderIceGiant::new);
RenderingRegistry.registerEntityRenderingHandler(EntityPhoenix.class, RenderPhoenix::new); RenderingRegistry.registerEntityRenderingHandler(EntityPhoenix.class, RenderPhoenix::new);
// Projectiles // Projectiles
RenderingRegistry.registerEntityRenderingHandler(EntityMagicMissile.class, manager -> new RenderMagicArrow(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/magic_missile.png"), false, 8.0, 4.0, 16, 9, false)); RenderingRegistry.registerEntityRenderingHandler(EntityMagicMissile.class, manager -> new RenderMagicArrow(manager,
RenderingRegistry.registerEntityRenderingHandler(EntityIceShard.class, manager -> new RenderMagicArrow(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/ice_shard.png"), false, 8.0, 2.0, 16, 5, false)); new ResourceLocation(Wizardry.MODID, "textures/entity/magic_missile.png"), false, 8.0, 4.0, 16, 9, false));
RenderingRegistry.registerEntityRenderingHandler(EntityLightningArrow.class, manager -> new RenderMagicArrow(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_arrow.png"), true, 8.0, 2.0, 16, 5, false)); RenderingRegistry.registerEntityRenderingHandler(EntityIceShard.class, manager -> new RenderMagicArrow(manager,
RenderingRegistry.registerEntityRenderingHandler(EntityDart.class, manager -> new RenderMagicArrow(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/dart.png"), false, 8.0, 2.0, 16, 5, true)); new ResourceLocation(Wizardry.MODID, "textures/entity/ice_shard.png"), false, 8.0, 2.0, 16, 5, false));
RenderingRegistry.registerEntityRenderingHandler(EntityIceLance.class, manager -> new RenderMagicArrow(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/ice_lance.png"), false, 16.0, 3.0, 22, 5, true)); RenderingRegistry.registerEntityRenderingHandler(EntityLightningArrow.class, manager -> new RenderMagicArrow(manager,
new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_arrow.png"), true, 8.0, 2.0, 16, 5, false));
RenderingRegistry.registerEntityRenderingHandler(EntityDart.class, manager -> new RenderMagicArrow(manager,
new ResourceLocation(Wizardry.MODID, "textures/entity/dart.png"), false, 8.0, 2.0, 16, 5, true));
RenderingRegistry.registerEntityRenderingHandler(EntityIceLance.class, manager -> new RenderMagicArrow(manager,
new ResourceLocation(Wizardry.MODID, "textures/entity/ice_lance.png"), false, 16.0, 3.0, 22, 5, true));
RenderingRegistry.registerEntityRenderingHandler(EntityForceArrow.class, RenderForceArrow::new); RenderingRegistry.registerEntityRenderingHandler(EntityForceArrow.class, RenderForceArrow::new);
// Creatures // Creatures
RenderingRegistry.registerEntityRenderingHandler(EntitySpiritWolf.class, manager -> new RenderSpiritWolf(manager, 0.5f)); RenderingRegistry.registerEntityRenderingHandler(EntitySpiritWolf.class, manager -> new RenderSpiritWolf(manager));
RenderingRegistry.registerEntityRenderingHandler(EntitySpiritHorse.class, manager -> new RenderSpiritHorse(manager, 0.5f)); RenderingRegistry.registerEntityRenderingHandler(EntitySpiritHorse.class, manager -> new RenderSpiritHorse(manager));
RenderingRegistry.registerEntityRenderingHandler(EntityWizard.class, RenderWizard::new); RenderingRegistry.registerEntityRenderingHandler(EntityWizard.class, RenderWizard::new);
RenderingRegistry.registerEntityRenderingHandler(EntityEvilWizard.class, RenderEvilWizard::new); RenderingRegistry.registerEntityRenderingHandler(EntityEvilWizard.class, RenderEvilWizard::new);
RenderingRegistry.registerEntityRenderingHandler(EntityDecoy.class, RenderDecoy::new); RenderingRegistry.registerEntityRenderingHandler(EntityDecoy.class, RenderDecoy::new);
// Throwables // Throwables
RenderingRegistry.registerEntityRenderingHandler(EntitySparkBomb.class, manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/entity/spark_bomb.png"), false)); RenderingRegistry.registerEntityRenderingHandler(EntitySparkBomb.class,
RenderingRegistry.registerEntityRenderingHandler(EntityFirebomb.class, manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/items/firebomb.png"), false)); manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/entity/spark_bomb.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntityPoisonBomb.class, manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/items/poison_bomb.png"), false)); RenderingRegistry.registerEntityRenderingHandler(EntityFirebomb.class,
RenderingRegistry.registerEntityRenderingHandler(EntityIceCharge.class, manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/entity/ice_charge.png"), false)); manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/items/firebomb.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntityForceOrb.class, manager -> new RenderProjectile(manager, 0.7f, new ResourceLocation(Wizardry.MODID, "textures/entity/force_orb.png"), true)); RenderingRegistry.registerEntityRenderingHandler(EntityPoisonBomb.class,
RenderingRegistry.registerEntityRenderingHandler(EntitySpark.class, manager -> new RenderProjectile(manager, 0.4f, new ResourceLocation(Wizardry.MODID, "textures/entity/spark.png"), true)); manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/items/poison_bomb.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntityDarknessOrb.class, manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/entity/darkness_orb.png"), true)); RenderingRegistry.registerEntityRenderingHandler(EntityIceCharge.class,
RenderingRegistry.registerEntityRenderingHandler(EntityFirebolt.class, manager -> new RenderProjectile(manager, 0.2f, new ResourceLocation(Wizardry.MODID, "textures/entity/firebolt.png"), false)); manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/entity/ice_charge.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntityLightningDisc.class, manager -> new RenderLightningDisc(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_sigil.png"), 2.0f)); RenderingRegistry.registerEntityRenderingHandler(EntityForceOrb.class,
RenderingRegistry.registerEntityRenderingHandler(EntitySmokeBomb.class, manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/items/smoke_bomb.png"), false)); manager -> new RenderProjectile(manager, 0.7f, new ResourceLocation(Wizardry.MODID, "textures/entity/force_orb.png"), true));
RenderingRegistry.registerEntityRenderingHandler(EntitySpark.class,
manager -> new RenderProjectile(manager, 0.4f, new ResourceLocation(Wizardry.MODID, "textures/entity/spark.png"), true));
RenderingRegistry.registerEntityRenderingHandler(EntityDarknessOrb.class,
manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/entity/darkness_orb.png"), true));
RenderingRegistry.registerEntityRenderingHandler(EntityFirebolt.class,
manager -> new RenderProjectile(manager, 0.2f, new ResourceLocation(Wizardry.MODID, "textures/entity/firebolt.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntityLightningDisc.class,
manager -> new RenderLightningDisc(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_sigil.png"), 2.0f));
RenderingRegistry.registerEntityRenderingHandler(EntitySmokeBomb.class,
manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/items/smoke_bomb.png"), false));
// Effects and constructs // Effects and constructs
RenderingRegistry.registerEntityRenderingHandler(EntityArc.class, RenderArc::new); RenderingRegistry.registerEntityRenderingHandler(EntityArc.class, RenderArc::new);
@@ -576,11 +597,16 @@ public class ClientProxy extends CommonProxy {
RenderingRegistry.registerEntityRenderingHandler(EntityHailstorm.class, RenderBlank::new); RenderingRegistry.registerEntityRenderingHandler(EntityHailstorm.class, RenderBlank::new);
// Runes on ground // Runes on ground
RenderingRegistry.registerEntityRenderingHandler(EntityHealAura.class, manager -> new RenderSigil(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/healing_aura.png"), 5.0f, false)); RenderingRegistry.registerEntityRenderingHandler(EntityHealAura.class,
RenderingRegistry.registerEntityRenderingHandler(EntityFireSigil.class, manager -> new RenderSigil(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/fire_sigil.png"), 2.0f, true)); manager -> new RenderSigil(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/healing_aura.png"), 5.0f, false));
RenderingRegistry.registerEntityRenderingHandler(EntityFrostSigil.class, manager -> new RenderSigil(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/frost_sigil.png"), 2.0f, true)); RenderingRegistry.registerEntityRenderingHandler(EntityFireSigil.class,
RenderingRegistry.registerEntityRenderingHandler(EntityLightningSigil.class, manager -> new RenderSigil(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_sigil.png"), 2.0f, true)); manager -> new RenderSigil(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/fire_sigil.png"), 2.0f, true));
RenderingRegistry.registerEntityRenderingHandler(EntityFireRing.class, manager -> new RenderFireRing(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/ring_of_fire.png"), 5.0f)); RenderingRegistry.registerEntityRenderingHandler(EntityFrostSigil.class,
manager -> new RenderSigil(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/frost_sigil.png"), 2.0f, true));
RenderingRegistry.registerEntityRenderingHandler(EntityLightningSigil.class,
manager -> new RenderSigil(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_sigil.png"), 2.0f, true));
RenderingRegistry.registerEntityRenderingHandler(EntityFireRing.class,
manager -> new RenderFireRing(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/ring_of_fire.png"), 5.0f));
RenderingRegistry.registerEntityRenderingHandler(EntityDecay.class, RenderDecay::new); RenderingRegistry.registerEntityRenderingHandler(EntityDecay.class, RenderDecay::new);
RenderingRegistry.registerEntityRenderingHandler(EntityLightningPulse.class, manager -> new RenderLightningPulse(manager, 8.0f)); RenderingRegistry.registerEntityRenderingHandler(EntityLightningPulse.class, manager -> new RenderLightningPulse(manager, 8.0f));
@@ -1,76 +1,81 @@
package electroblob.wizardry.client; package electroblob.wizardry.client;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.I18n;
import net.minecraft.entity.EntityList; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.client.config.GuiButtonExt; import net.minecraftforge.fml.client.config.GuiButtonExt;
import net.minecraftforge.fml.client.config.GuiEditArray; import net.minecraftforge.fml.client.config.GuiEditArray;
import net.minecraftforge.fml.client.config.GuiEditArrayEntries; import net.minecraftforge.fml.client.config.GuiEditArrayEntries;
import net.minecraftforge.fml.client.config.GuiEditArrayEntries.StringEntry; import net.minecraftforge.fml.client.config.GuiEditArrayEntries.StringEntry;
import net.minecraftforge.fml.client.config.GuiSelectString; import net.minecraftforge.fml.client.config.GuiSelectString;
import net.minecraftforge.fml.client.config.IConfigElement; import net.minecraftforge.fml.client.config.IConfigElement;
import net.minecraftforge.fml.common.registry.EntityEntry;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
/** [NYI] Intended as a way of choosing entities by name from all those currently registered, within the config file, so /**
* that users don't have to look up the entity IDs. I can't get this to work correctly at the moment. */ * [NYI] Intended as a way of choosing entities by name from all those currently registered, within the config file, so
* that users don't have to look up the entity IDs. I can't get this to work correctly at the moment.
*/
public class EntityNameEntry extends StringEntry { public class EntityNameEntry extends StringEntry {
protected final GuiButtonExt btnValue; protected final GuiButtonExt btnValue;
protected Object entityClass; protected Object entityClass;
public EntityNameEntry(GuiEditArray owningScreen, GuiEditArrayEntries owningEntryList, IConfigElement configElement, Object value) public EntityNameEntry(GuiEditArray owningScreen, GuiEditArrayEntries owningEntryList, IConfigElement configElement,
{ Object value){
super(owningScreen, owningEntryList, configElement, value); super(owningScreen, owningEntryList, configElement, value);
this.btnValue = new GuiButtonExt(0, 0, 0, owningEntryList.controlWidth, 18, I18n.format(this.textFieldValue.getText())); this.btnValue = new GuiButtonExt(0, 0, 0, owningEntryList.controlWidth, 18,
//this.btnValue.enabled = owningScreen.enabled; I18n.format(this.textFieldValue.getText()));
} // this.btnValue.enabled = owningScreen.enabled;
}
@Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected)
{
//super.drawEntry(slotIndex, x, y, listWidth, slotHeight, tessellator, mouseX, mouseY, isSelected);
this.btnValue.xPosition = listWidth / 4;
this.btnValue.yPosition = y;
String trans = I18n.format(this.textFieldValue.getText()); @Override
if (!trans.equals(this.textFieldValue.getText())) public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY,
this.btnValue.displayString = trans; boolean isSelected, float partialTicks){
else //super.drawEntry(slotIndex, x, y, listWidth, slotHeight, mouseX, mouseY, isSelected, partial);
this.btnValue.displayString = this.textFieldValue.getText(); this.btnValue.x = listWidth / 4;
//btnValue.packedFGColour = value ? GuiUtils.getColorCode('2', true) : GuiUtils.getColorCode('4', true); this.btnValue.y = y;
this.btnValue.drawButton(owningEntryList.getMC(), mouseX, mouseY); String trans = I18n.format(this.textFieldValue.getText());
} if(!trans.equals(this.textFieldValue.getText()))
this.btnValue.displayString = trans;
else
this.btnValue.displayString = this.textFieldValue.getText();
// btnValue.packedFGColour = value ? GuiUtils.getColorCode('2', true) : GuiUtils.getColorCode('4', true);
@Override this.btnValue.drawButton(owningEntryList.getMC(), mouseX, mouseY, partialTicks);
public boolean mousePressed(int index, int x, int y, int mouseEvent, int relativeX, int relativeY) }
{
if (this.btnValue.mousePressed(owningEntryList.getMC(), x, y))
{
btnValue.playPressSound(owningEntryList.getMC().getSoundHandler());
// Some sort of type incompatiblity meant that I had to do this first.
Map<Object, String> map = new HashMap<Object, String>(EntityList.CLASS_TO_NAME);
Minecraft.getMinecraft().displayGuiScreen(new GuiSelectString(this.owningScreen, configElement, index, map, this.getValue(), true));
owningEntryList.recalculateState();
return true;
}
return super.mousePressed(index, x, y, mouseEvent, relativeX, relativeY); @Override
} public boolean mousePressed(int index, int x, int y, int mouseEvent, int relativeX, int relativeY){
if(this.btnValue.mousePressed(owningEntryList.getMC(), x, y)){
btnValue.playPressSound(owningEntryList.getMC().getSoundHandler());
// Goodness only knows if this works, but the class is unimplemented right now so it doesn't really matter.
Map<Object, String> map = ForgeRegistries.ENTITIES.getEntries().stream().collect(
Collectors.<Entry<ResourceLocation, EntityEntry>, Object, String>toMap(e -> e.getValue().getClass(),
e -> e.getValue().getName()));
Minecraft.getMinecraft().displayGuiScreen(
new GuiSelectString(this.owningScreen, configElement, index, map, this.getValue(), true));
owningEntryList.recalculateState();
return true;
}
@Override return super.mousePressed(index, x, y, mouseEvent, relativeX, relativeY);
public void mouseReleased(int index, int x, int y, int mouseEvent, int relativeX, int relativeY) }
{
this.btnValue.mouseReleased(x, y);
super.mouseReleased(index, x, y, mouseEvent, relativeX, relativeY);
}
@Override @Override
public Object getValue() public void mouseReleased(int index, int x, int y, int mouseEvent, int relativeX, int relativeY){
{ this.btnValue.mouseReleased(x, y);
return this.textFieldValue.getText(); super.mouseReleased(index, x, y, mouseEvent, relativeX, relativeY);
} }
@Override
public Object getValue(){
return this.textFieldValue.getText();
}
} }
@@ -30,18 +30,23 @@ import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
public class GuiArcaneWorkbench extends GuiContainer { public class GuiArcaneWorkbench extends GuiContainer {
private GuiButton applyBtn; private GuiButton applyBtn;
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/gui/arcane_workbench.png"); private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID,
"textures/gui/arcane_workbench.png");
private IInventory playerInventory; private IInventory playerInventory;
private IInventory arcaneWorkbenchInventory; private IInventory arcaneWorkbenchInventory;
private final int tooltipWidth = 164; private final int tooltipWidth = 164;
public GuiArcaneWorkbench(InventoryPlayer invPlayer, TileEntityArcaneWorkbench entity) { // We report the actual size of the GUI to Minecraft when a wand is in so JEI doesn't overdraw it.
// For calculations, we use the size without the tooltip.
private final int xSizeNoTip = 176;
public GuiArcaneWorkbench(InventoryPlayer invPlayer, TileEntityArcaneWorkbench entity){
super(new ContainerArcaneWorkbench(invPlayer, entity)); super(new ContainerArcaneWorkbench(invPlayer, entity));
this.playerInventory = invPlayer; this.playerInventory = invPlayer;
this.arcaneWorkbenchInventory = entity; this.arcaneWorkbenchInventory = entity;
xSize = 176; xSize = xSizeNoTip;
ySize = 220; ySize = 220;
} }
@@ -49,12 +54,15 @@ public class GuiArcaneWorkbench extends GuiContainer {
public void drawScreen(int p_73863_1_, int p_73863_2_, float p_73863_3_){ public void drawScreen(int p_73863_1_, int p_73863_2_, float p_73863_3_){
// Tests if there is a wand in the workbench and edits the positioning accordingly // Tests if there is a wand in the workbench and edits the positioning accordingly
if(this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getHasStack() && this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack().getItem() instanceof ItemWand){ if(this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getHasStack() && this.inventorySlots
guiLeft = (this.width - this.xSize - tooltipWidth)/2; .getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack().getItem() instanceof ItemWand){
this.applyBtn.xPosition = (this.width - tooltipWidth)/2 + 48; xSize = xSizeNoTip + tooltipWidth;
guiLeft = (this.width - this.xSize) / 2;
this.applyBtn.x = (this.width - tooltipWidth) / 2 + 48;
}else{ }else{
guiLeft = (this.width - this.xSize)/2; xSize = xSizeNoTip;
this.applyBtn.xPosition = this.width/2 + 48; guiLeft = (this.width - this.xSize) / 2;
this.applyBtn.x = this.width / 2 + 48;
} }
if(this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getHasStack()){ if(this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getHasStack()){
@@ -64,69 +72,73 @@ public class GuiArcaneWorkbench extends GuiContainer {
} }
super.drawScreen(p_73863_1_, p_73863_2_, p_73863_3_); super.drawScreen(p_73863_1_, p_73863_2_, p_73863_3_);
// Required now, or item mouseover tooltips won't render.
this.renderHoveredToolTip(p_73863_1_, p_73863_2_);
} }
@Override @Override
public void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY) { public void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY){
GlStateManager.pushAttrib();
GlStateManager.color(1F, 1F, 1F, 1F); GlStateManager.color(1F, 1F, 1F, 1F);
Minecraft.getMinecraft().renderEngine.bindTexture(texture); Minecraft.getMinecraft().renderEngine.bindTexture(texture);
// Main inventory // Main inventory
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize); drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSizeNoTip, ySize);
// Changing slots // Changing slots
for(int i=0; i<ContainerArcaneWorkbench.CRYSTAL_SLOT; i++){ for(int i = 0; i < ContainerArcaneWorkbench.CRYSTAL_SLOT; i++){
Slot slot = this.inventorySlots.getSlot(i); Slot slot = this.inventorySlots.getSlot(i);
if(slot.xDisplayPosition >=0 && slot.yDisplayPosition >= 0) if(slot.xPos >= 0 && slot.yPos >= 0)
this.drawTexturedModalRect(guiLeft + slot.xDisplayPosition - 10, guiTop + slot.yDisplayPosition - 10, this.drawTexturedModalRect(guiLeft + slot.xPos - 10, guiTop + slot.yPos - 10, 0, 220, 36, 36);
0, 220, 36, 36);
} }
// Tooltip only drawn if there is a wand // Tooltip only drawn if there is a wand
if(this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getHasStack() && this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack().getItem() instanceof ItemWand){ if(this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getHasStack() && this.inventorySlots
.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack().getItem() instanceof ItemWand){
// Tooltip box // Tooltip box
drawTexturedModalRect(guiLeft + xSize, guiTop, xSize, 0, 256 - xSize - 4, ySize); drawTexturedModalRect(guiLeft + xSizeNoTip, guiTop, xSizeNoTip, 0, 256 - xSizeNoTip - 4, ySize);
drawTexturedModalRect(guiLeft + 252, guiTop, xSize + 4, 0, tooltipWidth - 2*(256 - xSize - 4), ySize); drawTexturedModalRect(guiLeft + 252, guiTop, xSizeNoTip + 4, 0, tooltipWidth - 2 * (256 - xSizeNoTip - 4), ySize);
drawTexturedModalRect(guiLeft + xSize + tooltipWidth - (256 - xSize - 4), guiTop, xSize + 4, 0, 256 - xSize - 4, ySize); drawTexturedModalRect(guiLeft + xSize - (256 - xSizeNoTip - 4), guiTop, xSizeNoTip + 4, 0,
256 - xSizeNoTip - 4, ySize);
ItemStack wand = this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack(); ItemStack wand = this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack();
Spell[] spells = WandHelper.getSpells(wand); Spell[] spells = WandHelper.getSpells(wand);
int i=0; int i = 0;
for(Spell spell : spells){ for(Spell spell : spells){
boolean discovered = true; boolean discovered = true;
if(!this.mc.thePlayer.capabilities.isCreativeMode && WizardData.get(this.mc.thePlayer) != null){ if(!this.mc.player.capabilities.isCreativeMode && WizardData.get(this.mc.player) != null){
discovered = WizardData.get(this.mc.thePlayer).hasSpellBeenDiscovered(spell); discovered = WizardData.get(this.mc.player).hasSpellBeenDiscovered(spell);
} }
// As of Wizardry 1.2, the icons have been split off into their own texture files to allow for add-on // As of Wizardry 1.2, the icons have been split off into their own texture files to allow for add-on
// mods to add their own. // mods to add their own.
Minecraft.getMinecraft().renderEngine.bindTexture(discovered ? spell.element.getIcon() : Element.MAGIC.getIcon()); Minecraft.getMinecraft().renderEngine
.bindTexture(discovered ? spell.element.getIcon() : Element.MAGIC.getIcon());
// Renders the little element icon // Renders the little element icon
WizardryUtilities.drawTexturedRect(guiLeft + xSize + 5, guiTop + 34 + 10*i++, 8, 8); WizardryUtilities.drawTexturedRect(guiLeft + xSizeNoTip + 5, guiTop + 34 + 10 * i++, 8, 8);
} }
int x = 0; int x = 0;
int y = guiTop + 50 + spells.length*10; int y = guiTop + 50 + spells.length * 10;
// Look how much shorter this is with the WandHelper class! // Look how much shorter this is with the WandHelper class!
for(Item item : WandHelper.getSpecialUpgrades()){ for(Item item : WandHelper.getSpecialUpgrades()){
int level = WandHelper.getUpgradeLevel(wand, item); int level = WandHelper.getUpgradeLevel(wand, item);
if(level > 0){ if(level > 0){
ItemStack stack = new ItemStack(item, level); ItemStack stack = new ItemStack(item, level);
GlStateManager.enableDepth(); GlStateManager.enableDepth();
this.itemRender.renderItemAndEffectIntoGUI(stack, guiLeft + xSize + 6 + x, y); this.itemRender.renderItemAndEffectIntoGUI(stack, guiLeft + xSizeNoTip + 6 + x, y);
this.itemRender.renderItemOverlayIntoGUI(this.fontRendererObj, stack, guiLeft + xSize + 6 + x, y, null); this.itemRender.renderItemOverlayIntoGUI(this.fontRenderer, stack, guiLeft + xSizeNoTip + 6 + x, y,
null);
x += 18; x += 18;
GlStateManager.disableDepth(); GlStateManager.disableDepth();
} }
@@ -134,26 +146,31 @@ public class GuiArcaneWorkbench extends GuiContainer {
} }
Minecraft.getMinecraft().renderEngine.bindTexture(texture); Minecraft.getMinecraft().renderEngine.bindTexture(texture);
// Fixes the bug that caused the slot hightlight to render opaque. I don't know why it works, it just works! // Fixes the bug that caused the slot hightlight to render opaque. I don't know why it works, it just works!
GlStateManager.disableBlend(); GlStateManager.disableBlend();
GlStateManager.enableAlpha(); GlStateManager.enableAlpha();
GlStateManager.popAttrib();
} }
@Override @Override
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY){ protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY){
this.fontRendererObj.drawString(this.arcaneWorkbenchInventory.hasCustomName() ? this.arcaneWorkbenchInventory.getName() : I18n.format(this.arcaneWorkbenchInventory.getName()), 8, 6, 4210752); this.fontRenderer
this.fontRendererObj.drawString(this.playerInventory.hasCustomName() ? this.playerInventory.getName() : I18n.format(this.playerInventory.getName()), 8, this.ySize - 96 + 2, 4210752); .drawString(this.arcaneWorkbenchInventory.hasCustomName() ? this.arcaneWorkbenchInventory.getName()
: I18n.format(this.arcaneWorkbenchInventory.getName()), 8, 6, 4210752);
this.fontRenderer.drawString(this.playerInventory.hasCustomName() ? this.playerInventory.getName()
: I18n.format(this.playerInventory.getName()), 8, this.ySize - 96 + 2, 4210752);
if(this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getHasStack() && this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack().getItem() instanceof ItemWand){ if(this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getHasStack() && this.inventorySlots
.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack().getItem() instanceof ItemWand){
ItemStack wand = this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack(); ItemStack wand = this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack();
this.fontRendererObj.drawStringWithShadow("\u00A7f" + wand.getDisplayName(), xSize + 6, 6, 0); this.fontRenderer.drawStringWithShadow("\u00A7f" + wand.getDisplayName(), xSizeNoTip + 6, 6, 0);
this.fontRendererObj.drawStringWithShadow("\u00A77" + I18n.format("container.wizardry:arcane_workbench.mana") + " " + (wand.getMaxDamage() - wand.getItemDamage()) + "/" + wand.getMaxDamage(), xSize + 6, 20, 0); this.fontRenderer.drawStringWithShadow(
"\u00A77" + I18n.format("container." + Wizardry.MODID + ":arcane_workbench.mana") + " "
+ (wand.getMaxDamage() - wand.getItemDamage()) + "/" + wand.getMaxDamage(),
xSizeNoTip + 6, 20, 0);
Spell[] spells = WandHelper.getSpells(wand); Spell[] spells = WandHelper.getSpells(wand);
@@ -163,33 +180,35 @@ public class GuiArcaneWorkbench extends GuiContainer {
boolean discovered = true; boolean discovered = true;
if(!this.mc.thePlayer.capabilities.isCreativeMode && WizardData.get(this.mc.thePlayer) != null){ if(!this.mc.player.capabilities.isCreativeMode && WizardData.get(this.mc.player) != null){
discovered = WizardData.get(this.mc.thePlayer).hasSpellBeenDiscovered(spell); discovered = WizardData.get(this.mc.player).hasSpellBeenDiscovered(spell);
} }
if(discovered){ if(discovered){
this.fontRendererObj.drawStringWithShadow(spell.getDisplayNameWithFormatting(), xSize + 16, y, 0); this.fontRenderer.drawStringWithShadow(spell.getDisplayNameWithFormatting(), xSizeNoTip + 16, y, 0);
}else{ }else{
this.mc.standardGalacticFontRenderer.drawStringWithShadow("\u00A79" + SpellGlyphData.getGlyphName(spell, this.mc.theWorld), xSize + 16, y, 0); this.mc.standardGalacticFontRenderer.drawStringWithShadow(
"\u00A79" + SpellGlyphData.getGlyphName(spell, this.mc.world), xSizeNoTip + 16, y, 0);
} }
y += 10; y += 10;
} }
if(WandHelper.getTotalUpgrades(wand) > 0){ if(WandHelper.getTotalUpgrades(wand) > 0){
this.fontRendererObj.drawStringWithShadow("\u00A7f" + I18n.format("container.wizardry:arcane_workbench.upgrades"), xSize + 6, y + 6, 0); this.fontRenderer.drawStringWithShadow(
"\u00A7f" + I18n.format("container." + Wizardry.MODID + ":arcane_workbench.upgrades"), xSizeNoTip + 6, y + 6, 0);
int x = 0; int x = 0;
y = 50 + spells.length*10; y = 50 + spells.length * 10;
// Wand upgrade tooltips // Wand upgrade tooltips
for(Item item : WandHelper.getSpecialUpgrades()){ for(Item item : WandHelper.getSpecialUpgrades()){
int level = WandHelper.getUpgradeLevel(wand, item); int level = WandHelper.getUpgradeLevel(wand, item);
if(level > 0){ if(level > 0){
// The javadoc for isPointInRegion is ambiguous; what it means is that the REGION is // The javadoc for isPointInRegion is ambiguous; what it means is that the REGION is
// relative to the GUI but the POINT isn't. // relative to the GUI but the POINT isn't.
if(isPointInRegion(xSize + 6 + x, y, 16, 16, mouseX, mouseY)){ if(isPointInRegion(xSizeNoTip + 6 + x, y, 16, 16, mouseX, mouseY)){
ItemStack stack = new ItemStack(item, level); ItemStack stack = new ItemStack(item, level);
this.renderToolTip(stack, mouseX - guiLeft, mouseY - guiTop); this.renderToolTip(stack, mouseX - guiLeft, mouseY - guiTop);
} }
@@ -202,12 +221,12 @@ public class GuiArcaneWorkbench extends GuiContainer {
@Override @Override
public void initGui(){ public void initGui(){
this.mc.thePlayer.openContainer = this.inventorySlots; this.mc.player.openContainer = this.inventorySlots;
this.guiLeft = (this.width - this.xSize) / 2; this.guiLeft = (this.width - this.xSize) / 2;
this.guiTop = (this.height - this.ySize) / 2; this.guiTop = (this.height - this.ySize) / 2;
Keyboard.enableRepeatEvents(true); Keyboard.enableRepeatEvents(true);
this.buttonList.clear(); this.buttonList.clear();
this.buttonList.add(this.applyBtn = new GuiButtonApply(0, this.width/2 + 48, this.height/2 + 3)); this.buttonList.add(this.applyBtn = new GuiButtonApply(0, this.width / 2 + 48, this.height / 2 + 3));
} }
@Override @Override
@@ -1,5 +1,6 @@
package electroblob.wizardry.client; package electroblob.wizardry.client;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.util.WizardryUtilities; import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
@@ -10,32 +11,32 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
class GuiButtonApply extends GuiButton { class GuiButtonApply extends GuiButton {
public GuiButtonApply(int id, int x, int y){ public GuiButtonApply(int id, int x, int y){
super(id, x, y, 32, 16, I18n.format("container." + Wizardry.MODID + ":arcane_workbench.apply"));
super(id, x, y, 32, 16, I18n.format("container.wizardry:arcane_workbench.apply")); }
}
@Override @Override
public void drawButton(Minecraft minecraft, int mouseX, int mouseY){ public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
// Whether the button is highlighted // Whether the button is highlighted
this.hovered = mouseX >= this.xPosition && mouseY >= this.yPosition && mouseX < this.xPosition + this.width && mouseY < this.yPosition + this.height; this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
int k = 36; int k = 36;
int l = 220; int l = 220;
int colour = 14737632; int colour = 14737632;
if(this.enabled){ if(this.enabled){
if(this.hovered){ if(this.hovered){
k += this.width*2; k += this.width * 2;
colour = 16777120; colour = 16777120;
} }
}else{ }else{
k += this.width; k += this.width;
colour = 10526880; colour = 10526880;
} }
WizardryUtilities.drawTexturedRect(this.xPosition, this.yPosition, k, l, this.width, this.height, 256, 256); WizardryUtilities.drawTexturedRect(this.x, this.y, k, l, this.width, this.height, 256, 256);
this.drawCenteredString(minecraft.fontRendererObj, this.displayString, this.xPosition + this.width / 2, this.yPosition + (this.height - 8) / 2, colour); this.drawCenteredString(minecraft.fontRenderer, this.displayString, this.x + this.width / 2,
} this.y + (this.height - 8) / 2, colour);
}
} }
@@ -8,16 +8,13 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
class GuiButtonInvisible extends GuiButton { class GuiButtonInvisible extends GuiButton {
public GuiButtonInvisible(int id, int x, int y, int width, int height){ public GuiButtonInvisible(int id, int x, int y, int width, int height){
super(id, x, y, width, height, "");
super(id, x, y, width, height, ""); }
}
@Override
public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
}
/**
* Draws this button to the screen.
*/
public void drawButton(Minecraft par1Minecraft, int par2, int par3){
this.hovered = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height;
}
} }
@@ -12,41 +12,36 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
class GuiButtonTurnPage extends GuiButton { class GuiButtonTurnPage extends GuiButton {
/** True for pointing right (next page), false for pointing left (previous page). */ /** True for pointing right (next page), false for pointing left (previous page). */
private final boolean nextPage; private final boolean nextPage;
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/gui/handbook.png");
public GuiButtonTurnPage(int id, int x, int y, boolean isNextPage) private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/gui/handbook.png");
{
super(id, x, y, 23, 13, "");
this.nextPage = isNextPage;
}
/** public GuiButtonTurnPage(int id, int x, int y, boolean isNextPage){
* Draws this button to the screen. super(id, x, y, 23, 13, "");
*/ this.nextPage = isNextPage;
public void drawButton(Minecraft par1Minecraft, int par2, int par3) }
{
if (this.visible)
{
boolean flag = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height;
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
par1Minecraft.getTextureManager().bindTexture(texture);
int k = 0;
int l = 192;
if (flag) @Override
{ public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
k += 23;
} if(this.visible){
boolean flag = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
minecraft.getTextureManager().bindTexture(texture);
int k = 0;
int l = 192;
if (!this.nextPage) if(flag){
{ k += 23;
l += 13; }
}
WizardryUtilities.drawTexturedRect(this.xPosition, this.yPosition, k, l, 23, 13, 288, 256); if(!this.nextPage){
} l += 13;
} }
WizardryUtilities.drawTexturedRect(this.x, this.y, k, l, 23, 13, 288, 256);
}
}
} }
@@ -18,63 +18,113 @@ import net.minecraftforge.fml.client.config.IConfigElement;
public class GuiConfigWizardry extends GuiConfig { public class GuiConfigWizardry extends GuiConfig {
public GuiConfigWizardry(GuiScreen parent){ public GuiConfigWizardry(GuiScreen parent){
super(parent, getConfigEntries(), Wizardry.MODID, false, false, Wizardry.NAME + " - " + I18n.format("config.wizardry.title.general")); super(parent, getConfigEntries(), Wizardry.MODID, false, false,
//this.titleLine2 = "File location: " + Wizardry.config.getConfigFile().getAbsolutePath(); Wizardry.NAME + " - " + I18n.format("config." + Wizardry.MODID + ".title.general"));
// this.titleLine2 = "File location: " + Wizardry.config.getConfigFile().getAbsolutePath();
} }
private static List<IConfigElement> getConfigEntries(){ private static List<IConfigElement> getConfigEntries(){
List<IConfigElement> configList = new ArrayList<IConfigElement>(1); List<IConfigElement> configList = new ArrayList<IConfigElement>(1);
configList.add(new DummyCategoryElement("spellsConfig", "config.wizardry.category." + Settings.SPELLS_CATEGORY, SpellsCategory.class));
configList.add(new DummyCategoryElement("resistancesConfig", "config.wizardry.category." + Settings.RESISTANCES_CATEGORY, ResistancesCategory.class)); configList.add(new DummyCategoryElement("gameplayConfig", "config." + Wizardry.MODID + ".category." + Settings.GAMEPLAY_CATEGORY, GameplayCategory.class));
configList.add(new DummyCategoryElement("worldgenConfig", "config." + Wizardry.MODID + ".category." + Settings.WORLDGEN_CATEGORY, WorldgenCategory.class));
configList.add(new DummyCategoryElement("commandsConfig", "config." + Wizardry.MODID + ".category." + Settings.COMMANDS_CATEGORY, CommandsCategory.class));
configList.add(new DummyCategoryElement("clientConfig", "config." + Wizardry.MODID + ".category." + Settings.CLIENT_CATEGORY, ClientCategory.class));
configList.add(new DummyCategoryElement("spellsConfig", "config." + Wizardry.MODID + ".category." + Settings.SPELLS_CATEGORY, SpellsCategory.class));
configList.add(new DummyCategoryElement("resistancesConfig", "config." + Wizardry.MODID + ".category." + Settings.RESISTANCES_CATEGORY, ResistancesCategory.class));
configList.addAll(new ConfigElement(Wizardry.settings.getConfigCategory(Configuration.CATEGORY_GENERAL)).getChildElements()); configList.addAll(new ConfigElement(Wizardry.settings.getConfigCategory(Configuration.CATEGORY_GENERAL)).getChildElements());
return configList; return configList;
} }
/** Spells category of the config gui. This adds a button which opens up the spells category config. */ // The reason this system is so convoluted is that it's designed for use with the @Config annotation. The problem is,
public static class SpellsCategory extends CategoryEntry // I'm not sure whether that will play well with the load phases. Hmmm...
{
public SpellsCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop) public static abstract class CategoryBase extends CategoryEntry {
{
super(owningScreen, owningEntryList, prop); public CategoryBase(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
} super(owningScreen, owningEntryList, prop);
}
@Override
protected GuiScreen buildChildScreen() @Override
{ protected GuiScreen buildChildScreen(){
// This GuiConfig object specifies the configID of the object and as such will force-save when it is closed.
// The parent GuiConfig object's entryList will also be refreshed to reflect the changes. String category = this.getCategory();
GuiConfig spellsMenu = new GuiConfig(this.owningScreen,
(new ConfigElement(Wizardry.settings.getConfigCategory(Settings.SPELLS_CATEGORY))).getChildElements(), // This GuiConfig object specifies the configID of the object and as such will force-save when it is closed.
this.owningScreen.modID, Settings.SPELLS_CATEGORY, false, false, // The parent GuiConfig object's entryList will also be refreshed to reflect the changes.
Wizardry.NAME + " - " + I18n.format("config.wizardry.title." + Settings.SPELLS_CATEGORY)); GuiConfig childScreen = new GuiConfig(this.owningScreen,
(new ConfigElement(Wizardry.settings.getConfigCategory(category))).getChildElements(),
spellsMenu.titleLine2 = I18n.format("config.wizardry.subtitle." + Settings.SPELLS_CATEGORY); this.owningScreen.modID, category, false, false,
Wizardry.NAME + " - " + I18n.format("config." + Wizardry.MODID + ".title." + category));
return spellsMenu;
} childScreen.titleLine2 = I18n.format("config." + Wizardry.MODID + ".subtitle." + category);
}
return childScreen;
/** Resistances category of the config gui. */ }
public static class ResistancesCategory extends CategoryEntry
{ protected abstract String getCategory();
public ResistancesCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop) }
{
super(owningScreen, owningEntryList, prop); /** Gameplay category of the config gui. */
} public static class GameplayCategory extends CategoryBase {
@Override public GameplayCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
protected GuiScreen buildChildScreen() super(owningScreen, owningEntryList, prop);
{ }
// This GuiConfig object specifies the configID of the object and as such will force-save when it is closed.
// The parent GuiConfig object's entryList will also be refreshed to reflect the changes. @Override protected String getCategory() { return Settings.GAMEPLAY_CATEGORY; }
GuiConfig idsMenu = new GuiConfig(this.owningScreen, }
(new ConfigElement(Wizardry.settings.getConfigCategory(Settings.RESISTANCES_CATEGORY))).getChildElements(),
this.owningScreen.modID, Settings.RESISTANCES_CATEGORY, false, false, /** Spells category of the config gui. */
Wizardry.NAME + " - " + I18n.format("config.wizardry.title." + Settings.RESISTANCES_CATEGORY)); public static class SpellsCategory extends CategoryBase {
idsMenu.titleLine2 = I18n.format("config.wizardry.subtitle." + Settings.RESISTANCES_CATEGORY); public SpellsCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
super(owningScreen, owningEntryList, prop);
return idsMenu; }
}
} @Override protected String getCategory() { return Settings.SPELLS_CATEGORY; }
}
/** Resistances category of the config gui. */
public static class ResistancesCategory extends CategoryBase {
public ResistancesCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
super(owningScreen, owningEntryList, prop);
}
@Override protected String getCategory() { return Settings.RESISTANCES_CATEGORY; }
}
/** Worldgen category of the config gui. */
public static class WorldgenCategory extends CategoryBase {
public WorldgenCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
super(owningScreen, owningEntryList, prop);
}
@Override protected String getCategory() { return Settings.WORLDGEN_CATEGORY; }
}
/** Client category of the config gui. */
public static class ClientCategory extends CategoryBase {
public ClientCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
super(owningScreen, owningEntryList, prop);
}
@Override protected String getCategory() { return Settings.CLIENT_CATEGORY; }
}
/** Commands category of the config gui. */
public static class CommandsCategory extends CategoryBase {
public CommandsCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
super(owningScreen, owningEntryList, prop);
}
@Override protected String getCategory() { return Settings.COMMANDS_CATEGORY; }
}
} }
@@ -11,29 +11,27 @@ import net.minecraft.world.World;
/** Crafting table GUI that doesn't require a crafting table container object. */ /** Crafting table GUI that doesn't require a crafting table container object. */
public class GuiPortableCrafting extends GuiContainer { public class GuiPortableCrafting extends GuiContainer {
private static final ResourceLocation craftingTableGuiTextures = new ResourceLocation("textures/gui/container/crafting_table.png");
public GuiPortableCrafting(InventoryPlayer p_i1084_1_, World p_i1084_2_, BlockPos pos)
{
super(new ContainerWorkbench(p_i1084_1_, p_i1084_2_, pos));
}
/** private static final ResourceLocation craftingTableGuiTextures = new ResourceLocation(
* Draw the foreground layer for the GuiContainer (everything in front of the items) "textures/gui/container/crafting_table.png");
*/
protected void drawGuiContainerForegroundLayer(int p_146979_1_, int p_146979_2_)
{
this.fontRendererObj.drawString(I18n.format("container.crafting"), 28, 6, 4210752);
this.fontRendererObj.drawString(I18n.format("container.inventory"), 8, this.ySize - 96 + 2, 4210752);
}
protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) public GuiPortableCrafting(InventoryPlayer p_i1084_1_, World p_i1084_2_, BlockPos pos){
{ super(new ContainerWorkbench(p_i1084_1_, p_i1084_2_, pos));
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); }
this.mc.getTextureManager().bindTexture(craftingTableGuiTextures);
int k = (this.width - this.xSize) / 2; /**
int l = (this.height - this.ySize) / 2; * Draw the foreground layer for the GuiContainer (everything in front of the items)
this.drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize); */
} protected void drawGuiContainerForegroundLayer(int p_146979_1_, int p_146979_2_){
this.fontRenderer.drawString(I18n.format("container.crafting"), 28, 6, 4210752);
this.fontRenderer.drawString(I18n.format("container.inventory"), 8, this.ySize - 96 + 2, 4210752);
}
protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_){
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.getTextureManager().bindTexture(craftingTableGuiTextures);
int k = (this.width - this.xSize) / 2;
int l = (this.height - this.ySize) / 2;
this.drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize);
}
} }
@@ -15,113 +15,98 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
public class GuiSpellBook extends GuiScreen { public class GuiSpellBook extends GuiScreen {
private int xSize, ySize; private int xSize, ySize;
private Spell spell; private Spell spell;
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/gui/spellbook.png"); private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/gui/spellbook.png");
public GuiSpellBook(Spell spell) { public GuiSpellBook(Spell spell){
super(); super();
xSize = 288; xSize = 288;
ySize = 180; ySize = 180;
this.spell = spell; this.spell = spell;
} }
/** /**
* Draws the screen and all the components in it. * Draws the screen and all the components in it.
*/ */
public void drawScreen(int par1, int par2, float par3) { public void drawScreen(int par1, int par2, float par3){
int xPos = this.width/2 - xSize/2; int xPos = this.width / 2 - xSize / 2;
int yPos = this.height/2 - this.ySize/2; int yPos = this.height / 2 - this.ySize / 2;
EntityPlayer player = Minecraft.getMinecraft().thePlayer; EntityPlayer player = Minecraft.getMinecraft().player;
boolean discovered = true; boolean discovered = true;
if(Wizardry.settings.discoveryMode && !player.capabilities.isCreativeMode && WizardData.get(player) != null if(Wizardry.settings.discoveryMode && !player.capabilities.isCreativeMode && WizardData.get(player) != null
&& !WizardData.get(player).hasSpellBeenDiscovered(spell)){ && !WizardData.get(player).hasSpellBeenDiscovered(spell)){
discovered = false; discovered = false;
} }
// Draws spell illustration on opposite page, underneath the book so it shows through the hole. // Draws spell illustration on opposite page, underneath the book so it shows through the hole.
Minecraft.getMinecraft().renderEngine.bindTexture(discovered ? spell.getIcon() : Spells.none.getIcon()); Minecraft.getMinecraft().renderEngine.bindTexture(discovered ? spell.getIcon() : Spells.none.getIcon());
WizardryUtilities.drawTexturedRect(xPos + 145, yPos + 20, 0, 0, 128, 128, 128, 128); WizardryUtilities.drawTexturedRect(xPos + 145, yPos + 20, 0, 0, 128, 128, 128, 128);
Minecraft.getMinecraft().renderEngine.bindTexture(texture); Minecraft.getMinecraft().renderEngine.bindTexture(texture);
WizardryUtilities.drawTexturedRect(xPos, yPos, 0, 0, xSize, ySize, xSize, 256); WizardryUtilities.drawTexturedRect(xPos, yPos, 0, 0, xSize, ySize, xSize, 256);
super.drawScreen(par1, par2, par3); super.drawScreen(par1, par2, par3);
if(discovered){ if(discovered){
this.fontRendererObj.drawString(spell.getDisplayName(), xPos+17, yPos+14, 0); this.fontRenderer.drawString(spell.getDisplayName(), xPos + 17, yPos + 14, 0);
this.fontRendererObj.drawString(spell.type.getDisplayName(), xPos+17, yPos+25, 0x777777); this.fontRenderer.drawString(spell.type.getDisplayName(), xPos + 17, yPos + 25, 0x777777);
}else{ }else{
this.mc.standardGalacticFontRenderer.drawString(SpellGlyphData.getGlyphName(spell, player.worldObj), xPos+17, yPos+14, 0); this.mc.standardGalacticFontRenderer.drawString(SpellGlyphData.getGlyphName(spell, player.world), xPos + 17,
this.mc.standardGalacticFontRenderer.drawString(spell.type.getDisplayName(), xPos+17, yPos+25, 0x777777); yPos + 14, 0);
this.mc.standardGalacticFontRenderer.drawString(spell.type.getDisplayName(), xPos + 17, yPos + 25,
0x777777);
} }
this.fontRendererObj.drawString("-------------------", xPos+17, yPos+34, 0);
if(spell.tier == Tier.BASIC){
// Basic is usually white but this doesn't show up.
this.fontRendererObj.drawString("Tier: \u00A77" + Tier.BASIC.getDisplayName(), xPos+17, yPos+44, 0);
}else{
this.fontRendererObj.drawString("Tier: " + spell.tier.getDisplayNameWithFormatting(), xPos+17, yPos+44, 0);
}
String element = "Element: " + spell.element.getFormattingCode() + spell.element.getDisplayName();
if(!discovered) element = "Element: ?";
this.fontRendererObj.drawString(element, xPos+17, yPos+56, 0);
String manaCost = "Mana Cost: " + spell.cost;
if(spell.isContinuous) manaCost = "Mana Cost: " + spell.cost + "/second";
if(!discovered) manaCost = "Mana Cost: ?";
this.fontRendererObj.drawString(manaCost, xPos+17, yPos+68, 0);
if(discovered){
this.fontRendererObj.drawSplitString(spell.getDescription(), xPos+17, yPos+82, 118, 0);
}else{
this.mc.standardGalacticFontRenderer.drawSplitString(SpellGlyphData.getGlyphDescription(spell, player.worldObj), xPos+17, yPos+82, 118, 0);
}
/*
// Word wrapping
int charNumber = 0;
int lineNumber = 0;
while(charNumber < spell.desc.length()){
int lineLength = 0;
String line;
if(spell.desc.length() - charNumber > 22){
for(int i = charNumber; i < charNumber+23; i++){
if(spell.desc.charAt(i) == ' '){
lineLength = i - charNumber;
}
}
line = spell.desc.substring(charNumber, charNumber + lineLength);
}else{
line = spell.desc.substring(charNumber, spell.desc.length());
charNumber = spell.desc.length();
}
this.fontRendererObj.drawString("\u00A7o" + line, xPos+17, yPos+82+10*lineNumber, 0);
charNumber+=(lineLength+1);
lineNumber++;
}
*/
}
public void initGui() this.fontRenderer.drawString("-------------------", xPos + 17, yPos + 34, 0);
{
if(spell.tier == Tier.BASIC){
// Basic is usually white but this doesn't show up.
this.fontRenderer.drawString("Tier: \u00A77" + Tier.BASIC.getDisplayName(), xPos + 17, yPos + 44, 0);
}else{
this.fontRenderer.drawString("Tier: " + spell.tier.getDisplayNameWithFormatting(), xPos + 17, yPos + 44,
0);
}
String element = "Element: " + spell.element.getFormattingCode() + spell.element.getDisplayName();
if(!discovered) element = "Element: ?";
this.fontRenderer.drawString(element, xPos + 17, yPos + 56, 0);
String manaCost = "Mana Cost: " + spell.cost;
if(spell.isContinuous) manaCost = "Mana Cost: " + spell.cost + "/second";
if(!discovered) manaCost = "Mana Cost: ?";
this.fontRenderer.drawString(manaCost, xPos + 17, yPos + 68, 0);
if(discovered){
this.fontRenderer.drawSplitString(spell.getDescription(), xPos + 17, yPos + 82, 118, 0);
}else{
this.mc.standardGalacticFontRenderer.drawSplitString(
SpellGlyphData.getGlyphDescription(spell, player.world), xPos + 17, yPos + 82, 118, 0);
}
/* // Word wrapping int charNumber = 0; int lineNumber = 0;
*
* while(charNumber < spell.desc.length()){ int lineLength = 0; String line; if(spell.desc.length() - charNumber
* > 22){ for(int i = charNumber; i < charNumber+23; i++){ if(spell.desc.charAt(i) == ' '){ lineLength = i -
* charNumber; } } line = spell.desc.substring(charNumber, charNumber + lineLength); }else{ line =
* spell.desc.substring(charNumber, spell.desc.length()); charNumber = spell.desc.length(); }
* this.fontRendererObj.drawString("\u00A7o" + line, xPos+17, yPos+82+10*lineNumber, 0);
* charNumber+=(lineLength+1); lineNumber++; } */
}
public void initGui(){
super.initGui(); super.initGui();
Keyboard.enableRepeatEvents(true); Keyboard.enableRepeatEvents(true);
this.buttonList.clear(); this.buttonList.clear();
} }
public void onGuiClosed()
{
super.onGuiClosed();
Keyboard.enableRepeatEvents(false);
}
}
public void onGuiClosed(){
super.onGuiClosed();
Keyboard.enableRepeatEvents(false);
}
}
@@ -32,7 +32,7 @@ public class GuiSpellDisplay extends Gui {
private static final ResourceLocation hudTexture = new ResourceLocation(Wizardry.MODID, "textures/gui/spell_hud.png"); private static final ResourceLocation hudTexture = new ResourceLocation(Wizardry.MODID, "textures/gui/spell_hud.png");
public GuiSpellDisplay(Minecraft par1Minecraft) { public GuiSpellDisplay(Minecraft par1Minecraft){
super(); super();
this.mc = par1Minecraft; this.mc = par1Minecraft;
} }
@@ -40,16 +40,16 @@ public class GuiSpellDisplay extends Gui {
@SubscribeEvent @SubscribeEvent
public void draw(RenderGameOverlayEvent event){ public void draw(RenderGameOverlayEvent event){
EntityPlayer player = this.mc.thePlayer; EntityPlayer player = this.mc.player;
// If the player has a wand in each hand, only displays for the one in the main hand. // If the player has a wand in each hand, only displays for the one in the main hand.
ItemStack wand = player.getHeldItemMainhand(); ItemStack wand = player.getHeldItemMainhand();
if(wand == null || !(wand.getItem() instanceof ItemWand)){ if(!(wand.getItem() instanceof ItemWand)){
wand = player.getHeldItemOffhand(); wand = player.getHeldItemOffhand();
// If the player isn't holding a wand, then nothing else needs to be done. // If the player isn't holding a wand, then nothing else needs to be done.
if(wand == null || !(wand.getItem() instanceof ItemWand)) return; if(!(wand.getItem() instanceof ItemWand)) return;
} }
int width = event.getResolution().getScaledWidth(); int width = event.getResolution().getScaledWidth();
@@ -58,7 +58,7 @@ public class GuiSpellDisplay extends Gui {
Spell spell = WandHelper.getCurrentSpell(wand); Spell spell = WandHelper.getCurrentSpell(wand);
int cooldown = WandHelper.getCurrentCooldown(wand); int cooldown = WandHelper.getCurrentCooldown(wand);
float cooldownMultiplier = 1.0f - WandHelper.getUpgradeLevel(wand, WizardryItems.cooldown_upgrade)*Constants.COOLDOWN_REDUCTION_PER_LEVEL; float cooldownMultiplier = 1.0f - WandHelper.getUpgradeLevel(wand, WizardryItems.cooldown_upgrade) * Constants.COOLDOWN_REDUCTION_PER_LEVEL;
if(player.isPotionActive(WizardryPotions.font_of_mana)){ if(player.isPotionActive(WizardryPotions.font_of_mana)){
// Dividing by this rather than setting it takes upgrades and font of mana into account simultaneously // Dividing by this rather than setting it takes upgrades and font of mana into account simultaneously
@@ -72,17 +72,17 @@ public class GuiSpellDisplay extends Gui {
if(Wizardry.settings.spellHUDPosition == GuiPosition.BOTTOM_LEFT){ if(Wizardry.settings.spellHUDPosition == GuiPosition.BOTTOM_LEFT){
left = 0; left = 0;
top = height-36; top = height - 36;
}else if(Wizardry.settings.spellHUDPosition == GuiPosition.TOP_LEFT){ }else if(Wizardry.settings.spellHUDPosition == GuiPosition.TOP_LEFT){
left = 0; left = 0;
top = 0; top = 0;
}else if(Wizardry.settings.spellHUDPosition == GuiPosition.TOP_RIGHT){ }else if(Wizardry.settings.spellHUDPosition == GuiPosition.TOP_RIGHT){
left = width-128; left = width - 128;
top = 0; top = 0;
mirror = true; mirror = true;
}else if(Wizardry.settings.spellHUDPosition == GuiPosition.BOTTOM_RIGHT){ }else if(Wizardry.settings.spellHUDPosition == GuiPosition.BOTTOM_RIGHT){
left = width-128; left = width - 128;
top = height-36; top = height - 36;
mirror = true; mirror = true;
} }
@@ -97,14 +97,14 @@ public class GuiSpellDisplay extends Gui {
// Makes spells greyed out if they are in cooldown or if the player has the arcane jammer effect // Makes spells greyed out if they are in cooldown or if the player has the arcane jammer effect
String colour = cooldown > 0 || player.isPotionActive(WizardryPotions.arcane_jammer) ? "\u00A78" : spell.element.getFormattingCode(); String colour = cooldown > 0 || player.isPotionActive(WizardryPotions.arcane_jammer) ? "\u00A78" : spell.element.getFormattingCode();
if(!discovered) colour = "\u00A79"; if(!discovered) colour = "\u00A79";
String spellName = discovered ? spell.getDisplayName() : SpellGlyphData.getGlyphName(spell, player.worldObj); String spellName = discovered ? spell.getDisplayName() : SpellGlyphData.getGlyphName(spell, player.world);
FontRenderer font = discovered ? this.mc.fontRendererObj : this.mc.standardGalacticFontRenderer; FontRenderer font = discovered ? this.mc.fontRenderer : this.mc.standardGalacticFontRenderer;
int maxWidth = 90; int maxWidth = 90;
if(font.getStringWidth(spellName) <= maxWidth){ if(font.getStringWidth(spellName) <= maxWidth){
// Single line is rendered more centrally // Single line is rendered more centrally
font.drawStringWithShadow(colour + spellName, mirror ? left+5 : left+41, top+13, 0xffffffff); font.drawStringWithShadow(colour + spellName, mirror ? left + 5 : left + 41, top + 13, 0xffffffff);
}else{ }else{
@@ -114,20 +114,18 @@ public class GuiSpellDisplay extends Gui {
for(Object line : lines){ for(Object line : lines){
if(line instanceof String){ if(line instanceof String){
font.drawStringWithShadow(colour + (String)line, mirror ? left+5 : left+41, top+6 + 11*lineNumber, 0xffffffff); font.drawStringWithShadow(colour + (String)line, mirror ? left + 5 : left + 41, top + 6 + 11 * lineNumber, 0xffffffff);
} }
lineNumber++; lineNumber++;
} }
} }
}else if(event.getType() == RenderGameOverlayEvent.ElementType.HOTBAR){ }else if(event.getType() == RenderGameOverlayEvent.ElementType.HOTBAR){
GlStateManager.pushAttrib();
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA); GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
GlStateManager.color(1, 1, 1); GlStateManager.color(1, 1, 1);
this.mc.renderEngine.bindTexture(hudTexture); this.mc.renderEngine.bindTexture(hudTexture);
// Background of spell hud // Background of spell hud
@@ -135,20 +133,19 @@ public class GuiSpellDisplay extends Gui {
// Cooldown bar // Cooldown bar
if(cooldown > 0){ if(cooldown > 0){
this.drawTexturedModalRect(mirror ? left+5 : left+41, height-8, 128, 6, 82, 6); this.drawTexturedModalRect(mirror ? left + 5 : left + 41, top + 28, 128, 6, 82, 6);
int l = (int)(((double)(spell.cooldown * cooldownMultiplier - cooldown) int l = (int)(((double)(spell.cooldown * cooldownMultiplier - cooldown) / (double)(spell.cooldown * cooldownMultiplier)) * 82);
/ (double)(spell.cooldown * cooldownMultiplier)) * 82);
this.drawTexturedModalRect(mirror ? left+5 : left+41, height-8, 128, 0, l, 6); this.drawTexturedModalRect(mirror ? left + 5 : left + 41, top + 28, 128, 0, l, 6);
} }
// Spell illustration // Spell illustration
this.mc.renderEngine.bindTexture(discovered ? spell.getIcon() : Spells.none.getIcon()); this.mc.renderEngine.bindTexture(discovered ? spell.getIcon() : Spells.none.getIcon());
WizardryUtilities.drawTexturedRect(mirror ? left+94 : left+2, top+2, 0, 0, 32, 32, 32, 32); WizardryUtilities.drawTexturedRect(mirror ? left + 94 : left + 2, top + 2, 0, 0, 32, 32, 32, 32);
GlStateManager.popAttrib(); // Blend needs to be left enabled here because otherwise the hotbar becomes opaque
} }
} }
File diff suppressed because it is too large Load Diff
@@ -8,87 +8,91 @@ import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
/** Font renderer that renders parts of strings surrounded by '#' (without quotes) in the SGA instead of normal text. /**
* @since Wizardry 1.1 */ * Font renderer that renders parts of strings surrounded by '#' (without quotes) in the SGA instead of normal text.
*
* @since Wizardry 1.1
*/
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class MixedFontRenderer extends FontRenderer { public class MixedFontRenderer extends FontRenderer {
public MixedFontRenderer(GameSettings p_i1035_1_, ResourceLocation p_i1035_2_, TextureManager p_i1035_3_, public MixedFontRenderer(GameSettings p_i1035_1_, ResourceLocation p_i1035_2_, TextureManager p_i1035_3_,
boolean p_i1035_4_) { boolean p_i1035_4_){
super(p_i1035_1_, p_i1035_2_, p_i1035_3_, p_i1035_4_); super(p_i1035_1_, p_i1035_2_, p_i1035_3_, p_i1035_4_);
} }
@Override @Override
public int drawString(String string, float x, float y, int colour, boolean shadow){ public int drawString(String string, float x, float y, int colour, boolean shadow){
int l = 0; int l = 0;
boolean sga = false; boolean sga = false;
while(string.indexOf('#') > -1){ while(string.indexOf('#') > -1){
String section = string.substring(0, string.indexOf('#')); String section = string.substring(0, string.indexOf('#'));
if(sga){ if(sga){
l += Minecraft.getMinecraft().standardGalacticFontRenderer.drawString(section, x, y, colour, shadow); l += Minecraft.getMinecraft().standardGalacticFontRenderer.drawString(section, x, y, colour, shadow);
x += Minecraft.getMinecraft().standardGalacticFontRenderer.getStringWidth(section); x += Minecraft.getMinecraft().standardGalacticFontRenderer.getStringWidth(section);
}else{ }else{
l += Minecraft.getMinecraft().fontRendererObj.drawString(section, x, y, colour, shadow); l += Minecraft.getMinecraft().fontRenderer.drawString(section, x, y, colour, shadow);
x += Minecraft.getMinecraft().fontRendererObj.getStringWidth(section); x += Minecraft.getMinecraft().fontRenderer.getStringWidth(section);
} }
string = string.substring(string.indexOf('#') + 1); string = string.substring(string.indexOf('#') + 1);
sga = !sga; sga = !sga;
} }
if(sga){ if(sga){
l += Minecraft.getMinecraft().standardGalacticFontRenderer.drawString(string, x, y, colour, shadow); l += Minecraft.getMinecraft().standardGalacticFontRenderer.drawString(string, x, y, colour, shadow);
}else{ }else{
l += Minecraft.getMinecraft().fontRendererObj.drawString(string, x, y, colour, shadow); l += Minecraft.getMinecraft().fontRenderer.drawString(string, x, y, colour, shadow);
} }
return l; return l;
} }
@Override @Override
public int getStringWidth(String string){ public int getStringWidth(String string){
int l = 0; int l = 0;
boolean sga = false; boolean sga = false;
while(string.indexOf('#') > -1){ while(string.indexOf('#') > -1){
String section = string.substring(0, string.indexOf('#')); String section = string.substring(0, string.indexOf('#'));
if(sga){ if(sga){
l += Minecraft.getMinecraft().standardGalacticFontRenderer.getStringWidth(section); l += Minecraft.getMinecraft().standardGalacticFontRenderer.getStringWidth(section);
}else{ }else{
l += Minecraft.getMinecraft().fontRendererObj.getStringWidth(section); l += Minecraft.getMinecraft().fontRenderer.getStringWidth(section);
} }
string = string.substring(string.indexOf('#') + 1); string = string.substring(string.indexOf('#') + 1);
sga = !sga; sga = !sga;
} }
if(sga){ if(sga){
l += Minecraft.getMinecraft().standardGalacticFontRenderer.getStringWidth(string); l += Minecraft.getMinecraft().standardGalacticFontRenderer.getStringWidth(string);
}else{ }else{
l += Minecraft.getMinecraft().fontRendererObj.getStringWidth(string); l += Minecraft.getMinecraft().fontRenderer.getStringWidth(string);
} }
return l; return l;
} }
// This doesn't work the same way yet // This doesn't work the same way yet
@Override @Override
public void drawSplitString(String string, int x, int y, int width, int colour){ public void drawSplitString(String string, int x, int y, int width, int colour){
if(string.contains("#")){ if(string.contains("#")){
Minecraft.getMinecraft().standardGalacticFontRenderer.drawSplitString(string.substring(1), x, y, width, colour); Minecraft.getMinecraft().standardGalacticFontRenderer.drawSplitString(string.substring(1), x, y, width,
}else{ colour);
Minecraft.getMinecraft().fontRendererObj.drawSplitString(string, x, y, width, colour); }else{
} Minecraft.getMinecraft().fontRenderer.drawSplitString(string, x, y, width, colour);
} }
}
} }
@@ -10,50 +10,43 @@ import net.minecraftforge.fml.relauncher.SideOnly;
// Copied from MovingSoundMinecart; if it ever breaks between updates take a look at that. // Copied from MovingSoundMinecart; if it ever breaks between updates take a look at that.
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class MovingSoundEntity extends MovingSound public class MovingSoundEntity extends MovingSound {
{ private final Entity source;
private final Entity source; private float distance = 0.0F;
private float distance = 0.0F;
public MovingSoundEntity(Entity entity, SoundEvent sound, float volume, float pitch, boolean repeat) public MovingSoundEntity(Entity entity, SoundEvent sound, float volume, float pitch, boolean repeat){
{ // Uses BLOCKS because that's the closest thing to inanimate entities. Could use NEUTRAL like
// Uses BLOCKS because that's the closest thing to inanimate entities. Could use NEUTRAL like MovingSoundMinecart. // MovingSoundMinecart.
super(sound, SoundCategory.BLOCKS); super(sound, SoundCategory.BLOCKS);
this.source = entity; this.source = entity;
this.repeat = repeat; this.repeat = repeat;
this.volume = volume; this.volume = volume;
this.pitch = pitch; this.pitch = pitch;
this.repeatDelay = 0; this.repeatDelay = 0;
} }
/** /**
* Updates the JList with a new model. * Updates the JList with a new model.
*/ */
@Override @Override
public void update() public void update(){
{ if(this.source.isDead && repeat){
if (this.source.isDead && repeat) this.donePlaying = true;
{ }else{
this.donePlaying = true; this.xPosF = (float)this.source.posX;
} this.yPosF = (float)this.source.posY;
else this.zPosF = (float)this.source.posZ;
{ float f = MathHelper.sqrt(this.source.motionX * this.source.motionX
this.xPosF = (float)this.source.posX; + this.source.motionY * this.source.motionY + this.source.motionZ * this.source.motionZ);
this.yPosF = (float)this.source.posY;
this.zPosF = (float)this.source.posZ;
float f = MathHelper.sqrt_double(this.source.motionX * this.source.motionX + this.source.motionY * this.source.motionY + this.source.motionZ * this.source.motionZ);
// Is this something to do with the Doppler effect? // Is this something to do with the Doppler effect?
if ((double)f >= 0.01D) if((double)f >= 0.01D){
{ this.distance = MathHelper.clamp(this.distance + 0.0025F, 0.0F, 1.0F);
this.distance = MathHelper.clamp_float(this.distance + 0.0025F, 0.0F, 1.0F); this.volume = 0.0F + MathHelper.clamp(f, 0.0F, 0.5F) * 0.7F;
this.volume = 0.0F + MathHelper.clamp_float(f, 0.0F, 0.5F) * 0.7F; }else{
} // this.pitch = 0.0F;
else // this.volume = 0.0F;
{ }
//this.pitch = 0.0F; }
//this.volume = 0.0F; }
}
}
}
} }
@@ -9,6 +9,7 @@ import electroblob.wizardry.item.ItemSpectralBow;
import electroblob.wizardry.item.ItemWand; import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.packet.PacketControlInput; import electroblob.wizardry.packet.PacketControlInput;
import electroblob.wizardry.packet.WizardryPacketHandler; import electroblob.wizardry.packet.WizardryPacketHandler;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryPotions; import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.spell.Flight; import electroblob.wizardry.spell.Flight;
import electroblob.wizardry.spell.ShadowWard; import electroblob.wizardry.spell.ShadowWard;
@@ -17,18 +18,26 @@ import electroblob.wizardry.tileentity.ContainerArcaneWorkbench;
import electroblob.wizardry.util.WandHelper; import electroblob.wizardry.util.WandHelper;
import electroblob.wizardry.util.WizardryUtilities; import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiMerchant;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityArmorStand;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.village.MerchantRecipe;
import net.minecraftforge.client.event.FOVUpdateEvent; import net.minecraftforge.client.event.FOVUpdateEvent;
import net.minecraftforge.client.event.GuiContainerEvent;
import net.minecraftforge.client.event.MouseEvent; import net.minecraftforge.client.event.MouseEvent;
import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.client.event.RenderLivingEvent; import net.minecraftforge.client.event.RenderLivingEvent;
@@ -39,12 +48,15 @@ import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
/** /**
* Event handler responsible for all client-side only events, mostly rendering. * Event handler responsible for all client-side only events, mostly rendering.
*
* @author Electroblob * @author Electroblob
* @since Wizardry 1.0 * @since Wizardry 1.0
*/ */
@SideOnly(Side.CLIENT)
@Mod.EventBusSubscriber(Side.CLIENT) @Mod.EventBusSubscriber(Side.CLIENT)
public final class WizardryClientEventHandler { public final class WizardryClientEventHandler {
@@ -66,17 +78,17 @@ public final class WizardryClientEventHandler {
// Shift-scrolling to change spells // Shift-scrolling to change spells
@SubscribeEvent @SubscribeEvent
public static void onMouseEvent(MouseEvent event){ public static void onMouseEvent(MouseEvent event){
EntityPlayer player = Minecraft.getMinecraft().thePlayer; EntityPlayer player = Minecraft.getMinecraft().player;
ItemStack wand = player.getHeldItemMainhand(); ItemStack wand = player.getHeldItemMainhand();
if(wand == null || !(wand.getItem() instanceof ItemWand)){ if(!(wand.getItem() instanceof ItemWand)){
wand = player.getHeldItemOffhand(); wand = player.getHeldItemOffhand();
// If the player isn't holding a wand, then nothing else needs to be done. // If the player isn't holding a wand, then nothing else needs to be done.
if(wand == null || !(wand.getItem() instanceof ItemWand)) return; if(!(wand.getItem() instanceof ItemWand)) return;
} }
if(Minecraft.getMinecraft().inGameHasFocus && wand != null && event.getDwheel() != 0 && player.isSneaking() if(Minecraft.getMinecraft().inGameHasFocus && !wand.isEmpty() && event.getDwheel() != 0 && player.isSneaking()
&& Wizardry.settings.enableShiftScrolling){ && Wizardry.settings.enableShiftScrolling){
event.setCanceled(true); event.setCanceled(true);
@@ -98,21 +110,74 @@ public final class WizardryClientEventHandler {
public static void onFOVUpdateEvent(FOVUpdateEvent event){ public static void onFOVUpdateEvent(FOVUpdateEvent event){
// Bow zoom. Taken directly from AbstractClientPlayer so it works exactly like vanilla. // Bow zoom. Taken directly from AbstractClientPlayer so it works exactly like vanilla.
if(event.getEntity().isHandActive() && event.getEntity().getActiveItemStack() != null if(event.getEntity().isHandActive() && event.getEntity().getActiveItemStack().getItem() instanceof ItemSpectralBow){
&& event.getEntity().getActiveItemStack().getItem() instanceof ItemSpectralBow){
int maxUseTicks = event.getEntity().getItemInUseMaxCount();
float maxUseSeconds = (float)maxUseTicks / 20.0F;
if(maxUseSeconds > 1.0F){
maxUseSeconds = 1.0F;
}else{
maxUseSeconds = maxUseSeconds * maxUseSeconds;
}
event.setNewfov(event.getFov() * 1.0F - maxUseSeconds * 0.15F);
}
}
// Brute-force fix for crystals not showing up when a wizard is given a spell book in the trade GUI.
@SubscribeEvent
public static void onGuiDrawForegroundEvent(GuiContainerEvent.DrawForeground event){
if(event.getGuiContainer() instanceof GuiMerchant){
int maxUseTicks = event.getEntity().getItemInUseMaxCount(); GuiMerchant gui = (GuiMerchant)event.getGuiContainer();
// Note that gui.getMerchant() returns an NpcMerchant, not an EntityWizard.
float maxUseSeconds = (float)maxUseTicks / 20.0F;
// Using == the specific item rather than instanceof because that's how trades do it.
if(gui.inventorySlots.getSlot(0).getStack().getItem() == WizardryItems.spell_book
|| gui.inventorySlots.getSlot(1).getStack().getItem() == WizardryItems.spell_book){
for(MerchantRecipe trade : gui.getMerchant().getRecipes(Minecraft.getMinecraft().player)){
if(trade.getItemToBuy().getItem() == WizardryItems.spell_book && trade.getSecondItemToBuy().isEmpty()){
Slot slot = gui.inventorySlots.getSlot(2);
// Uses reflection to draw the itemstack
// It still doesn't look quite right because the slot highlight is behind the item, but it'll do
// until/unless I find a better solution.
renderItemAndTooltip(gui, trade.getItemToSell(), slot.xPos, slot.yPos, event.getMouseX(), event.getMouseY(),
gui.getSlotUnderMouse() == slot);
}
}
}
}
}
private static void renderItemAndTooltip(GuiContainer gui, ItemStack stack, int x, int y, int mouseX, int mouseY, boolean tooltip){
if(maxUseSeconds > 1.0F){ RenderItem renderItem = Minecraft.getMinecraft().getRenderItem();
maxUseSeconds = 1.0F; GlStateManager.pushMatrix();
}else{ RenderHelper.enableGUIStandardItemLighting();
maxUseSeconds = maxUseSeconds * maxUseSeconds; GlStateManager.disableLighting();
} GlStateManager.enableRescaleNormal();
GlStateManager.enableColorMaterial();
GlStateManager.enableLighting();
renderItem.zLevel = 100.0F;
event.setNewfov(event.getFov() * 1.0F - maxUseSeconds * 0.15F); if(!stack.isEmpty()){
} renderItem.renderItemAndEffectIntoGUI(stack, x, y);
renderItem.renderItemOverlays(Minecraft.getMinecraft().fontRenderer, stack, x, y);
if(tooltip){
gui.drawHoveringText(gui.getItemToolTip(stack), mouseX + gui.getXSize()/2 - gui.width/2,
mouseY + gui.getYSize()/2 - gui.height/2);
}
}
GlStateManager.popMatrix();
GlStateManager.enableLighting();
GlStateManager.enableDepth();
RenderHelper.enableStandardItemLighting();
} }
// Third person // Third person
@@ -128,128 +193,31 @@ public final class WizardryClientEventHandler {
public static void onRenderWorldLastEvent(RenderWorldLastEvent event){ public static void onRenderWorldLastEvent(RenderWorldLastEvent event){
// Now only fires in first person. // Now only fires in first person.
if(Minecraft.getMinecraft().gameSettings.thirdPersonView == 0){ if(Minecraft.getMinecraft().gameSettings.thirdPersonView == 0){
renderShieldFirstPerson(Minecraft.getMinecraft().thePlayer); renderShieldFirstPerson(Minecraft.getMinecraft().player);
renderShadowWardFirstPerson(Minecraft.getMinecraft().thePlayer); renderShadowWardFirstPerson(Minecraft.getMinecraft().player);
} }
} }
@SubscribeEvent @SubscribeEvent
public static void onRenderLivingEvent(RenderLivingEvent.Post<EntityLivingBase> event){ public static void onRenderLivingEvent(RenderLivingEvent.Post<EntityLivingBase> event){
/*
// Frost effect
if(event.entity.isPotionActive(Wizardry.frost)){
GlStateManager.pushMatrix();
GL11.glDisable(GL11.GL_TEXTURE_2D);
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
float someScalingFactor = 0.0625f;
float yaw = event.entity.prevRotationYaw;
//int brightness = event.entity.getBrightnessForRender(0);
//int j = brightness % 65536;
//int k = brightness / 65536;
//OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)j / 1.0F, (float)k / 1.0F);
//GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
GlStateManager.translate(event.x, event.y, event.z);
GlStateManager.rotate(-yaw + 180, 0F, 1F, 0F);
Render render = renderManager.getEntityRenderObject(event.entity);
RenderLiving renderliving = event.renderer;
// Reflection
try {
Timer timer = ReflectionHelper.getPrivateValue(Minecraft.class, Minecraft.getMinecraft(), "timer");
// Chooses the appropriate zombie model, normal or villager
// Fixed by moving before the model fields are accessed
if(render instanceof RenderZombie && event.entity instanceof EntityZombie){
// The second argument is never used...
ReflectionHelper.findMethod(RenderZombie.class, (RenderZombie)render, new String[]{"func_82427_a"}, EntityZombie.class)
.invoke(renderliving, (EntityZombie)event.entity);
}
// Turns out that java automatically infers the type parameter T in this method from the type
// I am assigning the returned value to. Neat!
ModelBase mainModel = ReflectionHelper.getPrivateValue(RenderLiving.class, renderliving, "mainModel");
mainModel.isRiding = event.entity.isRiding();
mainModel.isChild = event.entity.isChild();
GlStateManager.enableRescaleNormal();
GlStateManager.scale(-1.0F, -1.0F, 1.0F);
// The second argument is never used...
ReflectionHelper.findMethod(RenderLiving.class, renderliving, new String[]{"preRenderCallback"}, EntityLivingBase.class, float.class)
.invoke(renderliving, event.entity, someScalingFactor);
// Why is this -1.5f? No idea!
GlStateManager.translate(0, -1.5f, 0);
float f6 = event.entity.prevLimbSwingAmount + (event.entity.limbSwingAmount - event.entity.prevLimbSwingAmount) * timer.renderPartialTicks;
float f7 = event.entity.limbSwing - event.entity.limbSwingAmount * (1.0F - timer.renderPartialTicks);
if (event.entity.isChild())
{
f7 *= 3.0F;
}
if (f6 > 1.0F)
{
f6 = 1.0F;
}
mainModel.setLivingAnimations(event.entity, f7, f6, timer.renderPartialTicks);
GlStateManager.enableAlpha();
GlStateManager.color(0.5f, 0.7f, 1, 0.5f);
mainModel.render(event.entity, f7, f6, 0, 0, 0, someScalingFactor);
GL11.glDepthMask(true);
// 'Pokemon' exception handling... Because why not?!
} catch (Exception e) {
System.err.println("Something went very wrong! Error while rendering frost effect:");
e.printStackTrace();
}
GlStateManager.disableAlpha();
GlStateManager.disableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GlStateManager.disableRescaleNormal();
GL11.glEnable(GL11.GL_TEXTURE_2D);
GlStateManager.popMatrix();
}
*/
Minecraft mc = Minecraft.getMinecraft(); Minecraft mc = Minecraft.getMinecraft();
WizardData properties = WizardData.get(mc.thePlayer); WizardData properties = WizardData.get(mc.player);
RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(mc.theWorld, mc.thePlayer, 16); RayTraceResult rayTrace = WizardryUtilities.standardEntityRayTrace(mc.world, mc.player, 16);
RenderManager renderManager = event.getRenderer().getRenderManager(); RenderManager renderManager = event.getRenderer().getRenderManager();
ItemStack wand = mc.thePlayer.getHeldItemMainhand();
if(wand == null || !(wand.getItem() instanceof ItemWand)){ ItemStack wand = mc.player.getHeldItemMainhand();
wand = mc.thePlayer.getHeldItemOffhand();
if(!(wand.getItem() instanceof ItemWand)){
wand = mc.player.getHeldItemOffhand();
} }
// Target selection pointer // Target selection pointer
if(mc.thePlayer.isSneaking() && wand != null && wand.getItem() instanceof ItemWand && rayTrace != null if(mc.player.isSneaking() && wand.getItem() instanceof ItemWand && rayTrace != null && !(event.getEntity() instanceof EntityArmorStand)
&& rayTrace.entityHit instanceof EntityLivingBase && rayTrace.entityHit == event.getEntity() && rayTrace.entityHit == event.getEntity() && properties != null && properties.selectedMinion != null){
&& properties != null && properties.selectedMinion != null){
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
@@ -257,7 +225,7 @@ public final class WizardryClientEventHandler {
GlStateManager.disableLighting(); GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
// Disabling depth test allows it to be seen through everything. // Disabling depth test allows it to be seen through everything.
GL11.glDisable(GL11.GL_DEPTH_TEST); GlStateManager.disableDepth();
GlStateManager.color(1, 1, 1, 1); GlStateManager.color(1, 1, 1, 1);
GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height + 0.5, event.getZ()); GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height + 0.5, event.getZ());
@@ -273,24 +241,24 @@ public final class WizardryClientEventHandler {
mc.renderEngine.bindTexture(targetPointerTexture); mc.renderEngine.bindTexture(targetPointerTexture);
buffer.pos(-0.2, 0.24, 0).tex(0, 0).endVertex(); buffer.pos(-0.2, 0.24, 0).tex(0, 0).endVertex();
buffer.pos(0.2, 0.24, 0).tex(9f/16f, 0).endVertex(); buffer.pos(0.2, 0.24, 0).tex(9f / 16f, 0).endVertex();
buffer.pos(0.2, -0.24, 0).tex(9f/16f, 11f/16f).endVertex(); buffer.pos(0.2, -0.24, 0).tex(9f / 16f, 11f / 16f).endVertex();
buffer.pos(-0.2, -0.24, 0).tex(0, 11f/16f).endVertex(); buffer.pos(-0.2, -0.24, 0).tex(0, 11f / 16f).endVertex();
tessellator.draw(); tessellator.draw();
GlStateManager.enableCull(); GlStateManager.enableCull();
GlStateManager.enableLighting(); GlStateManager.enableLighting();
GL11.glEnable(GL11.GL_DEPTH_TEST); GlStateManager.enableDepth();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
// Summoned creature selection pointer // Summoned creature selection pointer
if(properties != null && properties.selectedMinion != null && properties.selectedMinion.get() == event.getEntity()){ if(properties != null && properties.selectedMinion != null && properties.selectedMinion.get() == event.getEntity()){
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
@@ -298,7 +266,7 @@ public final class WizardryClientEventHandler {
GlStateManager.disableLighting(); GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
// Disabling depth test allows it to be seen through everything. // Disabling depth test allows it to be seen through everything.
GL11.glDisable(GL11.GL_DEPTH_TEST); GlStateManager.disableDepth();
GlStateManager.color(1, 1, 1, 1); GlStateManager.color(1, 1, 1, 1);
GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height + 0.5, event.getZ()); GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height + 0.5, event.getZ());
@@ -314,26 +282,26 @@ public final class WizardryClientEventHandler {
mc.renderEngine.bindTexture(pointerTexture); mc.renderEngine.bindTexture(pointerTexture);
buffer.pos(-0.2, 0.24, 0).tex(0, 0).endVertex(); buffer.pos(-0.2, 0.24, 0).tex(0, 0).endVertex();
buffer.pos(0.2, 0.24, 0).tex(9f/16f, 0).endVertex(); buffer.pos(0.2, 0.24, 0).tex(9f / 16f, 0).endVertex();
buffer.pos(0.2, -0.24, 0).tex(9f/16f, 11f/16f).endVertex(); buffer.pos(0.2, -0.24, 0).tex(9f / 16f, 11f / 16f).endVertex();
buffer.pos(-0.2, -0.24, 0).tex(0, 11f/16f).endVertex(); buffer.pos(-0.2, -0.24, 0).tex(0, 11f / 16f).endVertex();
tessellator.draw(); tessellator.draw();
GlStateManager.enableCull(); GlStateManager.enableCull();
GlStateManager.enableLighting(); GlStateManager.enableLighting();
GL11.glEnable(GL11.GL_DEPTH_TEST); GlStateManager.enableDepth();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
// Sixth sense // Sixth sense
if(mc.thePlayer.isPotionActive(WizardryPotions.sixth_sense) && event.getEntity() != mc.thePlayer if(mc.player.isPotionActive(WizardryPotions.sixth_sense) && !(event.getEntity() instanceof EntityArmorStand) && event.getEntity() != mc.player
&& mc.thePlayer.getActivePotionEffect(WizardryPotions.sixth_sense) != null && mc.player.getActivePotionEffect(WizardryPotions.sixth_sense) != null && event.getEntity().getDistance(mc.player) < 20
&& event.getEntity().getDistanceToEntity(mc.thePlayer) < 20*(1+mc.thePlayer.getActivePotionEffect(WizardryPotions.sixth_sense).getAmplifier()*Constants.RANGE_INCREASE_PER_LEVEL)){ * (1 + mc.player.getActivePotionEffect(WizardryPotions.sixth_sense).getAmplifier() * Constants.RANGE_INCREASE_PER_LEVEL)){
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
@@ -343,7 +311,7 @@ public final class WizardryClientEventHandler {
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
// Disabling depth test allows it to be seen through everything. // Disabling depth test allows it to be seen through everything.
GL11.glDisable(GL11.GL_DEPTH_TEST); GlStateManager.disableDepth();
GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height * 0.6, event.getZ()); GlStateManager.translate(event.getX(), event.getY() + event.getEntity().height * 0.6, event.getZ());
@@ -367,7 +335,7 @@ public final class WizardryClientEventHandler {
GlStateManager.enableCull(); GlStateManager.enableCull();
GlStateManager.disableBlend(); GlStateManager.disableBlend();
GlStateManager.enableLighting(); GlStateManager.enableLighting();
GL11.glEnable(GL11.GL_DEPTH_TEST); GlStateManager.enableDepth();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
@@ -375,61 +343,62 @@ public final class WizardryClientEventHandler {
@SubscribeEvent @SubscribeEvent
public static void onRenderGameOverlayEvent(RenderGameOverlayEvent.Post event){ public static void onRenderGameOverlayEvent(RenderGameOverlayEvent.Post event){
if(event.getType() == RenderGameOverlayEvent.ElementType.HELMET if(event.getType() == RenderGameOverlayEvent.ElementType.HELMET
&& Minecraft.getMinecraft().thePlayer.isPotionActive(WizardryPotions.sixth_sense)){ && Minecraft.getMinecraft().player.isPotionActive(WizardryPotions.sixth_sense)){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GL11.glDisable(GL11.GL_DEPTH_TEST); GlStateManager.disableDepth();
GL11.glDepthMask(false); GlStateManager.depthMask(false);
OpenGlHelper.glBlendFunc(770, 771, 1, 0); OpenGlHelper.glBlendFunc(770, 771, 1, 0);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
GlStateManager.disableAlpha(); GlStateManager.disableAlpha();
Minecraft.getMinecraft().renderEngine.bindTexture(sixthSenseOverlayTexture); Minecraft.getMinecraft().renderEngine.bindTexture(sixthSenseOverlayTexture);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(0.0D, (double)event.getResolution().getScaledHeight(), -90.0D).tex(0.0D, 1.0D).endVertex(); buffer.pos(0.0D, (double)event.getResolution().getScaledHeight(), -90.0D).tex(0.0D, 1.0D).endVertex();
buffer.pos((double)event.getResolution().getScaledWidth(), (double)event.getResolution().getScaledHeight(), -90.0D).tex(1.0D, 1.0D).endVertex(); buffer.pos((double)event.getResolution().getScaledWidth(), (double)event.getResolution().getScaledHeight(), -90.0D).tex(1.0D, 1.0D)
.endVertex();
buffer.pos((double)event.getResolution().getScaledWidth(), 0.0D, -90.0D).tex(1.0D, 0.0D).endVertex(); buffer.pos((double)event.getResolution().getScaledWidth(), 0.0D, -90.0D).tex(1.0D, 0.0D).endVertex();
buffer.pos(0.0D, 0.0D, -90.0D).tex(0.0D, 0.0D).endVertex(); buffer.pos(0.0D, 0.0D, -90.0D).tex(0.0D, 0.0D).endVertex();
tessellator.draw(); tessellator.draw();
GL11.glDepthMask(true); GlStateManager.depthMask(true);
GL11.glEnable(GL11.GL_DEPTH_TEST); GlStateManager.enableDepth();
GlStateManager.enableAlpha(); GlStateManager.enableAlpha();
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
if(event.getType() == RenderGameOverlayEvent.ElementType.HELMET if(event.getType() == RenderGameOverlayEvent.ElementType.HELMET && Minecraft.getMinecraft().player.isPotionActive(WizardryPotions.frost)){
&& Minecraft.getMinecraft().thePlayer.isPotionActive(WizardryPotions.frost)){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GL11.glDisable(GL11.GL_DEPTH_TEST); GlStateManager.disableDepth();
GL11.glDepthMask(false); GlStateManager.depthMask(false);
OpenGlHelper.glBlendFunc(770, 771, 1, 0); OpenGlHelper.glBlendFunc(770, 771, 1, 0);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
GlStateManager.disableAlpha(); GlStateManager.disableAlpha();
Minecraft.getMinecraft().renderEngine.bindTexture(frostOverlayTexture); Minecraft.getMinecraft().renderEngine.bindTexture(frostOverlayTexture);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(0.0D, (double)event.getResolution().getScaledHeight(), -90.0D).tex(0.0D, 1.0D).endVertex(); buffer.pos(0.0D, (double)event.getResolution().getScaledHeight(), -90.0D).tex(0.0D, 1.0D).endVertex();
buffer.pos((double)event.getResolution().getScaledWidth(), (double)event.getResolution().getScaledHeight(), -90.0D).tex(1.0D, 1.0D).endVertex(); buffer.pos((double)event.getResolution().getScaledWidth(), (double)event.getResolution().getScaledHeight(), -90.0D).tex(1.0D, 1.0D)
.endVertex();
buffer.pos((double)event.getResolution().getScaledWidth(), 0.0D, -90.0D).tex(1.0D, 0.0D).endVertex(); buffer.pos((double)event.getResolution().getScaledWidth(), 0.0D, -90.0D).tex(1.0D, 0.0D).endVertex();
buffer.pos(0.0D, 0.0D, -90.0D).tex(0.0D, 0.0D).endVertex(); buffer.pos(0.0D, 0.0D, -90.0D).tex(0.0D, 0.0D).endVertex();
tessellator.draw(); tessellator.draw();
GL11.glDepthMask(true); GlStateManager.depthMask(true);
GL11.glEnable(GL11.GL_DEPTH_TEST); GlStateManager.enableDepth();
GlStateManager.enableAlpha(); GlStateManager.enableAlpha();
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
@@ -440,8 +409,9 @@ public final class WizardryClientEventHandler {
// FIXME: Something in here is making the first person shadow ward rather translucent. // FIXME: Something in here is making the first person shadow ward rather translucent.
private static void renderShadowWardFirstPerson(EntityPlayer entityplayer){ private static void renderShadowWardFirstPerson(EntityPlayer entityplayer){
ItemStack wand = entityplayer.getActiveItemStack(); ItemStack wand = entityplayer.getActiveItemStack();
if(WizardData.get(entityplayer) != null && WizardData.get(entityplayer).currentlyCasting() instanceof ShadowWard || (entityplayer.isHandActive() && wand != null && wand.getItemDamage() < wand.getMaxDamage() if(WizardData.get(entityplayer) != null && WizardData.get(entityplayer).currentlyCasting() instanceof ShadowWard
&& wand.getItem() instanceof ItemWand && WandHelper.getCurrentSpell(wand) instanceof ShadowWard)){ || (entityplayer.isHandActive() && wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand
&& WandHelper.getCurrentSpell(wand) instanceof ShadowWard)){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
@@ -455,18 +425,18 @@ public final class WizardryClientEventHandler {
GlStateManager.translate(0, 1.2, 0); GlStateManager.translate(0, 1.2, 0);
GlStateManager.rotate(-entityplayer.rotationYaw, 0, 1, 0); GlStateManager.rotate(-entityplayer.rotationYaw, 0, 1, 0);
GlStateManager.rotate(entityplayer.rotationPitch, 1, 0, 0); GlStateManager.rotate(entityplayer.rotationPitch, 1, 0, 0);
Minecraft.getMinecraft().renderEngine.bindTexture(shadowWardTexture); Minecraft.getMinecraft().renderEngine.bindTexture(shadowWardTexture);
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.translate(0, 0, 1.2); GlStateManager.translate(0, 0, 1.2);
GlStateManager.rotate(entityplayer.worldObj.getWorldTime()*-2, 0, 0, 1); GlStateManager.rotate(entityplayer.world.getWorldTime() * -2, 0, 0, 1);
GlStateManager.scale(1.1, 1.1, 1.1); GlStateManager.scale(1.1, 1.1, 1.1);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-0.5, 0.5, -0.5).tex(0, 0).endVertex(); buffer.pos(-0.5, 0.5, -0.5).tex(0, 0).endVertex();
@@ -498,8 +468,9 @@ public final class WizardryClientEventHandler {
private static void renderShadowWardIfActive(EntityPlayer entityplayer){ private static void renderShadowWardIfActive(EntityPlayer entityplayer){
ItemStack wand = entityplayer.getActiveItemStack(); ItemStack wand = entityplayer.getActiveItemStack();
if(WizardData.get(entityplayer).currentlyCasting() instanceof ShadowWard || (entityplayer.isHandActive() && wand != null if(WizardData.get(entityplayer).currentlyCasting() instanceof ShadowWard
&& wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand && WandHelper.getCurrentSpell(wand) instanceof ShadowWard)){ || (entityplayer.isHandActive() && wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand
&& WandHelper.getCurrentSpell(wand) instanceof ShadowWard)){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
@@ -510,14 +481,14 @@ public final class WizardryClientEventHandler {
GlStateManager.rotate(180, 0, 1, 0); GlStateManager.rotate(180, 0, 1, 0);
GlStateManager.rotate(-entityplayer.renderYawOffset, 0, 1, 0); GlStateManager.rotate(-entityplayer.renderYawOffset, 0, 1, 0);
Minecraft.getMinecraft().renderEngine.bindTexture(shadowWardTexture); Minecraft.getMinecraft().renderEngine.bindTexture(shadowWardTexture);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
GlStateManager.translate(0, 1.2, 0); GlStateManager.translate(0, 1.2, 0);
GlStateManager.rotate(entityplayer.worldObj.getWorldTime()*-2, 0, 0, 1); GlStateManager.rotate(entityplayer.world.getWorldTime() * -2, 0, 0, 1);
GlStateManager.scale(1.1, 1.1, 1.1); GlStateManager.scale(1.1, 1.1, 1.1);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
@@ -548,8 +519,9 @@ public final class WizardryClientEventHandler {
private static void renderWingsIfActive(EntityPlayer entityplayer, float partialTickTime){ private static void renderWingsIfActive(EntityPlayer entityplayer, float partialTickTime){
ItemStack wand = entityplayer.getActiveItemStack(); ItemStack wand = entityplayer.getActiveItemStack();
if(WizardData.get(entityplayer).currentlyCasting() instanceof Flight || (entityplayer.isHandActive() && wand != null if(WizardData.get(entityplayer).currentlyCasting() instanceof Flight
&& wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand && WandHelper.getCurrentSpell(wand) instanceof Flight)){ || (entityplayer.isHandActive() && wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand
&& WandHelper.getCurrentSpell(wand) instanceof Flight)){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
@@ -558,18 +530,18 @@ public final class WizardryClientEventHandler {
GlStateManager.disableLighting(); GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
//GlStateManager.rotate(-entityplayer.rotationYawHead, 0, 1, 0); // GlStateManager.rotate(-entityplayer.rotationYawHead, 0, 1, 0);
GlStateManager.rotate(-entityplayer.renderYawOffset, 0, 1, 0); GlStateManager.rotate(-entityplayer.renderYawOffset, 0, 1, 0);
//GlStateManager.rotate(180, 1, 0, 0); // GlStateManager.rotate(180, 1, 0, 0);
Minecraft.getMinecraft().renderEngine.bindTexture(wingTexture); Minecraft.getMinecraft().renderEngine.bindTexture(wingTexture);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.translate(0.1, 0.4, -0.15); GlStateManager.translate(0.1, 0.4, -0.15);
GlStateManager.rotate(20 + 20*(float)Math.sin(entityplayer.worldObj.getWorldTime()*0.3), 0, 1, 0); GlStateManager.rotate(20 + 20 * (float)Math.sin(entityplayer.world.getWorldTime() * 0.3), 0, 1, 0);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
@@ -594,7 +566,7 @@ public final class WizardryClientEventHandler {
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.translate(-0.1, 0.4, -0.15); GlStateManager.translate(-0.1, 0.4, -0.15);
GlStateManager.rotate(-200 - 20*(float)Math.sin(entityplayer.worldObj.getWorldTime()*0.3), 0, 1, 0); GlStateManager.rotate(-200 - 20 * (float)Math.sin(entityplayer.world.getWorldTime() * 0.3), 0, 1, 0);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
@@ -625,8 +597,10 @@ public final class WizardryClientEventHandler {
private static void renderShieldFirstPerson(EntityPlayer entityplayer){ private static void renderShieldFirstPerson(EntityPlayer entityplayer){
ItemStack wand = entityplayer.getActiveItemStack(); ItemStack wand = entityplayer.getActiveItemStack();
if(WizardData.get(entityplayer) != null && WizardData.get(entityplayer).shield != null && (WizardData.get(entityplayer).currentlyCasting() instanceof Shield || (entityplayer.isHandActive() && wand != null if(WizardData.get(entityplayer) != null && WizardData.get(entityplayer).shield != null
&& wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand && WandHelper.getCurrentSpell(wand) instanceof Shield))){ && (WizardData.get(entityplayer).currentlyCasting() instanceof Shield
|| (entityplayer.isHandActive() && wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand
&& WandHelper.getCurrentSpell(wand) instanceof Shield))){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
@@ -649,13 +623,13 @@ public final class WizardryClientEventHandler {
Minecraft.getMinecraft().renderEngine.bindTexture(shieldTexture); Minecraft.getMinecraft().renderEngine.bindTexture(shieldTexture);
renderShield(tessellator); renderShield(tessellator);
GlStateManager.enableLighting(); GlStateManager.enableLighting();
GlStateManager.shadeModel(GL11.GL_FLAT); GlStateManager.shadeModel(GL11.GL_FLAT);
GlStateManager.enableCull(); GlStateManager.enableCull();
GlStateManager.disableBlend(); GlStateManager.disableBlend();
//RenderHelper.enableStandardItemLighting(); // RenderHelper.enableStandardItemLighting();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
@@ -663,8 +637,9 @@ public final class WizardryClientEventHandler {
private static void renderShieldIfActive(EntityPlayer entityplayer){ private static void renderShieldIfActive(EntityPlayer entityplayer){
ItemStack wand = entityplayer.getActiveItemStack(); ItemStack wand = entityplayer.getActiveItemStack();
if(WizardData.get(entityplayer).shield != null && (WizardData.get(entityplayer).currentlyCasting() instanceof Shield || (entityplayer.isHandActive() && wand != null if(WizardData.get(entityplayer).shield != null && (WizardData.get(entityplayer).currentlyCasting() instanceof Shield
&& wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand && WandHelper.getCurrentSpell(wand) instanceof Shield))){ || (entityplayer.isHandActive() && wand.getItemDamage() < wand.getMaxDamage() && wand.getItem() instanceof ItemWand
&& WandHelper.getCurrentSpell(wand) instanceof Shield))){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
@@ -679,9 +654,9 @@ public final class WizardryClientEventHandler {
GlStateManager.translate(0, 1.3, 0); GlStateManager.translate(0, 1.3, 0);
//GlStateManager.rotate(180, 0, 1, 0); // GlStateManager.rotate(180, 0, 1, 0);
GlStateManager.rotate(-entityplayer.renderYawOffset, 0, 1, 0); GlStateManager.rotate(-entityplayer.renderYawOffset, 0, 1, 0);
//GlStateManager.rotate(-entityplayer.rotationPitch, 1, 0, 0); // GlStateManager.rotate(-entityplayer.rotationPitch, 1, 0, 0);
GlStateManager.translate(0, 0, 0.8); GlStateManager.translate(0, 0, 0.8);
@@ -696,7 +671,7 @@ public final class WizardryClientEventHandler {
GlStateManager.shadeModel(GL11.GL_FLAT); GlStateManager.shadeModel(GL11.GL_FLAT);
GlStateManager.enableCull(); GlStateManager.enableCull();
GlStateManager.disableBlend(); GlStateManager.disableBlend();
//RenderHelper.enableStandardItemLighting(); // RenderHelper.enableStandardItemLighting();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
@@ -704,7 +679,7 @@ public final class WizardryClientEventHandler {
private static void renderShield(Tessellator tessellator){ private static void renderShield(Tessellator tessellator){
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
double widthOuter = 0.6d; double widthOuter = 0.6d;
double heightOuter = 0.7d; double heightOuter = 0.7d;
@@ -4,80 +4,75 @@ import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer; import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
public class ModelHammer extends ModelBase public class ModelHammer extends ModelBase {
{ ModelRenderer Shape1;
ModelRenderer Shape1; ModelRenderer Shape2;
ModelRenderer Shape2; ModelRenderer Shape3;
ModelRenderer Shape3; ModelRenderer Shape4;
ModelRenderer Shape4; ModelRenderer Shape5;
ModelRenderer Shape5; ModelRenderer Shape6;
ModelRenderer Shape6;
public ModelHammer(){
public ModelHammer() textureWidth = 64;
{ textureHeight = 64;
textureWidth = 64;
textureHeight = 64; Shape1 = new ModelRenderer(this, 0, 0);
Shape1.addBox(0F, 0F, 0F, 20, 12, 12);
Shape1 = new ModelRenderer(this, 0, 0); Shape1.setRotationPoint(-10F, 12F, -6F);
Shape1.addBox(0F, 0F, 0F, 20, 12, 12); Shape1.setTextureSize(64, 64);
Shape1.setRotationPoint(-10F, 12F, -6F); Shape1.mirror = true;
Shape1.setTextureSize(64, 64); setRotation(Shape1, 0F, 0F, 0F);
Shape1.mirror = true; Shape2 = new ModelRenderer(this, 0, 24);
setRotation(Shape1, 0F, 0F, 0F); Shape2.addBox(0F, 0F, 0F, 4, 14, 4);
Shape2 = new ModelRenderer(this, 0, 24); Shape2.setRotationPoint(-2F, -2F, -2F);
Shape2.addBox(0F, 0F, 0F, 4, 14, 4); Shape2.setTextureSize(64, 64);
Shape2.setRotationPoint(-2F, -2F, -2F); Shape2.mirror = true;
Shape2.setTextureSize(64, 64); setRotation(Shape2, 0F, 0F, 0F);
Shape2.mirror = true; Shape3 = new ModelRenderer(this, 0, 49);
setRotation(Shape2, 0F, 0F, 0F); Shape3.addBox(0F, 0F, 0F, 5, 5, 5);
Shape3 = new ModelRenderer(this, 0, 49); Shape3.setRotationPoint(-2.5F, -7F, -2.5F);
Shape3.addBox(0F, 0F, 0F, 5, 5, 5); Shape3.setTextureSize(64, 64);
Shape3.setRotationPoint(-2.5F, -7F, -2.5F); Shape3.mirror = true;
Shape3.setTextureSize(64, 64); setRotation(Shape3, 0F, 0F, 0F);
Shape3.mirror = true; Shape4 = new ModelRenderer(this, 0, 42);
setRotation(Shape3, 0F, 0F, 0F); Shape4.addBox(0F, 0F, 0F, 5, 2, 5);
Shape4 = new ModelRenderer(this, 0, 42); Shape4.setRotationPoint(-2.5F, 10F, -2.5F);
Shape4.addBox(0F, 0F, 0F, 5, 2, 5); Shape4.setTextureSize(64, 64);
Shape4.setRotationPoint(-2.5F, 10F, -2.5F); Shape4.mirror = true;
Shape4.setTextureSize(64, 64); setRotation(Shape4, 0F, 0F, 0F);
Shape4.mirror = true; Shape5 = new ModelRenderer(this, 20, 24);
setRotation(Shape4, 0F, 0F, 0F); Shape5.addBox(0F, 0F, 0F, 2, 14, 14);
Shape5 = new ModelRenderer(this, 20, 24); Shape5.setRotationPoint(-8F, 11F, -7F);
Shape5.addBox(0F, 0F, 0F, 2, 14, 14); Shape5.setTextureSize(64, 64);
Shape5.setRotationPoint(-8F, 11F, -7F); Shape5.mirror = true;
Shape5.setTextureSize(64, 64); setRotation(Shape5, 0F, 0F, 0F);
Shape5.mirror = true; Shape6 = new ModelRenderer(this, 20, 24);
setRotation(Shape5, 0F, 0F, 0F); Shape6.addBox(0F, 0F, 0F, 2, 14, 14);
Shape6 = new ModelRenderer(this, 20, 24); Shape6.setRotationPoint(6F, 11F, -7F);
Shape6.addBox(0F, 0F, 0F, 2, 14, 14); Shape6.setTextureSize(64, 64);
Shape6.setRotationPoint(6F, 11F, -7F); Shape6.mirror = true;
Shape6.setTextureSize(64, 64); setRotation(Shape6, 0F, 0F, 0F);
Shape6.mirror = true; }
setRotation(Shape6, 0F, 0F, 0F);
} public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5){
super.render(entity, f, f1, f2, f3, f4, f5);
public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) setRotationAngles(f, f1, f2, f3, f4, f5, entity);
{ Shape1.render(f5);
super.render(entity, f, f1, f2, f3, f4, f5); Shape2.render(f5);
setRotationAngles(f, f1, f2, f3, f4, f5, entity); Shape3.render(f5);
Shape1.render(f5); Shape4.render(f5);
Shape2.render(f5); Shape5.render(f5);
Shape3.render(f5); Shape6.render(f5);
Shape4.render(f5); }
Shape5.render(f5);
Shape6.render(f5); private void setRotation(ModelRenderer model, float x, float y, float z){
} model.rotateAngleX = x;
model.rotateAngleY = y;
private void setRotation(ModelRenderer model, float x, float y, float z) model.rotateAngleZ = z;
{ }
model.rotateAngleX = x;
model.rotateAngleY = y; public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity){
model.rotateAngleZ = z; super.setRotationAngles(f, f1, f2, f3, f4, f5, entity);
} }
public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity)
{
super.setRotationAngles(f, f1, f2, f3, f4, f5, entity);
}
} }
@@ -13,309 +13,299 @@ import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ModelIceGiant extends ModelBase public class ModelIceGiant extends ModelBase {
{ /** The head model for the iron golem. */
/** The head model for the iron golem. */ public ModelRenderer iceGiantHead;
public ModelRenderer iceGiantHead;
/** The body model for the iron golem. */ /** The body model for the iron golem. */
public ModelRenderer iceGiantBody; public ModelRenderer iceGiantBody;
/** The right arm model for the iron golem. */ /** The right arm model for the iron golem. */
public ModelRenderer iceGiantRightArm; public ModelRenderer iceGiantRightArm;
/** The left arm model for the iron golem. */ /** The left arm model for the iron golem. */
public ModelRenderer iceGiantLeftArm; public ModelRenderer iceGiantLeftArm;
/** The left leg model for the Iron Golem. */ /** The left leg model for the Iron Golem. */
public ModelRenderer iceGiantLeftLeg; public ModelRenderer iceGiantLeftLeg;
/** The right leg model for the Iron Golem. */ /** The right leg model for the Iron Golem. */
public ModelRenderer iceGiantRightLeg; public ModelRenderer iceGiantRightLeg;
ModelRenderer headSpike1;
ModelRenderer headSpike2;
ModelRenderer headSpike3;
ModelRenderer headSpike4;
ModelRenderer headSpike5;
ModelRenderer headSpike6;
ModelRenderer headSpike7;
ModelRenderer rightArmSpike1;
ModelRenderer rightArmSpike2;
ModelRenderer leftArmSpike1;
ModelRenderer leftArmSpike2;
ModelRenderer bodySpike1;
ModelRenderer bodySpike2;
ModelRenderer bodySpike3;
ModelRenderer bodySpike4;
ModelRenderer bodySpike5;
public ModelIceGiant() ModelRenderer headSpike1;
{ ModelRenderer headSpike2;
this(0.0F); ModelRenderer headSpike3;
} ModelRenderer headSpike4;
ModelRenderer headSpike5;
ModelRenderer headSpike6;
ModelRenderer headSpike7;
ModelRenderer rightArmSpike1;
ModelRenderer rightArmSpike2;
ModelRenderer leftArmSpike1;
ModelRenderer leftArmSpike2;
ModelRenderer bodySpike1;
ModelRenderer bodySpike2;
ModelRenderer bodySpike3;
ModelRenderer bodySpike4;
ModelRenderer bodySpike5;
public ModelIceGiant(float par1) public ModelIceGiant(){
{ this(0.0F);
this(par1, -7.0F); }
}
public ModelIceGiant(float par1, float par2) public ModelIceGiant(float par1){
{ this(par1, -7.0F);
short short1 = 128; }
short short2 = 128;
this.iceGiantHead = (new ModelRenderer(this)).setTextureSize(short1, short2);
this.iceGiantHead.setRotationPoint(0.0F, 0.0F + par2, -1.0F);
this.iceGiantHead.setTextureOffset(0, 10).addBox(-6.0F, -14.0F, -6.5F, 12, 12, 12, par1);
this.iceGiantBody = (new ModelRenderer(this)).setTextureSize(short1, short2);
this.iceGiantBody.setRotationPoint(0.0F, 0.0F + par2, 0.0F);
this.iceGiantBody.setTextureOffset(0, 40).addBox(-9.0F, -2.0F, -6.0F, 18, 12, 11, par1);
this.iceGiantBody.setTextureOffset(0, 70).addBox(-4.5F, 10.0F, -3.0F, 9, 5, 6, par1 + 0.5F);
this.iceGiantRightArm = (new ModelRenderer(this)).setTextureSize(short1, short2);
this.iceGiantRightArm.setRotationPoint(0.0F, -7.0F, 0.0F);
this.iceGiantRightArm.setTextureOffset(60, 21).addBox(-13.0F, -2.5F, -3.0F, 4, 30, 6, par1);
this.iceGiantLeftArm = (new ModelRenderer(this)).setTextureSize(short1, short2);
this.iceGiantLeftArm.setRotationPoint(0.0F, -7.0F, 0.0F);
this.iceGiantLeftArm.setTextureOffset(60, 58).addBox(9.0F, -2.5F, -3.0F, 4, 30, 6, par1);
this.iceGiantLeftLeg = (new ModelRenderer(this, 0, 22)).setTextureSize(short1, short2);
this.iceGiantLeftLeg.setRotationPoint(-4.0F, 18.0F + par2, 0.0F);
this.iceGiantLeftLeg.setTextureOffset(37, 0).addBox(-3.5F, -3.0F, -3.0F, 6, 16, 5, par1);
this.iceGiantRightLeg = (new ModelRenderer(this, 0, 22)).setTextureSize(short1, short2);
this.iceGiantRightLeg.mirror = true;
this.iceGiantRightLeg.setTextureOffset(60, 0).setRotationPoint(5.0F, 18.0F + par2, 0.0F);
this.iceGiantRightLeg.addBox(-3.5F, -3.0F, -3.0F, 6, 16, 5, par1);
headSpike1 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
headSpike1.addBox(-4F, -4F, 0F, 4, 4, 4);
headSpike1.setRotationPoint(-4F, -10F, -5F);
headSpike1.mirror = true;
setRotationWithEulerYzx(headSpike1, -0.1047198F, -0.5235988F, 0.9599311F);
headSpike2 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
headSpike2.addBox(0F, -4F, 0F, 4, 4, 4);
headSpike2.setRotationPoint(4F, -16F, 0F);
headSpike2.mirror = true;
setRotationWithEulerYzx(headSpike2, 0.5585054F, 0.9250245F, -0.5235988F);
headSpike3 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
headSpike3.addBox(-2F, -2F, -2F, 4, 4, 4);
headSpike3.setRotationPoint(4F, -13F, 4F);
headSpike3.mirror = true;
setRotationWithEulerYzx(headSpike3, 0.7853982F, -1.396263F, 0.7853982F);
headSpike4 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
headSpike4.addBox(-4F, -4F, 0F, 4, 4, 4);
headSpike4.setRotationPoint(-4F, -16F, 0F);
headSpike4.mirror = true;
setRotationWithEulerYzx(headSpike4, 0.5585054F, -0.9250245F, 0.5235988F);
headSpike5 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
headSpike5.addBox(0F, -4F, 0F, 4, 4, 4);
headSpike5.setRotationPoint(4F, -10F, -5F);
headSpike5.mirror = true;
setRotationWithEulerYzx(headSpike5, 0.5235988F, -0.9599311F, 0.1047198F);
rightArmSpike1 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
rightArmSpike1.addBox(-2F, -2F, -2F, 4, 4, 4);
rightArmSpike1.setRotationPoint(-11F, -8F, 0F);
rightArmSpike1.mirror = true;
setRotationWithEulerYzx(rightArmSpike1, 0.7853982F, 1.134464F, 0.9599311F);
headSpike6 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
headSpike6.addBox(-2F, -2F, -2F, 4, 4, 4);
headSpike6.setRotationPoint(-4F, -13F, 4F);
headSpike6.mirror = true;
setRotationWithEulerYzx(headSpike6, 0.7853982F, -1.745329F, 0.7853982F);
leftArmSpike1 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
leftArmSpike1.addBox(-2F, -2F, -2F, 4, 4, 4);
leftArmSpike1.setRotationPoint(11F, -8F, 0F);
leftArmSpike1.mirror = true;
setRotationWithEulerYzx(leftArmSpike1, 0.7853982F, -1.134464F, -0.9599311F);
leftArmSpike2 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
leftArmSpike2.addBox(-2F, -2F, -2F, 4, 4, 4);
leftArmSpike2.setRotationPoint(12F, -4F, 0F);
leftArmSpike2.mirror = true;
setRotationWithEulerYzx(leftArmSpike2, 0.7853982F, 0F, -0.9599311F);
bodySpike1 = new ModelRenderer(this, 32, 69).setTextureSize(short1, short2);
bodySpike1.addBox(-3F, -3F, -3F, 6, 6, 6);
bodySpike1.setRotationPoint(-4F, -4F, 3F);
bodySpike1.mirror = true;
setRotationWithEulerYzx(bodySpike1, 0.2808018F, 0.8096675F, 0.8339369F);
rightArmSpike2 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
rightArmSpike2.addBox(-2F, -2F, -2F, 4, 4, 4);
rightArmSpike2.setRotationPoint(-12F, -4F, 0F);
rightArmSpike2.mirror = true;
setRotationWithEulerYzx(rightArmSpike2, 0.7853982F, 0F, 0.9599311F);
bodySpike2 = new ModelRenderer(this, 32, 69).setTextureSize(short1, short2);
bodySpike2.addBox(-3F, -3F, -3F, 6, 6, 6);
bodySpike2.setRotationPoint(4F, -4F, 3F);
bodySpike2.mirror = true;
setRotationWithEulerYzx(bodySpike2, 0.2808018F, -0.8096757F, -0.8339358F);
bodySpike3 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
bodySpike3.addBox(-2F, -2F, -2F, 4, 4, 4);
bodySpike3.setRotationPoint(6F, -2F, -5F);
bodySpike3.mirror = true;
setRotationWithEulerYzx(bodySpike3, 1.120006F, -1.347726F, -0.8969422F);
bodySpike4 = new ModelRenderer(this, 32, 69).setTextureSize(short1, short2);
bodySpike4.addBox(-3F, -3F, -3F, 6, 6, 6);
bodySpike4.setRotationPoint(0F, -4F, -4F);
bodySpike4.mirror = true;
setRotationWithEulerYzx(bodySpike4, 0.7853982F, -1.570796F, 0.9599311F);
headSpike7 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
headSpike7.addBox(-2F, -2F, -2F, 4, 4, 4);
headSpike7.setRotationPoint(0F, -20F, 4F);
headSpike7.mirror = true;
setRotationWithEulerYzx(headSpike7, 0.7853982F, 1.570796F, 0.7853982F);
bodySpike5 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
bodySpike5.addBox(-2F, -2F, -2F, 4, 4, 4);
bodySpike5.setRotationPoint(-6F, -2F, -5F);
bodySpike5.mirror = true;
setRotationWithEulerYzx(bodySpike5, 1.120006F, 1.347725F, 0.896934F);
this.convertToChild(this.iceGiantHead, headSpike1);
this.convertToChild(this.iceGiantHead, headSpike2);
this.convertToChild(this.iceGiantHead, headSpike3);
this.convertToChild(this.iceGiantHead, headSpike4);
this.convertToChild(this.iceGiantHead, headSpike5);
this.convertToChild(this.iceGiantHead, headSpike6);
this.convertToChild(this.iceGiantHead, headSpike7);
this.convertToChild(this.iceGiantRightArm, rightArmSpike1);
this.convertToChild(this.iceGiantRightArm, rightArmSpike2);
this.convertToChild(this.iceGiantLeftArm, leftArmSpike1);
this.convertToChild(this.iceGiantLeftArm, leftArmSpike2);
this.convertToChild(this.iceGiantBody, bodySpike1);
this.convertToChild(this.iceGiantBody, bodySpike2);
this.convertToChild(this.iceGiantBody, bodySpike3);
this.convertToChild(this.iceGiantBody, bodySpike4);
this.convertToChild(this.iceGiantBody, bodySpike5);
}
/** public ModelIceGiant(float par1, float par2){
* Sets the models various rotation angles then renders the model. short short1 = 128;
*/ short short2 = 128;
public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7)
{
this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity);
this.iceGiantHead.render(par7);
this.iceGiantBody.render(par7);
this.iceGiantLeftLeg.render(par7);
this.iceGiantRightLeg.render(par7);
this.iceGiantRightArm.render(par7);
this.iceGiantLeftArm.render(par7);
}
/** this.iceGiantHead = (new ModelRenderer(this)).setTextureSize(short1, short2);
* Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms this.iceGiantHead.setRotationPoint(0.0F, 0.0F + par2, -1.0F);
* and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how this.iceGiantHead.setTextureOffset(0, 10).addBox(-6.0F, -14.0F, -6.5F, 12, 12, 12, par1);
* "far" arms and legs can swing at most.
*/
public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6, Entity par7Entity)
{
this.iceGiantHead.rotateAngleY = par4 / (180F / (float)Math.PI);
this.iceGiantHead.rotateAngleX = par5 / (180F / (float)Math.PI);
this.iceGiantLeftLeg.rotateAngleX = -1.5F * this.func_78172_a(par1, 13.0F) * par2;
this.iceGiantRightLeg.rotateAngleX = 1.5F * this.func_78172_a(par1, 13.0F) * par2;
this.iceGiantLeftLeg.rotateAngleY = 0.0F;
this.iceGiantRightLeg.rotateAngleY = 0.0F;
}
/** this.iceGiantBody = (new ModelRenderer(this)).setTextureSize(short1, short2);
* Used for easily adding entity-dependent animations. The second and third float params here are the same second this.iceGiantBody.setRotationPoint(0.0F, 0.0F + par2, 0.0F);
* and third as in the setRotationAngles method. this.iceGiantBody.setTextureOffset(0, 40).addBox(-9.0F, -2.0F, -6.0F, 18, 12, 11, par1);
*/ this.iceGiantBody.setTextureOffset(0, 70).addBox(-4.5F, 10.0F, -3.0F, 9, 5, 6, par1 + 0.5F);
public void setLivingAnimations(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4)
{
EntityIceGiant entityicegiant = (EntityIceGiant)par1EntityLivingBase;
int i = entityicegiant.getAttackTimer();
if (i > 0) this.iceGiantRightArm = (new ModelRenderer(this)).setTextureSize(short1, short2);
{ this.iceGiantRightArm.setRotationPoint(0.0F, -7.0F, 0.0F);
this.iceGiantRightArm.rotateAngleX = -2.0F + 1.5F * this.func_78172_a((float)i - par4, 10.0F); this.iceGiantRightArm.setTextureOffset(60, 21).addBox(-13.0F, -2.5F, -3.0F, 4, 30, 6, par1);
this.iceGiantLeftArm.rotateAngleX = -2.0F + 1.5F * this.func_78172_a((float)i - par4, 10.0F);
}
else
{
this.iceGiantRightArm.rotateAngleX = (-0.2F + 1.5F * this.func_78172_a(par2, 13.0F)) * par3;
this.iceGiantLeftArm.rotateAngleX = (-0.2F - 1.5F * this.func_78172_a(par2, 13.0F)) * par3;
}
}
private float func_78172_a(float par1, float par2) this.iceGiantLeftArm = (new ModelRenderer(this)).setTextureSize(short1, short2);
{ this.iceGiantLeftArm.setRotationPoint(0.0F, -7.0F, 0.0F);
return (Math.abs(par1 % par2 - par2 * 0.5F) - par2 * 0.25F) / (par2 * 0.25F); this.iceGiantLeftArm.setTextureOffset(60, 58).addBox(9.0F, -2.5F, -3.0F, 4, 30, 6, par1);
}
this.iceGiantLeftLeg = (new ModelRenderer(this, 0, 22)).setTextureSize(short1, short2);
/** This is really useful for converting the source from a Techne model export this.iceGiantLeftLeg.setRotationPoint(-4.0F, 18.0F + par2, 0.0F);
* which will have absolute rotation points that need to be converted before this.iceGiantLeftLeg.setTextureOffset(37, 0).addBox(-3.5F, -3.0F, -3.0F, 6, 16, 5, par1);
* creating the addChild() relationship. [Courtesy of jabelar] */
protected void convertToChild(ModelRenderer parent, ModelRenderer child) this.iceGiantRightLeg = (new ModelRenderer(this, 0, 22)).setTextureSize(short1, short2);
{ this.iceGiantRightLeg.mirror = true;
// move child rotation point to be relative to parent this.iceGiantRightLeg.setTextureOffset(60, 0).setRotationPoint(5.0F, 18.0F + par2, 0.0F);
child.rotationPointX -= parent.rotationPointX; this.iceGiantRightLeg.addBox(-3.5F, -3.0F, -3.0F, 6, 16, 5, par1);
child.rotationPointY -= parent.rotationPointY;
child.rotationPointZ -= parent.rotationPointZ; headSpike1 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
// make rotations relative to parent headSpike1.addBox(-4F, -4F, 0F, 4, 4, 4);
child.rotateAngleX -= parent.rotateAngleX; headSpike1.setRotationPoint(-4F, -10F, -5F);
child.rotateAngleY -= parent.rotateAngleY; headSpike1.mirror = true;
child.rotateAngleZ -= parent.rotateAngleZ; setRotationWithEulerYzx(headSpike1, -0.1047198F, -0.5235988F, 0.9599311F);
// create relationship
parent.addChild(child); headSpike2 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
} headSpike2.addBox(0F, -4F, 0F, 4, 4, 4);
headSpike2.setRotationPoint(4F, -16F, 0F);
/** Fixes the Techne rotation order bug. [Courtesy of tprk77] */ headSpike2.mirror = true;
private Vector3f ConvertEulerYzxToZyx(Vector3f eulerYzx) { setRotationWithEulerYzx(headSpike2, 0.5585054F, 0.9250245F, -0.5235988F);
// Create a matrix from YZX ordered Euler angles
float a = MathHelper.cos(eulerYzx.x); headSpike3 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
float b = MathHelper.sin(eulerYzx.x); headSpike3.addBox(-2F, -2F, -2F, 4, 4, 4);
float c = MathHelper.cos(eulerYzx.y); headSpike3.setRotationPoint(4F, -13F, 4F);
float d = MathHelper.sin(eulerYzx.y); headSpike3.mirror = true;
float e = MathHelper.cos(eulerYzx.z); setRotationWithEulerYzx(headSpike3, 0.7853982F, -1.396263F, 0.7853982F);
float f = MathHelper.sin(eulerYzx.z);
Matrix4f matrix = new Matrix4f(); headSpike4 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
matrix.m00 = c * e; headSpike4.addBox(-4F, -4F, 0F, 4, 4, 4);
matrix.m01 = b * d - a * c * f; headSpike4.setRotationPoint(-4F, -16F, 0F);
matrix.m02 = b * c * f + a * d; headSpike4.mirror = true;
matrix.m10 = f; setRotationWithEulerYzx(headSpike4, 0.5585054F, -0.9250245F, 0.5235988F);
matrix.m11 = a * e;
matrix.m12 = -b * e; headSpike5 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
matrix.m20 = -d * e; headSpike5.addBox(0F, -4F, 0F, 4, 4, 4);
matrix.m21 = a * d * f + b * c; headSpike5.setRotationPoint(4F, -10F, -5F);
matrix.m22 = a * c - b * d * f; headSpike5.mirror = true;
matrix.m33 = 1.0F; setRotationWithEulerYzx(headSpike5, 0.5235988F, -0.9599311F, 0.1047198F);
// Create ZYX ordered Euler angles from the matrix
Vector3f eulerZyx = new Vector3f(); rightArmSpike1 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
eulerZyx.y = (float) Math.asin(MathHelper.clamp_float(-matrix.m20, -1, 1)); rightArmSpike1.addBox(-2F, -2F, -2F, 4, 4, 4);
if (MathHelper.abs(matrix.m20) < 0.99999) { rightArmSpike1.setRotationPoint(-11F, -8F, 0F);
eulerZyx.x = (float) Math.atan2(matrix.m21, matrix.m22); rightArmSpike1.mirror = true;
eulerZyx.z = (float) Math.atan2(matrix.m10, matrix.m00); setRotationWithEulerYzx(rightArmSpike1, 0.7853982F, 1.134464F, 0.9599311F);
} else {
eulerZyx.x = 0.0F; headSpike6 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
eulerZyx.z = (float) Math.atan2(-matrix.m01, matrix.m11); headSpike6.addBox(-2F, -2F, -2F, 4, 4, 4);
} headSpike6.setRotationPoint(-4F, -13F, 4F);
return eulerZyx; headSpike6.mirror = true;
} setRotationWithEulerYzx(headSpike6, 0.7853982F, -1.745329F, 0.7853982F);
private void setRotationWithEulerYzx(ModelRenderer model, float x, float y, float z) { leftArmSpike1 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
Vector3f eulerYzx = new Vector3f(x, y, z); leftArmSpike1.addBox(-2F, -2F, -2F, 4, 4, 4);
Vector3f eulerZyx = ConvertEulerYzxToZyx(eulerYzx); leftArmSpike1.setRotationPoint(11F, -8F, 0F);
model.rotateAngleX = eulerZyx.x; leftArmSpike1.mirror = true;
model.rotateAngleY = eulerZyx.y; setRotationWithEulerYzx(leftArmSpike1, 0.7853982F, -1.134464F, -0.9599311F);
model.rotateAngleZ = eulerZyx.z;
} leftArmSpike2 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
leftArmSpike2.addBox(-2F, -2F, -2F, 4, 4, 4);
leftArmSpike2.setRotationPoint(12F, -4F, 0F);
leftArmSpike2.mirror = true;
setRotationWithEulerYzx(leftArmSpike2, 0.7853982F, 0F, -0.9599311F);
bodySpike1 = new ModelRenderer(this, 32, 69).setTextureSize(short1, short2);
bodySpike1.addBox(-3F, -3F, -3F, 6, 6, 6);
bodySpike1.setRotationPoint(-4F, -4F, 3F);
bodySpike1.mirror = true;
setRotationWithEulerYzx(bodySpike1, 0.2808018F, 0.8096675F, 0.8339369F);
rightArmSpike2 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
rightArmSpike2.addBox(-2F, -2F, -2F, 4, 4, 4);
rightArmSpike2.setRotationPoint(-12F, -4F, 0F);
rightArmSpike2.mirror = true;
setRotationWithEulerYzx(rightArmSpike2, 0.7853982F, 0F, 0.9599311F);
bodySpike2 = new ModelRenderer(this, 32, 69).setTextureSize(short1, short2);
bodySpike2.addBox(-3F, -3F, -3F, 6, 6, 6);
bodySpike2.setRotationPoint(4F, -4F, 3F);
bodySpike2.mirror = true;
setRotationWithEulerYzx(bodySpike2, 0.2808018F, -0.8096757F, -0.8339358F);
bodySpike3 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
bodySpike3.addBox(-2F, -2F, -2F, 4, 4, 4);
bodySpike3.setRotationPoint(6F, -2F, -5F);
bodySpike3.mirror = true;
setRotationWithEulerYzx(bodySpike3, 1.120006F, -1.347726F, -0.8969422F);
bodySpike4 = new ModelRenderer(this, 32, 69).setTextureSize(short1, short2);
bodySpike4.addBox(-3F, -3F, -3F, 6, 6, 6);
bodySpike4.setRotationPoint(0F, -4F, -4F);
bodySpike4.mirror = true;
setRotationWithEulerYzx(bodySpike4, 0.7853982F, -1.570796F, 0.9599311F);
headSpike7 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
headSpike7.addBox(-2F, -2F, -2F, 4, 4, 4);
headSpike7.setRotationPoint(0F, -20F, 4F);
headSpike7.mirror = true;
setRotationWithEulerYzx(headSpike7, 0.7853982F, 1.570796F, 0.7853982F);
bodySpike5 = new ModelRenderer(this, 0, 0).setTextureSize(short1, short2);
bodySpike5.addBox(-2F, -2F, -2F, 4, 4, 4);
bodySpike5.setRotationPoint(-6F, -2F, -5F);
bodySpike5.mirror = true;
setRotationWithEulerYzx(bodySpike5, 1.120006F, 1.347725F, 0.896934F);
this.convertToChild(this.iceGiantHead, headSpike1);
this.convertToChild(this.iceGiantHead, headSpike2);
this.convertToChild(this.iceGiantHead, headSpike3);
this.convertToChild(this.iceGiantHead, headSpike4);
this.convertToChild(this.iceGiantHead, headSpike5);
this.convertToChild(this.iceGiantHead, headSpike6);
this.convertToChild(this.iceGiantHead, headSpike7);
this.convertToChild(this.iceGiantRightArm, rightArmSpike1);
this.convertToChild(this.iceGiantRightArm, rightArmSpike2);
this.convertToChild(this.iceGiantLeftArm, leftArmSpike1);
this.convertToChild(this.iceGiantLeftArm, leftArmSpike2);
this.convertToChild(this.iceGiantBody, bodySpike1);
this.convertToChild(this.iceGiantBody, bodySpike2);
this.convertToChild(this.iceGiantBody, bodySpike3);
this.convertToChild(this.iceGiantBody, bodySpike4);
this.convertToChild(this.iceGiantBody, bodySpike5);
}
/**
* Sets the models various rotation angles then renders the model.
*/
public void render(Entity par1Entity, float par2, float par3, float par4, float par5, float par6, float par7){
this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity);
this.iceGiantHead.render(par7);
this.iceGiantBody.render(par7);
this.iceGiantLeftLeg.render(par7);
this.iceGiantRightLeg.render(par7);
this.iceGiantRightArm.render(par7);
this.iceGiantLeftArm.render(par7);
}
/**
* Sets the model's various rotation angles. For bipeds, par1 and par2 are used for animating the movement of arms
* and legs, where par1 represents the time(so that arms and legs swing back and forth) and par2 represents how
* "far" arms and legs can swing at most.
*/
public void setRotationAngles(float par1, float par2, float par3, float par4, float par5, float par6,
Entity par7Entity){
this.iceGiantHead.rotateAngleY = par4 / (180F / (float)Math.PI);
this.iceGiantHead.rotateAngleX = par5 / (180F / (float)Math.PI);
this.iceGiantLeftLeg.rotateAngleX = -1.5F * this.func_78172_a(par1, 13.0F) * par2;
this.iceGiantRightLeg.rotateAngleX = 1.5F * this.func_78172_a(par1, 13.0F) * par2;
this.iceGiantLeftLeg.rotateAngleY = 0.0F;
this.iceGiantRightLeg.rotateAngleY = 0.0F;
}
/**
* Used for easily adding entity-dependent animations. The second and third float params here are the same second
* and third as in the setRotationAngles method.
*/
public void setLivingAnimations(EntityLivingBase par1EntityLivingBase, float par2, float par3, float par4){
EntityIceGiant entityicegiant = (EntityIceGiant)par1EntityLivingBase;
int i = entityicegiant.getAttackTimer();
if(i > 0){
this.iceGiantRightArm.rotateAngleX = -2.0F + 1.5F * this.func_78172_a((float)i - par4, 10.0F);
this.iceGiantLeftArm.rotateAngleX = -2.0F + 1.5F * this.func_78172_a((float)i - par4, 10.0F);
}else{
this.iceGiantRightArm.rotateAngleX = (-0.2F + 1.5F * this.func_78172_a(par2, 13.0F)) * par3;
this.iceGiantLeftArm.rotateAngleX = (-0.2F - 1.5F * this.func_78172_a(par2, 13.0F)) * par3;
}
}
private float func_78172_a(float par1, float par2){
return (Math.abs(par1 % par2 - par2 * 0.5F) - par2 * 0.25F) / (par2 * 0.25F);
}
/**
* This is really useful for converting the source from a Techne model export which will have absolute rotation
* points that need to be converted before creating the addChild() relationship. [Courtesy of jabelar]
*/
protected void convertToChild(ModelRenderer parent, ModelRenderer child){
// move child rotation point to be relative to parent
child.rotationPointX -= parent.rotationPointX;
child.rotationPointY -= parent.rotationPointY;
child.rotationPointZ -= parent.rotationPointZ;
// make rotations relative to parent
child.rotateAngleX -= parent.rotateAngleX;
child.rotateAngleY -= parent.rotateAngleY;
child.rotateAngleZ -= parent.rotateAngleZ;
// create relationship
parent.addChild(child);
}
/** Fixes the Techne rotation order bug. [Courtesy of tprk77] */
private Vector3f ConvertEulerYzxToZyx(Vector3f eulerYzx){
// Create a matrix from YZX ordered Euler angles
float a = MathHelper.cos(eulerYzx.x);
float b = MathHelper.sin(eulerYzx.x);
float c = MathHelper.cos(eulerYzx.y);
float d = MathHelper.sin(eulerYzx.y);
float e = MathHelper.cos(eulerYzx.z);
float f = MathHelper.sin(eulerYzx.z);
Matrix4f matrix = new Matrix4f();
matrix.m00 = c * e;
matrix.m01 = b * d - a * c * f;
matrix.m02 = b * c * f + a * d;
matrix.m10 = f;
matrix.m11 = a * e;
matrix.m12 = -b * e;
matrix.m20 = -d * e;
matrix.m21 = a * d * f + b * c;
matrix.m22 = a * c - b * d * f;
matrix.m33 = 1.0F;
// Create ZYX ordered Euler angles from the matrix
Vector3f eulerZyx = new Vector3f();
eulerZyx.y = (float)Math.asin(MathHelper.clamp(-matrix.m20, -1, 1));
if(MathHelper.abs(matrix.m20) < 0.99999){
eulerZyx.x = (float)Math.atan2(matrix.m21, matrix.m22);
eulerZyx.z = (float)Math.atan2(matrix.m10, matrix.m00);
}else{
eulerZyx.x = 0.0F;
eulerZyx.z = (float)Math.atan2(-matrix.m01, matrix.m11);
}
return eulerZyx;
}
private void setRotationWithEulerYzx(ModelRenderer model, float x, float y, float z){
Vector3f eulerYzx = new Vector3f(x, y, z);
Vector3f eulerZyx = ConvertEulerYzxToZyx(eulerYzx);
model.rotateAngleX = eulerZyx.x;
model.rotateAngleY = eulerZyx.y;
model.rotateAngleZ = eulerZyx.z;
}
} }
@@ -6,134 +6,126 @@ import net.minecraft.entity.Entity;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
public class ModelPhoenix extends ModelBase { public class ModelPhoenix extends ModelBase {
ModelRenderer body; ModelRenderer body;
ModelRenderer rightWing; ModelRenderer rightWing;
ModelRenderer leftWing; ModelRenderer leftWing;
ModelRenderer tailFeathers; ModelRenderer tailFeathers;
ModelRenderer tail; ModelRenderer tail;
ModelRenderer head; ModelRenderer head;
ModelRenderer neck; ModelRenderer neck;
ModelRenderer beak; ModelRenderer beak;
ModelRenderer plume; ModelRenderer plume;
public ModelPhoenix() public ModelPhoenix(){
{ textureWidth = 64;
textureWidth = 64; textureHeight = 64;
textureHeight = 64;
/* For future reference: - setRotationPoint sets the origin of a part relative to that of its parent. - The
/* For future reference: * first 3 arguments of addBox set the position of a part relative to its rotation point, and the last 3
* - setRotationPoint sets the origin of a part relative to that of its parent. * arguments are the size of the part. (This means that rotation point and position seem to be the wrong way
* - The first 3 arguments of addBox set the position of a part relative to its rotation point, and the last * round, since changing the rotation point will move the component without changing which point on the
* 3 arguments are the size of the part. * component it rotates about.) - The two integer arguments in the ModelRenderer constructor are the texture
* (This means that rotation point and position seem to be the wrong way round, since changing the rotation point * offset. - Mirror does nothing unless you set it before addBox. - Rotation is the usual pitch, yaw, roll. */
* will move the component without changing which point on the component it rotates about.)
* - The two integer arguments in the ModelRenderer constructor are the texture offset. body = new ModelRenderer(this, 0, 34);
* - Mirror does nothing unless you set it before addBox. body.addBox(0F, 0F, -3F, 6, 15, 6);
* - Rotation is the usual pitch, yaw, roll. body.setRotationPoint(-3F, 0F, -5F);
*/ body.setTextureSize(64, 64);
body.mirror = true;
body = new ModelRenderer(this, 0, 34); setRotation(body, 0.296706F, 0F, 0F);
body.addBox(0F, 0F, -3F, 6, 15, 6);
body.setRotationPoint(-3F, 0F, -5F); rightWing = new ModelRenderer(this, 0, 0);
body.setTextureSize(64, 64); rightWing.mirror = true;
body.mirror = true; rightWing.addBox(-27F, -27F, 0F, 27, 34, 0);
setRotation(body, 0.296706F, 0F, 0F); rightWing.setRotationPoint(0F, 5F, 0F);
rightWing.setTextureSize(64, 64);
rightWing = new ModelRenderer(this, 0, 0); setRotation(rightWing, 0.1745329F, 0F, 0F);
rightWing.mirror = true;
rightWing.addBox(-27F, -27F, 0F, 27, 34, 0); leftWing = new ModelRenderer(this, 0, 0);
rightWing.setRotationPoint(0F, 5F, 0F); leftWing.addBox(0F, -27F, 0F, 27, 34, 0);
rightWing.setTextureSize(64, 64); leftWing.setRotationPoint(6F, 5F, 0F);
setRotation(rightWing, 0.1745329F, 0F, 0F); leftWing.setTextureSize(64, 64);
setRotation(leftWing, 0.1745329F, 0F, 0F);
leftWing = new ModelRenderer(this, 0, 0);
leftWing.addBox(0F, -27F, 0F, 27, 34, 0); tailFeathers = new ModelRenderer(this, 0, 57);
leftWing.setRotationPoint(6F, 5F, 0F); tailFeathers.addBox(-5F, 0F, 0F, 10, 7, 0);
leftWing.setTextureSize(64, 64); tailFeathers.setRotationPoint(0F, 7F, 1F);
setRotation(leftWing, 0.1745329F, 0F, 0F); tailFeathers.setTextureSize(64, 64);
tailFeathers.mirror = true;
tailFeathers = new ModelRenderer(this, 0, 57); setRotation(tailFeathers, 0.5235988F, 0F, 0F);
tailFeathers.addBox(-5F, 0F, 0F, 10, 7, 0);
tailFeathers.setRotationPoint(0F, 7F, 1F); tail = new ModelRenderer(this, 20, 55);
tailFeathers.setTextureSize(64, 64); tail.addBox(-1F, 0F, -1F, 2, 7, 2);
tailFeathers.mirror = true; tail.setRotationPoint(3F, 15F, 2F);
setRotation(tailFeathers, 0.5235988F, 0F, 0F); tail.setTextureSize(64, 64);
tail.mirror = true;
tail = new ModelRenderer(this, 20, 55); setRotation(tail, 0.4014257F, 0F, 0F);
tail.addBox(-1F, 0F, -1F, 2, 7, 2);
tail.setRotationPoint(3F, 15F, 2F); head = new ModelRenderer(this, 24, 34);
tail.setTextureSize(64, 64); head.addBox(-2F, -4F, -5F, 4, 4, 6);
tail.mirror = true; head.setRotationPoint(0F, -4F, 0F);
setRotation(tail, 0.4014257F, 0F, 0F); head.setTextureSize(64, 64);
head.mirror = true;
head = new ModelRenderer(this, 24, 34); setRotation(head, 0F, 0F, 0F);
head.addBox(-2F, -4F, -5F, 4, 4, 6);
head.setRotationPoint(0F, -4F, 0F); neck = new ModelRenderer(this, 24, 44);
head.setTextureSize(64, 64); neck.addBox(-1F, -4F, -1F, 2, 4, 2);
head.mirror = true; neck.setRotationPoint(0F, 0F, -4F);
setRotation(head, 0F, 0F, 0F); neck.setTextureSize(64, 64);
neck.mirror = true;
neck = new ModelRenderer(this, 24, 44); setRotation(neck, 0.2443461F, 0F, 0F);
neck.addBox(-1F, -4F, -1F, 2, 4, 2);
neck.setRotationPoint(0F, 0F, -4F); beak = new ModelRenderer(this, 32, 44);
neck.setTextureSize(64, 64); beak.addBox(-0.5F, 4F, -1F, 1, 2, 3);
neck.mirror = true; beak.setRotationPoint(0F, -5F, -8F);
setRotation(neck, 0.2443461F, 0F, 0F); beak.setTextureSize(64, 64);
beak.mirror = true;
beak = new ModelRenderer(this, 32, 44); setRotation(beak, 0.2792527F, 0F, 0F);
beak.addBox(-0.5F, 4F, -1F, 1, 2, 3);
beak.setRotationPoint(0F, -5F, -8F); plume = new ModelRenderer(this, 28, 50);
beak.setTextureSize(64, 64); plume.addBox(-0.03333334F, 1F, 0F, 0, 5, 5);
beak.mirror = true; plume.setRotationPoint(0F, -7F, 0F);
setRotation(beak, 0.2792527F, 0F, 0F); plume.setTextureSize(64, 64);
plume.mirror = true;
plume = new ModelRenderer(this, 28, 50); setRotation(plume, 0F, 0F, 0F);
plume.addBox(-0.03333334F, 1F, 0F, 0, 5, 5);
plume.setRotationPoint(0F, -7F, 0F); neck.addChild(head);
plume.setTextureSize(64, 64); head.addChild(plume);
plume.mirror = true; head.addChild(beak);
setRotation(plume, 0F, 0F, 0F); tail.addChild(tailFeathers);
body.addChild(tail);
neck.addChild(head); body.addChild(rightWing);
head.addChild(plume); body.addChild(leftWing);
head.addChild(beak); }
tail.addChild(tailFeathers);
body.addChild(tail); public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5){
body.addChild(rightWing); super.render(entity, f, f1, f2, f3, f4, f5);
body.addChild(leftWing); setRotationAngles(f, f1, f2, f3, f4, f5, entity);
}
// float f6 = (180F / (float)Math.PI);
public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) this.neck.rotateAngleX = f4 / (180F / (float)Math.PI);
{ this.neck.rotateAngleY = f3 / (180F / (float)Math.PI);
super.render(entity, f, f1, f2, f3, f4, f5); this.neck.rotateAngleZ = 0.0F;
setRotationAngles(f, f1, f2, f3, f4, f5, entity); this.body.rotateAngleX = 0.3f + MathHelper.cos(f2 * 0.1F) * 0.15F;
this.body.rotateAngleY = 0.0F;
//float f6 = (180F / (float)Math.PI); this.tail.rotateAngleX = this.body.rotateAngleX * 1.1f;
this.neck.rotateAngleX = f4 / (180F / (float)Math.PI); this.tailFeathers.rotateAngleX = this.body.rotateAngleX * 1.2f;
this.neck.rotateAngleY = f3 / (180F / (float)Math.PI); this.rightWing.rotateAngleY = MathHelper.cos(f2 * 0.3F) * (float)Math.PI * 0.15F;
this.neck.rotateAngleZ = 0.0F; this.leftWing.rotateAngleY = -this.rightWing.rotateAngleY;
this.body.rotateAngleX = 0.3f + MathHelper.cos(f2 * 0.1F) * 0.15F;
this.body.rotateAngleY = 0.0F; body.render(f5);
this.tail.rotateAngleX = this.body.rotateAngleX * 1.1f; neck.render(f5);
this.tailFeathers.rotateAngleX = this.body.rotateAngleX * 1.2f; }
this.rightWing.rotateAngleY = MathHelper.cos(f2 * 0.3F) * (float)Math.PI * 0.15F;
this.leftWing.rotateAngleY = -this.rightWing.rotateAngleY; private void setRotation(ModelRenderer model, float x, float y, float z){
model.rotateAngleX = x;
body.render(f5); model.rotateAngleY = y;
neck.render(f5); model.rotateAngleZ = z;
} }
private void setRotation(ModelRenderer model, float x, float y, float z) public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity){
{ super.setRotationAngles(f, f1, f2, f3, f4, f5, entity);
model.rotateAngleX = x; }
model.rotateAngleY = y;
model.rotateAngleZ = z;
}
public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity)
{
super.setRotationAngles(f, f1, f2, f3, f4, f5, entity);
}
} }
@@ -3,172 +3,127 @@ package electroblob.wizardry.client.model;
import net.minecraft.client.model.ModelBiped; import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.model.ModelRenderer; import net.minecraft.client.model.ModelRenderer;
public class ModelWizard extends ModelBiped public class ModelWizard extends ModelBiped {
{ // fields
//fields ModelRenderer Shape5;
ModelRenderer Shape5; ModelRenderer Shape8;
ModelRenderer Shape8; ModelRenderer Shape9;
ModelRenderer Shape9; ModelRenderer Shape10;
ModelRenderer Shape10; ModelRenderer Shape7;
ModelRenderer Shape7; ModelRenderer Shape11;
ModelRenderer Shape11; ModelRenderer Shape12;
ModelRenderer Shape12; ModelRenderer beard;
ModelRenderer beard; ModelRenderer Shape13;
ModelRenderer Shape13;
public ModelWizard(){
public ModelWizard() // super(0, 0, 64, 32);
{ /* bipedRightLeg = new ModelRenderer(this, 32, 0); // 32 and 0 are the x and y texture offsets respectively.
//super(0, 0, 64, 32); * bipedRightLeg.addBox(-2F, 0F, -2F, 4, 12, 4); // x, y, z, u, v, w. bipedRightLeg.setRotationPoint(-2F, 12F,
/* * 0F); // Rotation point xyz (absolute, not relative) bipedRightLeg.setTextureSize(64, 64);
bipedRightLeg = new ModelRenderer(this, 32, 0); // 32 and 0 are the x and y texture offsets respectively. * bipedRightLeg.mirror = true; setRotation(bipedRightLeg, 0F, 0F, 0F);
bipedRightLeg.addBox(-2F, 0F, -2F, 4, 12, 4); // x, y, z, u, v, w. *
bipedRightLeg.setRotationPoint(-2F, 12F, 0F); // Rotation point xyz (absolute, not relative) * bipedLeftLeg.mirror = true; bipedLeftLeg = new ModelRenderer(this, 32, 0); bipedLeftLeg.addBox(-2F, 0F, -2F,
bipedRightLeg.setTextureSize(64, 64); * 4, 12, 4); bipedLeftLeg.setRotationPoint(2F, 12F, 0F); bipedLeftLeg.setTextureSize(64, 64);
bipedRightLeg.mirror = true; * bipedLeftLeg.mirror = true; setRotation(bipedLeftLeg, 0F, 0F, 0F); bipedLeftLeg.mirror = false;
setRotation(bipedRightLeg, 0F, 0F, 0F); *
* bipedBody = new ModelRenderer(this, 0, 16); bipedBody.addBox(0F, 0F, 0F, 8, 12, 4);
bipedLeftLeg.mirror = true; * bipedBody.setRotationPoint(-4F, 0F, -2F); bipedBody.setTextureSize(64, 64); bipedBody.mirror = true;
bipedLeftLeg = new ModelRenderer(this, 32, 0); * setRotation(bipedBody, 0F, 0F, 0F);
bipedLeftLeg.addBox(-2F, 0F, -2F, 4, 12, 4); *
bipedLeftLeg.setRotationPoint(2F, 12F, 0F); * bipedLeftArm.mirror = true; bipedLeftArm = new ModelRenderer(this, 48, 0); bipedLeftArm.addBox(-1F, 0F, -2F,
bipedLeftLeg.setTextureSize(64, 64); * 4, 12, 4); bipedLeftArm.setRotationPoint(4F, 0F, 0F); bipedLeftArm.setTextureSize(64, 64);
bipedLeftLeg.mirror = true; * bipedLeftArm.mirror = true; setRotation(bipedLeftArm, 0F, 0F, 0F); bipedLeftArm.mirror = false;
setRotation(bipedLeftLeg, 0F, 0F, 0F); *
bipedLeftLeg.mirror = false; * bipedRightArm = new ModelRenderer(this, 48, 0); bipedRightArm.addBox(-3F, 0F, -2F, 4, 12, 4);
* bipedRightArm.setRotationPoint(-4F, 0F, 0F); bipedRightArm.setTextureSize(64, 64); bipedRightArm.mirror =
bipedBody = new ModelRenderer(this, 0, 16); * true; setRotation(bipedRightArm, 0F, 0F, 0F);
bipedBody.addBox(0F, 0F, 0F, 8, 12, 4); *
bipedBody.setRotationPoint(-4F, 0F, -2F); * bipedHead = new ModelRenderer(this, 0, 0); bipedHead.addBox(-4F, -8F, -4F, 8, 8, 8);
bipedBody.setTextureSize(64, 64); * bipedHead.setRotationPoint(0F, 0F, 0F); bipedHead.setTextureSize(64, 64); bipedHead.mirror = true;
bipedBody.mirror = true; * setRotation(bipedHead, 0F, 0F, 0F); */
setRotation(bipedBody, 0F, 0F, 0F); Shape5 = new ModelRenderer(this, 0, 51);
Shape5.addBox(0F, 0F, 0F, 12, 1, 12);
bipedLeftArm.mirror = true; Shape5.setRotationPoint(-6F, -7F, -6F);
bipedLeftArm = new ModelRenderer(this, 48, 0); Shape5.setTextureSize(64, 64);
bipedLeftArm.addBox(-1F, 0F, -2F, 4, 12, 4); Shape5.mirror = true;
bipedLeftArm.setRotationPoint(4F, 0F, 0F); setRotation(Shape5, 0F, 0F, 0F);
bipedLeftArm.setTextureSize(64, 64); Shape8 = new ModelRenderer(this, 0, 32);
bipedLeftArm.mirror = true; Shape8.addBox(0F, 0F, 0F, 6, 1, 6);
setRotation(bipedLeftArm, 0F, 0F, 0F); Shape8.setRotationPoint(-3F, -9F, -3F);
bipedLeftArm.mirror = false; Shape8.setTextureSize(64, 64);
Shape8.mirror = true;
bipedRightArm = new ModelRenderer(this, 48, 0); setRotation(Shape8, -0.0349066F, 0F, 0F);
bipedRightArm.addBox(-3F, 0F, -2F, 4, 12, 4); Shape9 = new ModelRenderer(this, 24, 32);
bipedRightArm.setRotationPoint(-4F, 0F, 0F); Shape9.addBox(0F, 0F, 0F, 3, 3, 3);
bipedRightArm.setTextureSize(64, 64); Shape9.setRotationPoint(-1.5F, -13F, -0.5F);
bipedRightArm.mirror = true; Shape9.setTextureSize(64, 64);
setRotation(bipedRightArm, 0F, 0F, 0F); Shape9.mirror = true;
setRotation(Shape9, -0.2511622F, 0F, 0F);
bipedHead = new ModelRenderer(this, 0, 0); Shape10 = new ModelRenderer(this, 0, 39);
bipedHead.addBox(-4F, -8F, -4F, 8, 8, 8); Shape10.addBox(0F, 0F, 0F, 5, 1, 5);
bipedHead.setRotationPoint(0F, 0F, 0F); Shape10.setRotationPoint(-2.5F, -10F, -2.5F);
bipedHead.setTextureSize(64, 64); Shape10.setTextureSize(64, 64);
bipedHead.mirror = true; Shape10.mirror = true;
setRotation(bipedHead, 0F, 0F, 0F); setRotation(Shape10, -0.0698132F, 0F, 0F);
*/ Shape7 = new ModelRenderer(this, 0, 45);
Shape5 = new ModelRenderer(this, 0, 51); Shape7.addBox(0F, 0F, 0F, 4, 2, 4);
Shape5.addBox(0F, 0F, 0F, 12, 1, 12); Shape7.setRotationPoint(-2F, -11F, -1.5F);
Shape5.setRotationPoint(-6F, -7F, -6F); Shape7.setTextureSize(64, 64);
Shape5.setTextureSize(64, 64); Shape7.mirror = true;
Shape5.mirror = true; setRotation(Shape7, -0.1396263F, 0F, 0F);
setRotation(Shape5, 0F, 0F, 0F); Shape11 = new ModelRenderer(this, 20, 39);
Shape8 = new ModelRenderer(this, 0, 32); Shape11.addBox(0F, 0F, 0F, 2, 3, 2);
Shape8.addBox(0F, 0F, 0F, 6, 1, 6); Shape11.setRotationPoint(-1F, -15F, 1F);
Shape8.setRotationPoint(-3F, -9F, -3F); Shape11.setTextureSize(64, 64);
Shape8.setTextureSize(64, 64); Shape11.mirror = true;
Shape8.mirror = true; setRotation(Shape11, -0.4363323F, 0F, 0F);
setRotation(Shape8, -0.0349066F, 0F, 0F); Shape12 = new ModelRenderer(this, 28, 39);
Shape9 = new ModelRenderer(this, 24, 32); Shape12.addBox(0F, 0F, 0F, 1, 2, 1);
Shape9.addBox(0F, 0F, 0F, 3, 3, 3); Shape12.setRotationPoint(-0.5F, -16F, 2.5F);
Shape9.setRotationPoint(-1.5F, -13F, -0.5F); Shape12.setTextureSize(64, 64);
Shape9.setTextureSize(64, 64); Shape12.mirror = true;
Shape9.mirror = true; setRotation(Shape12, -0.715585F, 0F, 0F);
setRotation(Shape9, -0.2511622F, 0F, 0F); beard = new ModelRenderer(this, 32, 0);
Shape10 = new ModelRenderer(this, 0, 39); beard.addBox(0F, 0F, 0F, 8, 5, 0);
Shape10.addBox(0F, 0F, 0F, 5, 1, 5); beard.setRotationPoint(-4F, 0F, -4F);
Shape10.setRotationPoint(-2.5F, -10F, -2.5F); beard.setTextureSize(64, 64);
Shape10.setTextureSize(64, 64); beard.mirror = true;
Shape10.mirror = true; setRotation(beard, 0F, 0F, 0F);
setRotation(Shape10, -0.0698132F, 0F, 0F); Shape13 = new ModelRenderer(this, 36, 16);
Shape7 = new ModelRenderer(this, 0, 45); Shape13.addBox(4F, 0F, 2F, 8, 20, 6);
Shape7.addBox(0F, 0F, 0F, 4, 2, 4); Shape13.setRotationPoint(-4F, 0F, -3F);
Shape7.setRotationPoint(-2F, -11F, -1.5F); Shape13.setTextureSize(64, 64);
Shape7.setTextureSize(64, 64); Shape13.mirror = true;
Shape7.mirror = true; setRotation(Shape13, 0F, 0F, 0F);
setRotation(Shape7, -0.1396263F, 0F, 0F);
Shape11 = new ModelRenderer(this, 20, 39); // Makes head bits move with head
Shape11.addBox(0F, 0F, 0F, 2, 3, 2); // bipedHead.addChild(Shape5);
Shape11.setRotationPoint(-1F, -15F, 1F); bipedHead.addChild(beard);
Shape11.setTextureSize(64, 64); // bipedHead.addChild(Shape7);
Shape11.mirror = true; // bipedHead.addChild(Shape8);
setRotation(Shape11, -0.4363323F, 0F, 0F); // bipedHead.addChild(Shape9);
Shape12 = new ModelRenderer(this, 28, 39); // bipedHead.addChild(Shape10);
Shape12.addBox(0F, 0F, 0F, 1, 2, 1); // bipedHead.addChild(Shape11);
Shape12.setRotationPoint(-0.5F, -16F, 2.5F); // bipedHead.addChild(Shape12);
Shape12.setTextureSize(64, 64);
Shape12.mirror = true; // Makes cloak attached to body
setRotation(Shape12, -0.715585F, 0F, 0F); // bipedBody.addChild(Shape13);
beard = new ModelRenderer(this, 32, 0);
beard.addBox(0F, 0F, 0F, 8, 5, 0); // No outer head layer
beard.setRotationPoint(-4F, 0F, -4F); this.bipedHeadwear.isHidden = true;
beard.setTextureSize(64, 64); }
beard.mirror = true;
setRotation(beard, 0F, 0F, 0F); /* public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5) {
Shape13 = new ModelRenderer(this, 36, 16); * super.render(entity, f, f1, f2, f3, f4, f5); setRotationAngles(f, f1, f2, f3, f4, f5, entity);
Shape13.addBox(4F, 0F, 2F, 8, 20, 6); * bipedRightLeg.render(f5); bipedLeftLeg.render(f5); bipedBody.render(f5); bipedLeftArm.render(f5);
Shape13.setRotationPoint(-4F, 0F, -3F); * bipedRightArm.render(f5); bipedHead.render(f5); Shape5.render(f5); Shape8.render(f5); Shape9.render(f5);
Shape13.setTextureSize(64, 64); * Shape10.render(f5); Shape7.render(f5); Shape11.render(f5); Shape12.render(f5); Shape6.render(f5);
Shape13.mirror = true; * Shape13.render(f5); } */
setRotation(Shape13, 0F, 0F, 0F); private void setRotation(ModelRenderer model, float x, float y, float z){
model.rotateAngleX = x;
// Makes head bits move with head model.rotateAngleY = y;
//bipedHead.addChild(Shape5); model.rotateAngleZ = z;
bipedHead.addChild(beard); }
//bipedHead.addChild(Shape7); /* public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity) {
//bipedHead.addChild(Shape8); * super.setRotationAngles(f, f1, f2, f3, f4, f5, entity); } */
//bipedHead.addChild(Shape9);
//bipedHead.addChild(Shape10);
//bipedHead.addChild(Shape11);
//bipedHead.addChild(Shape12);
// Makes cloak attached to body
//bipedBody.addChild(Shape13);
// No outer head layer
this.bipedHeadwear.isHidden = true;
}
/*
public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5)
{
super.render(entity, f, f1, f2, f3, f4, f5);
setRotationAngles(f, f1, f2, f3, f4, f5, entity);
bipedRightLeg.render(f5);
bipedLeftLeg.render(f5);
bipedBody.render(f5);
bipedLeftArm.render(f5);
bipedRightArm.render(f5);
bipedHead.render(f5);
Shape5.render(f5);
Shape8.render(f5);
Shape9.render(f5);
Shape10.render(f5);
Shape7.render(f5);
Shape11.render(f5);
Shape12.render(f5);
Shape6.render(f5);
Shape13.render(f5);
}
*/
private void setRotation(ModelRenderer model, float x, float y, float z)
{
model.rotateAngleX = x;
model.rotateAngleY = y;
model.rotateAngleZ = z;
}
/*
public void setRotationAngles(float f, float f1, float f2, float f3, float f4, float f5, Entity entity)
{
super.setRotationAngles(f, f1, f2, f3, f4, f5, entity);
}
*/
} }
@@ -1,11 +1,9 @@
package electroblob.wizardry.client.model; package electroblob.wizardry.client.model;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.model.ModelRenderer; import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
public class ModelWizardArmour extends ModelBiped public class ModelWizardArmour extends ModelWtfMojang {
{
ModelRenderer Shape1; ModelRenderer Shape1;
ModelRenderer Shape2; ModelRenderer Shape2;
ModelRenderer Shape3; ModelRenderer Shape3;
@@ -90,7 +88,7 @@ public class ModelWizardArmour extends ModelBiped
bipedHead.addChild(Shape6); bipedHead.addChild(Shape6);
bipedHead.addChild(Shape7); bipedHead.addChild(Shape7);
// Makes the robe move with the body // Makes the robe move with the body
//bipedBody.addChild(robe); // bipedBody.addChild(robe);
} }
public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5){ public void render(Entity entity, float f, float f1, float f2, float f3, float f4, float f5){
@@ -0,0 +1,44 @@
package electroblob.wizardry.client.model;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.EntityArmorStand;
public class ModelWtfMojang extends ModelBiped {
public ModelWtfMojang(float modelSize, float rotationYOffset, int textureWidth, int textureHeight) {
super(modelSize, rotationYOffset, textureWidth, textureHeight);
}
@Override
public void setRotationAngles(float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scaleFactor, Entity entityIn) {
// [VanillaCopy] ModelArmorStandArmor
// this prevents helmets from always facing south, and the armor "breathing" on the stand
if (entityIn instanceof EntityArmorStand) {
EntityArmorStand entityarmorstand = (EntityArmorStand) entityIn;
this.bipedHead.rotateAngleX = 0.017453292F * entityarmorstand.getHeadRotation().getX();
this.bipedHead.rotateAngleY = 0.017453292F * entityarmorstand.getHeadRotation().getY();
this.bipedHead.rotateAngleZ = 0.017453292F * entityarmorstand.getHeadRotation().getZ();
this.bipedHead.setRotationPoint(0.0F, 1.0F, 0.0F);
this.bipedBody.rotateAngleX = 0.017453292F * entityarmorstand.getBodyRotation().getX();
this.bipedBody.rotateAngleY = 0.017453292F * entityarmorstand.getBodyRotation().getY();
this.bipedBody.rotateAngleZ = 0.017453292F * entityarmorstand.getBodyRotation().getZ();
this.bipedLeftArm.rotateAngleX = 0.017453292F * entityarmorstand.getLeftArmRotation().getX();
this.bipedLeftArm.rotateAngleY = 0.017453292F * entityarmorstand.getLeftArmRotation().getY();
this.bipedLeftArm.rotateAngleZ = 0.017453292F * entityarmorstand.getLeftArmRotation().getZ();
this.bipedRightArm.rotateAngleX = 0.017453292F * entityarmorstand.getRightArmRotation().getX();
this.bipedRightArm.rotateAngleY = 0.017453292F * entityarmorstand.getRightArmRotation().getY();
this.bipedRightArm.rotateAngleZ = 0.017453292F * entityarmorstand.getRightArmRotation().getZ();
this.bipedLeftLeg.rotateAngleX = 0.017453292F * entityarmorstand.getLeftLegRotation().getX();
this.bipedLeftLeg.rotateAngleY = 0.017453292F * entityarmorstand.getLeftLegRotation().getY();
this.bipedLeftLeg.rotateAngleZ = 0.017453292F * entityarmorstand.getLeftLegRotation().getZ();
this.bipedLeftLeg.setRotationPoint(1.9F, 11.0F, 0.0F);
this.bipedRightLeg.rotateAngleX = 0.017453292F * entityarmorstand.getRightLegRotation().getX();
this.bipedRightLeg.rotateAngleY = 0.017453292F * entityarmorstand.getRightLegRotation().getY();
this.bipedRightLeg.rotateAngleZ = 0.017453292F * entityarmorstand.getRightLegRotation().getZ();
this.bipedRightLeg.setRotationPoint(-1.9F, 11.0F, 0.0F);
copyModelAngles(this.bipedHead, this.bipedHeadwear);
} else super.setRotationAngles(limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scaleFactor, entityIn);
}
}
@@ -1,13 +1,11 @@
package electroblob.wizardry.client.model; package electroblob.wizardry.client.model;
import java.util.ArrayList;
import java.util.List;
import electroblob.wizardry.registry.WizardryBlocks; import electroblob.wizardry.registry.WizardryBlocks;
import electroblob.wizardry.registry.WizardryItems; import electroblob.wizardry.registry.WizardryItems;
import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.NonNullList;
import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
@@ -18,6 +16,7 @@ import net.minecraftforge.oredict.OreDictionary;
/** /**
* Class responsible for registering all of wizardry's item (and itemblock) models. * Class responsible for registering all of wizardry's item (and itemblock) models.
*
* @author Electroblob * @author Electroblob
* @since Wizardry 2.1 * @since Wizardry 2.1
*/ */
@@ -27,166 +26,173 @@ public final class WizardryItemModels {
@SubscribeEvent @SubscribeEvent
public static void register(ModelRegistryEvent event){ public static void register(ModelRegistryEvent event){
// ItemBlocks // ItemBlocks
registerItemModel(Item.getItemFromBlock(WizardryBlocks.arcane_workbench)); registerItemModel(Item.getItemFromBlock(WizardryBlocks.arcane_workbench));
registerItemModel(Item.getItemFromBlock(WizardryBlocks.crystal_ore)); registerItemModel(Item.getItemFromBlock(WizardryBlocks.crystal_ore));
registerItemModel(Item.getItemFromBlock(WizardryBlocks.crystal_flower)); registerItemModel(Item.getItemFromBlock(WizardryBlocks.crystal_flower));
registerItemModel(Item.getItemFromBlock(WizardryBlocks.transportation_stone)); registerItemModel(Item.getItemFromBlock(WizardryBlocks.transportation_stone));
registerItemModel(Item.getItemFromBlock(WizardryBlocks.crystal_block)); registerItemModel(Item.getItemFromBlock(WizardryBlocks.crystal_block));
// Items // Items
registerItemModel(WizardryItems.magic_crystal); registerItemModel(WizardryItems.magic_crystal);
registerItemModel(WizardryItems.magic_wand); registerItemModel(WizardryItems.magic_wand);
registerItemModel(WizardryItems.apprentice_wand); registerItemModel(WizardryItems.apprentice_wand);
registerItemModel(WizardryItems.advanced_wand); registerItemModel(WizardryItems.advanced_wand);
registerItemModel(WizardryItems.master_wand); registerItemModel(WizardryItems.master_wand);
registerItemModel(WizardryItems.spell_book); registerItemModel(WizardryItems.spell_book);
// Wildcard registered for wizard trades. // Wildcard registered for wizard trades.
registerItemModel(WizardryItems.spell_book, OreDictionary.WILDCARD_VALUE, "normal"); registerItemModel(WizardryItems.spell_book, OreDictionary.WILDCARD_VALUE, "normal");
registerItemModel(WizardryItems.arcane_tome); registerItemModel(WizardryItems.arcane_tome);
registerItemModel(WizardryItems.wizard_handbook); registerItemModel(WizardryItems.wizard_handbook);
registerItemModel(WizardryItems.basic_fire_wand);
registerItemModel(WizardryItems.basic_ice_wand);
registerItemModel(WizardryItems.basic_lightning_wand);
registerItemModel(WizardryItems.basic_necromancy_wand);
registerItemModel(WizardryItems.basic_earth_wand);
registerItemModel(WizardryItems.basic_sorcery_wand);
registerItemModel(WizardryItems.basic_healing_wand);
registerItemModel(WizardryItems.apprentice_fire_wand); registerItemModel(WizardryItems.basic_fire_wand);
registerItemModel(WizardryItems.apprentice_ice_wand); registerItemModel(WizardryItems.basic_ice_wand);
registerItemModel(WizardryItems.apprentice_lightning_wand); registerItemModel(WizardryItems.basic_lightning_wand);
registerItemModel(WizardryItems.apprentice_necromancy_wand); registerItemModel(WizardryItems.basic_necromancy_wand);
registerItemModel(WizardryItems.apprentice_earth_wand); registerItemModel(WizardryItems.basic_earth_wand);
registerItemModel(WizardryItems.apprentice_sorcery_wand); registerItemModel(WizardryItems.basic_sorcery_wand);
registerItemModel(WizardryItems.apprentice_healing_wand); registerItemModel(WizardryItems.basic_healing_wand);
registerItemModel(WizardryItems.advanced_fire_wand); registerItemModel(WizardryItems.apprentice_fire_wand);
registerItemModel(WizardryItems.advanced_ice_wand); registerItemModel(WizardryItems.apprentice_ice_wand);
registerItemModel(WizardryItems.advanced_lightning_wand); registerItemModel(WizardryItems.apprentice_lightning_wand);
registerItemModel(WizardryItems.advanced_necromancy_wand); registerItemModel(WizardryItems.apprentice_necromancy_wand);
registerItemModel(WizardryItems.advanced_earth_wand); registerItemModel(WizardryItems.apprentice_earth_wand);
registerItemModel(WizardryItems.advanced_sorcery_wand); registerItemModel(WizardryItems.apprentice_sorcery_wand);
registerItemModel(WizardryItems.advanced_healing_wand); registerItemModel(WizardryItems.apprentice_healing_wand);
registerItemModel(WizardryItems.master_fire_wand); registerItemModel(WizardryItems.advanced_fire_wand);
registerItemModel(WizardryItems.master_ice_wand); registerItemModel(WizardryItems.advanced_ice_wand);
registerItemModel(WizardryItems.master_lightning_wand); registerItemModel(WizardryItems.advanced_lightning_wand);
registerItemModel(WizardryItems.master_necromancy_wand); registerItemModel(WizardryItems.advanced_necromancy_wand);
registerItemModel(WizardryItems.master_earth_wand); registerItemModel(WizardryItems.advanced_earth_wand);
registerItemModel(WizardryItems.master_sorcery_wand); registerItemModel(WizardryItems.advanced_sorcery_wand);
registerItemModel(WizardryItems.master_healing_wand); registerItemModel(WizardryItems.advanced_healing_wand);
registerItemModel(WizardryItems.spectral_sword); registerItemModel(WizardryItems.master_fire_wand);
registerItemModel(WizardryItems.spectral_pickaxe); registerItemModel(WizardryItems.master_ice_wand);
registerItemModel(WizardryItems.spectral_bow); registerItemModel(WizardryItems.master_lightning_wand);
registerItemModel(WizardryItems.master_necromancy_wand);
registerItemModel(WizardryItems.master_earth_wand);
registerItemModel(WizardryItems.master_sorcery_wand);
registerItemModel(WizardryItems.master_healing_wand);
registerItemModel(WizardryItems.mana_flask); registerItemModel(WizardryItems.spectral_sword);
registerItemModel(WizardryItems.spectral_pickaxe);
registerItemModel(WizardryItems.spectral_bow);
registerItemModel(WizardryItems.storage_upgrade); registerItemModel(WizardryItems.mana_flask);
registerItemModel(WizardryItems.siphon_upgrade);
registerItemModel(WizardryItems.condenser_upgrade);
registerItemModel(WizardryItems.range_upgrade);
registerItemModel(WizardryItems.duration_upgrade);
registerItemModel(WizardryItems.cooldown_upgrade);
registerItemModel(WizardryItems.blast_upgrade);
registerItemModel(WizardryItems.attunement_upgrade);
registerItemModel(WizardryItems.flaming_axe); registerItemModel(WizardryItems.storage_upgrade);
registerItemModel(WizardryItems.frost_axe); registerItemModel(WizardryItems.siphon_upgrade);
registerItemModel(WizardryItems.condenser_upgrade);
registerItemModel(WizardryItems.range_upgrade);
registerItemModel(WizardryItems.duration_upgrade);
registerItemModel(WizardryItems.cooldown_upgrade);
registerItemModel(WizardryItems.blast_upgrade);
registerItemModel(WizardryItems.attunement_upgrade);
registerItemModel(WizardryItems.firebomb); registerItemModel(WizardryItems.flaming_axe);
registerItemModel(WizardryItems.poison_bomb); registerItemModel(WizardryItems.frost_axe);
registerItemModel(WizardryItems.blank_scroll);
registerItemModel(WizardryItems.scroll);
registerItemModel(WizardryItems.armour_upgrade); registerItemModel(WizardryItems.firebomb);
registerItemModel(WizardryItems.poison_bomb);
registerItemModel(WizardryItems.magic_silk);
registerItemModel(WizardryItems.wizard_hat);
registerItemModel(WizardryItems.wizard_robe);
registerItemModel(WizardryItems.wizard_leggings);
registerItemModel(WizardryItems.wizard_boots);
registerItemModel(WizardryItems.wizard_hat_fire); registerItemModel(WizardryItems.blank_scroll);
registerItemModel(WizardryItems.wizard_robe_fire); registerItemModel(WizardryItems.scroll);
registerItemModel(WizardryItems.wizard_leggings_fire);
registerItemModel(WizardryItems.wizard_boots_fire);
registerItemModel(WizardryItems.wizard_hat_ice); registerItemModel(WizardryItems.armour_upgrade);
registerItemModel(WizardryItems.wizard_robe_ice);
registerItemModel(WizardryItems.wizard_leggings_ice);
registerItemModel(WizardryItems.wizard_boots_ice);
registerItemModel(WizardryItems.wizard_hat_lightning); registerItemModel(WizardryItems.magic_silk);
registerItemModel(WizardryItems.wizard_robe_lightning);
registerItemModel(WizardryItems.wizard_leggings_lightning);
registerItemModel(WizardryItems.wizard_boots_lightning);
registerItemModel(WizardryItems.wizard_hat_necromancy); registerItemModel(WizardryItems.wizard_hat);
registerItemModel(WizardryItems.wizard_robe_necromancy); registerItemModel(WizardryItems.wizard_robe);
registerItemModel(WizardryItems.wizard_leggings_necromancy); registerItemModel(WizardryItems.wizard_leggings);
registerItemModel(WizardryItems.wizard_boots_necromancy); registerItemModel(WizardryItems.wizard_boots);
registerItemModel(WizardryItems.wizard_hat_earth); registerItemModel(WizardryItems.wizard_hat_fire);
registerItemModel(WizardryItems.wizard_robe_earth); registerItemModel(WizardryItems.wizard_robe_fire);
registerItemModel(WizardryItems.wizard_leggings_earth); registerItemModel(WizardryItems.wizard_leggings_fire);
registerItemModel(WizardryItems.wizard_boots_earth); registerItemModel(WizardryItems.wizard_boots_fire);
registerItemModel(WizardryItems.wizard_hat_sorcery);
registerItemModel(WizardryItems.wizard_robe_sorcery);
registerItemModel(WizardryItems.wizard_leggings_sorcery);
registerItemModel(WizardryItems.wizard_boots_sorcery);
registerItemModel(WizardryItems.wizard_hat_healing); registerItemModel(WizardryItems.wizard_hat_ice);
registerItemModel(WizardryItems.wizard_robe_healing); registerItemModel(WizardryItems.wizard_robe_ice);
registerItemModel(WizardryItems.wizard_leggings_healing); registerItemModel(WizardryItems.wizard_leggings_ice);
registerItemModel(WizardryItems.wizard_boots_healing); registerItemModel(WizardryItems.wizard_boots_ice);
registerItemModel(WizardryItems.spectral_helmet); registerItemModel(WizardryItems.wizard_hat_lightning);
registerItemModel(WizardryItems.spectral_chestplate); registerItemModel(WizardryItems.wizard_robe_lightning);
registerItemModel(WizardryItems.spectral_leggings); registerItemModel(WizardryItems.wizard_leggings_lightning);
registerItemModel(WizardryItems.spectral_boots); registerItemModel(WizardryItems.wizard_boots_lightning);
registerItemModel(WizardryItems.smoke_bomb); registerItemModel(WizardryItems.wizard_hat_necromancy);
registerItemModel(WizardryItems.wizard_robe_necromancy);
registerItemModel(WizardryItems.identification_scroll); registerItemModel(WizardryItems.wizard_leggings_necromancy);
registerItemModel(WizardryItems.wizard_boots_necromancy);
registerItemModel(WizardryItems.wizard_hat_earth);
registerItemModel(WizardryItems.wizard_robe_earth);
registerItemModel(WizardryItems.wizard_leggings_earth);
registerItemModel(WizardryItems.wizard_boots_earth);
registerItemModel(WizardryItems.wizard_hat_sorcery);
registerItemModel(WizardryItems.wizard_robe_sorcery);
registerItemModel(WizardryItems.wizard_leggings_sorcery);
registerItemModel(WizardryItems.wizard_boots_sorcery);
registerItemModel(WizardryItems.wizard_hat_healing);
registerItemModel(WizardryItems.wizard_robe_healing);
registerItemModel(WizardryItems.wizard_leggings_healing);
registerItemModel(WizardryItems.wizard_boots_healing);
registerItemModel(WizardryItems.spectral_helmet);
registerItemModel(WizardryItems.spectral_chestplate);
registerItemModel(WizardryItems.spectral_leggings);
registerItemModel(WizardryItems.spectral_boots);
registerItemModel(WizardryItems.smoke_bomb);
registerItemModel(WizardryItems.identification_scroll);
} }
// Moved from the proxies // Moved from the proxies
/** Registers an item model, using the item's registry name as the model name (this /**
* convention makes it easier to keep track of everything). Variant defaults to "normal". Registers the model * Registers an item model, using the item's registry name as the model name (this convention makes it easier to
* for metadata 0 automatically, plus all the other metadata values that the item can take, as defined in * keep track of everything). Variant defaults to "normal". Registers the model for metadata 0 automatically, plus
* all the other metadata values that the item can take, as defined in
* {@link Item#getSubItems(Item, net.minecraft.creativetab.CreativeTabs, java.util.List)}. The passed in item * {@link Item#getSubItems(Item, net.minecraft.creativetab.CreativeTabs, java.util.List)}. The passed in item
* <b>must</b> allow null to be passed in for the creative tab parameter in the aforementioned method, or a * <b>must</b> allow null to be passed in for the creative tab parameter in the aforementioned method, or a
* {@link NullPointerException} will result. */ * {@link NullPointerException} will result.
*/
private static void registerItemModel(Item item){ private static void registerItemModel(Item item){
if(item.getHasSubtypes()){ if(item.getHasSubtypes()){
List<ItemStack> items = new ArrayList<ItemStack>(); NonNullList<ItemStack> items = NonNullList.create();
item.getSubItems(item, null, items); // Client-only method, but we're client-side so this is OK. item.getSubItems(item.getCreativeTab(), items); // Client-only method, but we're client-side so this is OK.
for(ItemStack stack : items){ for(ItemStack stack : items){
ModelLoader.setCustomModelResourceLocation(item, stack.getMetadata(), new ModelResourceLocation(item.getRegistryName(), "inventory")); ModelLoader.setCustomModelResourceLocation(item, stack.getMetadata(),
new ModelResourceLocation(item.getRegistryName(), "inventory"));
} }
} }
// Changing the last parameter from null to "inventory" fixed the item/block model weirdness. No idea why! // Changing the last parameter from null to "inventory" fixed the item/block model weirdness. No idea why!
ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(item.getRegistryName(), "inventory")); ModelLoader.setCustomModelResourceLocation(item, 0,
new ModelResourceLocation(item.getRegistryName(), "inventory"));
} }
/** Registers an item model for the given metadata, using the item's registry name as the model name (this /**
* convention makes it easier to keep track of everything). This is intended for registering additional metadata * Registers an item model for the given metadata, using the item's registry name as the model name (this convention
* values which aren't displayed in the creative menu, for example the wildcard spell book used in wizard trades. */ * makes it easier to keep track of everything). This is intended for registering additional metadata values which
private static void registerItemModel(Item item, int metadata, String variant) { * aren't displayed in the creative menu, for example the wildcard spell book used in wizard trades.
ModelLoader.setCustomModelResourceLocation(item, metadata, new ModelResourceLocation(item.getRegistryName(), variant)); */
private static void registerItemModel(Item item, int metadata, String variant){
ModelLoader.setCustomModelResourceLocation(item, metadata,
new ModelResourceLocation(item.getRegistryName(), variant));
} }
} }
@@ -6,67 +6,69 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ParticleBlizzard extends ParticleSnow { public class ParticleBlizzard extends ParticleSnow {
private double angle;
private double radius;
private double speed;
public ParticleBlizzard(World world, int maxAge, double originX, double originZ, double radius, double yPos){ private double angle;
super(world, 0, 0, 0, 0, 0, 0, maxAge); private double radius;
this.angle = this.rand.nextDouble() * Math.PI * 2; private double speed;
double x = originX - Math.cos(angle)*radius;
double z = originZ + radius*Math.sin(angle);
this.radius = radius;
this.setPosition(x, yPos, z);
this.prevPosX = x;
this.prevPosY = yPos;
this.prevPosZ = z;
if(rand.nextBoolean()){
speed = rand.nextDouble()*2 + 1;
}else{
speed = rand.nextDouble()*-2 - 1;
}
this.multipleParticleScaleBy(1.5f);
}
@Override
public void init(){
super.init();
this.fullBrightness = true;
}
// @Override public ParticleBlizzard(World world, int maxAge, double originX, double originZ, double radius, double yPos){
// public void renderParticle(VertexBuffer buffer, Entity entity, float partialTicks, float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ){ super(world, 0, 0, 0, 0, 0, 0, maxAge);
// if(this.particleAge < this.particleMaxAge / 3 || (this.particleAge + this.particleMaxAge) / 3 % 2 == 0){ this.angle = this.rand.nextDouble() * Math.PI * 2;
// super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ); double x = originX - Math.cos(angle) * radius;
// } double z = originZ + radius * Math.sin(angle);
// } this.radius = radius;
this.setPosition(x, yPos, z);
this.prevPosX = x;
this.prevPosY = yPos;
this.prevPosZ = z;
if(rand.nextBoolean()){
speed = rand.nextDouble() * 2 + 1;
}else{
speed = rand.nextDouble() * -2 - 1;
}
this.multipleParticleScaleBy(1.5f);
}
@Override @Override
public void onUpdate(){ public void init(){
super.init();
this.prevPosX = this.posX; this.fullBrightness = true;
this.prevPosY = this.posY; }
this.prevPosZ = this.posZ;
if(this.particleAge++ >= this.particleMaxAge){ // @Override
this.setExpired(); // public void renderParticle(VertexBuffer buffer, Entity entity, float partialTicks, float rotationX, float
} // rotationZ, float rotationYZ, float rotationXY, float rotationXZ){
// if(this.particleAge < this.particleMaxAge / 3 || (this.particleAge + this.particleMaxAge) / 3 % 2 == 0){
// This is in radians per tick... // super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ);
double omega = Math.signum(speed) * ((Math.PI*2)/20 - speed/(20*radius)); // }
// }
// v = r times omega; therefore the normalised velocity vector needs to be r times the angle increment / 2 pi.
this.angle += omega;
this.motionY -= 0.04D * (double)this.particleGravity; @Override
this.motionZ = radius * omega * Math.cos(angle); public void onUpdate(){
this.motionX = radius * omega * Math.sin(angle);
this.moveEntity(motionX, motionY, motionZ);
if(this.particleAge > this.particleMaxAge / 2){ this.prevPosX = this.posX;
this.setAlphaF(1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge); this.prevPosY = this.posY;
} this.prevPosZ = this.posZ;
} if(this.particleAge++ >= this.particleMaxAge){
this.setExpired();
}
// This is in radians per tick...
double omega = Math.signum(speed) * ((Math.PI * 2) / 20 - speed / (20 * radius));
// v = r times omega; therefore the normalised velocity vector needs to be r times the angle increment / 2 pi.
this.angle += omega;
this.motionY -= 0.04D * (double)this.particleGravity;
this.motionZ = radius * omega * Math.cos(angle);
this.motionX = radius * omega * Math.sin(angle);
this.move(motionX, motionY, motionZ);
if(this.particleAge > this.particleMaxAge / 2){
this.setAlphaF(
1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
}
}
} }
@@ -1,20 +1,17 @@
package electroblob.wizardry.client.particle; package electroblob.wizardry.client.particle;
import java.util.List;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.Particle; import net.minecraft.client.particle.Particle;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
@@ -23,6 +20,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
* Abstract superclass for all particles that use custom textures. This is intended to centralise as much code as * Abstract superclass for all particles that use custom textures. This is intended to centralise as much code as
* possible; all subclasses need to do is to define the texture to use, how the frames are arranged (and which to * possible; all subclasses need to do is to define the texture to use, how the frames are arranged (and which to
* choose), and any properties like gravity and collisions. * choose), and any properties like gravity and collisions.
*
* @author Electroblob * @author Electroblob
* @since Wizardry 1.2 * @since Wizardry 1.2
*/ */
@@ -40,33 +38,41 @@ public abstract class ParticleCustomTexture extends Particle {
this.init(); this.init();
} }
public ParticleCustomTexture(World world, double x, double y, double z, double vx, double vy, double vz, int maxAge){ public ParticleCustomTexture(World world, double x, double y, double z, double vx, double vy, double vz,
int maxAge){
this(world, x, y, z, vx, vy, vz); this(world, x, y, z, vx, vy, vz);
this.particleMaxAge = maxAge; this.particleMaxAge = maxAge;
} }
/** Called from both constructors to set constants, avoiding duplicate code. Common fields to set here /**
* include: particleScale, particleGravity, canCollide, fullBrightness and setting the texture index. */ * Called from both constructors to set constants, avoiding duplicate code. Common fields to set here include:
* particleScale, particleGravity, canCollide, fullBrightness and setting the texture index.
*/
public abstract void init(); public abstract void init();
/** Returns a ResourceLocation for the particle's texture sheet. Do not create a new ResourceLocation in this
* method, only return a constant. */ /**
* Returns a ResourceLocation for the particle's texture sheet. Do not create a new ResourceLocation in this method,
* only return a constant.
*/
public abstract ResourceLocation getTexture(); public abstract ResourceLocation getTexture();
/** Returns how many 'frames' there are in the x direction on the texture. */ /** Returns how many 'frames' there are in the x direction on the texture. */
protected abstract int getXFrames(); protected abstract int getXFrames();
/** Returns how many 'frames' there are in the y direction on the texture. */ /** Returns how many 'frames' there are in the y direction on the texture. */
protected abstract int getYFrames(); protected abstract int getYFrames();
/* There are 4 layers of particles, specified as 0-3 by the method below. /* There are 4 layers of particles, specified as 0-3 by the method below. - Layer 0 causes the normal particles.png
* - Layer 0 causes the normal particles.png to be bound to the render engine for normal particles. * to be bound to the render engine for normal particles. - Layer 1 causes the block textures to be bound to the
* - Layer 1 causes the block textures to be bound to the render engine for digging fx and falling fx. * render engine for digging fx and falling fx. - Layer 2 causes the item textures to be bound to the render engine
* - Layer 2 causes the item textures to be bound to the render engine for tool breaking fx, snowballpoofs, slime particles, etc. * for tool breaking fx, snowballpoofs, slime particles, etc. - Layer 3 is not used in vanilla minecraft and was
* - Layer 3 is not used in vanilla minecraft and was presumably added by forge for exactly this reason. * presumably added by forge for exactly this reason. This means no texture is bound by vanilla minecraft, meaning
* This means no texture is bound by vanilla minecraft, meaning you are free to do as you wish without possibly * you are free to do as you wish without possibly overwriting vanilla particles. Mod particles won't be overwritten
* overwriting vanilla particles. Mod particles won't be overwritten anyway since they bind their own textures. * anyway since they bind their own textures. It is of course important to bind the texture every time you render a
* It is of course important to bind the texture every time you render a custom particle, but I don't see how * custom particle, but I don't see how you could do it any other way, since you don't have access to
* you could do it any other way, since you don't have access to EffectRenderer. */ * EffectRenderer. */
@Override @Override
public int getFXLayer() { public int getFXLayer(){
// This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer. // This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer.
return 3; return 3;
} }
@@ -78,73 +84,75 @@ public abstract class ParticleCustomTexture extends Particle {
} }
// Overridden to fix the bug with vanilla that makes particles frictionless. (y != y... seriously, Mojang?) // Overridden to fix the bug with vanilla that makes particles frictionless. (y != y... seriously, Mojang?)
@Override // TESTME: Probably no longer necessary.
public void moveEntity(double x, double y, double z){ // @Override
// public void move(double x, double y, double z){
double d0 = y; //
// double d0 = y;
if (this.canCollide) //
{ // if (this.canCollide)
List<AxisAlignedBB> list = this.worldObj.getCollisionBoxes((Entity)null, this.getEntityBoundingBox().addCoord(x, y, z)); // {
// List<AxisAlignedBB> list = this.world.getCollisionBoxes((Entity)null, this.getBoundingBox().addCoord(x, y, z));
for (AxisAlignedBB axisalignedbb : list) //
{ // for (AxisAlignedBB axisalignedbb : list)
y = axisalignedbb.calculateYOffset(this.getEntityBoundingBox(), y); // {
} // y = axisalignedbb.calculateYOffset(this.getBoundingBox(), y);
// }
this.setEntityBoundingBox(this.getEntityBoundingBox().offset(0.0D, y, 0.0D)); //
// this.setBoundingBox(this.getBoundingBox().offset(0.0D, y, 0.0D));
for (AxisAlignedBB axisalignedbb1 : list) //
{ // for (AxisAlignedBB axisalignedbb1 : list)
x = axisalignedbb1.calculateXOffset(this.getEntityBoundingBox(), x); // {
} // x = axisalignedbb1.calculateXOffset(this.getBoundingBox(), x);
// }
this.setEntityBoundingBox(this.getEntityBoundingBox().offset(x, 0.0D, 0.0D)); //
// this.setBoundingBox(this.getBoundingBox().offset(x, 0.0D, 0.0D));
for (AxisAlignedBB axisalignedbb2 : list) //
{ // for (AxisAlignedBB axisalignedbb2 : list)
z = axisalignedbb2.calculateZOffset(this.getEntityBoundingBox(), z); // {
} // z = axisalignedbb2.calculateZOffset(this.getBoundingBox(), z);
// }
this.setEntityBoundingBox(this.getEntityBoundingBox().offset(0.0D, 0.0D, z)); //
} // this.setBoundingBox(this.getBoundingBox().offset(0.0D, 0.0D, z));
else // }
{ // else
this.setEntityBoundingBox(this.getEntityBoundingBox().offset(x, y, z)); // {
} // this.setBoundingBox(this.getBoundingBox().offset(x, y, z));
// }
this.resetPositionToBB(); //
this.isCollided = d0 != y && d0 < 0.0D; // this.resetPositionToBB();
// this.onGround = d0 != y && d0 < 0.0D;
/* Can never be true! - But this doesn't seem to make any difference anyway. //
if (x != x) // /* Can never be true! - But this doesn't seem to make any difference anyway.
{ // if (x != x)
this.motionX = 0.0D; // {
} // this.motionX = 0.0D;
// }
if (z != z) //
{ // if (z != z)
this.motionZ = 0.0D; // {
} // this.motionZ = 0.0D;
*/ // }
} // */
// }
// Overridden to bind the new texture. I think this can be done with TextureAtlasSprite, but this works as it is // Overridden to bind the new texture. I think this can be done with TextureAtlasSprite, but this works as it is
// so I'm not changing it for the time being. // so I'm not changing it for the time being.
@Override @Override
public void renderParticle(VertexBuffer buffer, Entity viewer, float partialTicks, float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ){ public void renderParticle(BufferBuilder buffer, Entity viewer, float partialTicks, float rotationX, float rotationZ,
float rotationYZ, float rotationXY, float rotationXZ){
GlStateManager.pushMatrix();
GlStateManager.pushAttrib();
GlStateManager.pushMatrix();
this.applyGLStateChanges(); this.applyGLStateChanges();
// This stuff does the shading. It vanilla does this later on for each point, but this also seems to work. // This stuff does the shading. It vanilla does this later on for each point, but this also seems to work.
int brightness = this.getBrightnessForRender(partialTicks); int brightness = this.getBrightnessForRender(partialTicks);
int lightmapX = brightness % 65536; int lightmapX = brightness % 65536;
int lightmapY = brightness / 65536; int lightmapY = brightness / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)lightmapX / 1.0F, (float)lightmapY / 1.0F); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)lightmapX / 1.0F,
(float)lightmapY / 1.0F);
RenderHelper.disableStandardItemLighting(); RenderHelper.disableStandardItemLighting();
Minecraft.getMinecraft().getTextureManager().bindTexture(getTexture()); Minecraft.getMinecraft().getTextureManager().bindTexture(getTexture());
@@ -152,9 +160,9 @@ public abstract class ParticleCustomTexture extends Particle {
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
float u1 = (float)this.particleTextureIndexX / (float)getXFrames(); float u1 = (float)this.particleTextureIndexX / (float)getXFrames();
float u2 = u1 + 1.0f/getXFrames(); float u2 = u1 + 1.0f / getXFrames();
float v1 = (float)this.particleTextureIndexY / (float)getYFrames(); float v1 = (float)this.particleTextureIndexY / (float)getYFrames();
float v2 = v1 + 1.0f/getYFrames(); float v2 = v1 + 1.0f / getYFrames();
float scale = 0.1F * this.particleScale; float scale = 0.1F * this.particleScale;
// I'm pretty sure these were always static. // I'm pretty sure these were always static.
@@ -166,27 +174,41 @@ public abstract class ParticleCustomTexture extends Particle {
float y = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY); float y = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY);
float z = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ); float z = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ);
buffer.pos((double)(x - rotationX * scale - rotationXY * scale), (double)(y - rotationZ * scale), (double)(z - rotationYZ * scale - rotationXZ * scale)).tex(u2, v2).color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex(); buffer.pos((double)(x - rotationX * scale - rotationXY * scale), (double)(y - rotationZ * scale),
buffer.pos((double)(x - rotationX * scale + rotationXY * scale), (double)(y + rotationZ * scale), (double)(z - rotationYZ * scale + rotationXZ * scale)).tex(u2, v1).color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex(); (double)(z - rotationYZ * scale - rotationXZ * scale)).tex(u2, v2)
buffer.pos((double)(x + rotationX * scale + rotationXY * scale), (double)(y + rotationZ * scale), (double)(z + rotationYZ * scale + rotationXZ * scale)).tex(u1, v1).color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex(); .color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex();
buffer.pos((double)(x + rotationX * scale - rotationXY * scale), (double)(y - rotationZ * scale), (double)(z + rotationYZ * scale - rotationXZ * scale)).tex(u1, v2).color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex();; buffer.pos((double)(x - rotationX * scale + rotationXY * scale), (double)(y + rotationZ * scale),
(double)(z - rotationYZ * scale + rotationXZ * scale)).tex(u2, v1)
.color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex();
buffer.pos((double)(x + rotationX * scale + rotationXY * scale), (double)(y + rotationZ * scale),
(double)(z + rotationYZ * scale + rotationXZ * scale)).tex(u1, v1)
.color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex();
buffer.pos((double)(x + rotationX * scale - rotationXY * scale), (double)(y - rotationZ * scale),
(double)(z + rotationYZ * scale - rotationXZ * scale)).tex(u1, v2)
.color(particleRed, particleGreen, particleBlue, particleAlpha).endVertex();
;
Tessellator.getInstance().draw(); Tessellator.getInstance().draw();
this.undoGLStateChanges(); this.undoGLStateChanges();
GlStateManager.popAttrib();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
/** Override to add any GL state changes, like blending. Does nothing by default. <b>State changes should be /**
* done using GLStateManager, not using GL11 directly</b> (as is the case with all rendering code now). */ * Override to add any GL state changes, like blending. Does nothing by default. <b>State changes should be done
public void applyGLStateChanges(){} * using GLStateManager, not using GL11 directly</b> (as is the case with all rendering code now).
*/
/** Override to undo any GL state changes, like blending. Does nothing by default. <b>State changes should be public void applyGLStateChanges(){
* done using GLStateManager, not using GL11 directly</b> (as is the case with all rendering code now). */ }
public void undoGLStateChanges(){}
/**
* Override to undo any GL state changes, like blending. Does nothing by default. <b>State changes should be done
* using GLStateManager, not using GL11 directly</b> (as is the case with all rendering code now).
*/
public void undoGLStateChanges(){
}
@Override @Override
public int getBrightnessForRender(float partialTick){ public int getBrightnessForRender(float partialTick){
@@ -1,7 +1,7 @@
package electroblob.wizardry.client.particle; package electroblob.wizardry.client.particle;
import net.minecraft.client.particle.Particle; import net.minecraft.client.particle.Particle;
import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
@@ -9,82 +9,70 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ParticleDarkMagic extends Particle { public class ParticleDarkMagic extends Particle {
/** Base spell texture index */
private int baseSpellTextureIndex = 128;
public ParticleDarkMagic(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float r, float g, float b) /** Base spell texture index */
{ private int baseSpellTextureIndex = 128;
super(par1World, par2, par4, par6, par8, par10, par12);
this.motionY *= 0.20000000298023224D;
this.particleRed = r;
this.particleGreen = g;
this.particleBlue = b;
this.particleScale *= 0.75F; public ParticleDarkMagic(World par1World, double par2, double par4, double par6, double par8, double par10,
this.particleMaxAge = (int)(8.0D / (Math.random() * 0.8D + 0.2D)); double par12, float r, float g, float b){
this.canCollide = true; super(par1World, par2, par4, par6, par8, par10, par12);
} this.motionY *= 0.20000000298023224D;
@Override this.particleRed = r;
public void renderParticle(VertexBuffer buffer, Entity entity, float partialTicks, float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ) this.particleGreen = g;
{ this.particleBlue = b;
float f6 = ((float)this.particleAge + partialTicks) / (float)this.particleMaxAge * 32.0F;
if (f6 < 0.0F) this.particleScale *= 0.75F;
{ this.particleMaxAge = (int)(8.0D / (Math.random() * 0.8D + 0.2D));
f6 = 0.0F; this.canCollide = true;
} }
if (f6 > 1.0F) @Override
{ public void renderParticle(BufferBuilder buffer, Entity entity, float partialTicks, float rotationX, float rotationZ,
f6 = 1.0F; float rotationYZ, float rotationXY, float rotationXZ){
} float f6 = ((float)this.particleAge + partialTicks) / (float)this.particleMaxAge * 32.0F;
super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ); if(f6 < 0.0F){
} f6 = 0.0F;
}
/** if(f6 > 1.0F){
* Called to update the entity's position/logic. f6 = 1.0F;
*/ }
public void onUpdate()
{
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if (this.particleAge++ >= this.particleMaxAge) super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ);
{ }
this.setExpired();
}
this.setParticleTextureIndex(this.baseSpellTextureIndex + (7 - this.particleAge * 8 / this.particleMaxAge)); /**
this.motionY += 0.004D; * Called to update the entity's position/logic.
this.moveEntity(this.motionX, this.motionY, this.motionZ); */
/* public void onUpdate(){
if (this.posY == this.prevPosY) this.prevPosX = this.posX;
{ this.prevPosY = this.posY;
this.motionX *= 1.1D; this.prevPosZ = this.posZ;
this.motionZ *= 1.1D;
}
*/
this.motionX *= 0.9599999785423279D;
this.motionY *= 0.9599999785423279D;
this.motionZ *= 0.9599999785423279D;
if (this.isCollided) if(this.particleAge++ >= this.particleMaxAge){
{ this.setExpired();
this.motionX *= 0.699999988079071D; }
this.motionZ *= 0.699999988079071D;
}
}
/** this.setParticleTextureIndex(this.baseSpellTextureIndex + (7 - this.particleAge * 8 / this.particleMaxAge));
* Sets the base spell texture index this.motionY += 0.004D;
*/ this.move(this.motionX, this.motionY, this.motionZ);
public void setBaseSpellTextureIndex(int par1) /* if (this.posY == this.prevPosY) { this.motionX *= 1.1D; this.motionZ *= 1.1D; } */
{ this.motionX *= 0.9599999785423279D;
this.baseSpellTextureIndex = par1; this.motionY *= 0.9599999785423279D;
} this.motionZ *= 0.9599999785423279D;
if(this.onGround){
this.motionX *= 0.699999988079071D;
this.motionZ *= 0.699999988079071D;
}
}
/**
* Sets the base spell texture index
*/
public void setBaseSpellTextureIndex(int par1){
this.baseSpellTextureIndex = par1;
}
} }
@@ -7,51 +7,42 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ParticleDust extends Particle { public class ParticleDust extends Particle {
private final boolean shaded; private final boolean shaded;
public ParticleDust(World par1World, double x, double y, double z, double par8, double par10, double par12, float r, float g, float b, boolean shaded)
{
super(par1World, x, y, z, par8, par10, par12);
this.particleRed = r;
this.particleGreen = g;
this.particleBlue = b;
this.setParticleTextureIndex(0);
this.setSize(0.01F, 0.01F);
this.particleScale *= this.rand.nextFloat() + 0.2F;
this.motionX = par8;
this.motionY = par10;
this.motionZ = par12;
this.particleMaxAge = (int)(16.0D / (Math.random() * 0.8D + 0.2D));
this.shaded = shaded;
}
/** public ParticleDust(World par1World, double x, double y, double z, double par8, double par10, double par12, float r,
* Called to update the entity's position/logic. float g, float b, boolean shaded){
*/ super(par1World, x, y, z, par8, par10, par12);
public void onUpdate() this.particleRed = r;
{ this.particleGreen = g;
this.prevPosX = this.posX; this.particleBlue = b;
this.prevPosY = this.posY; this.setParticleTextureIndex(0);
this.prevPosZ = this.posZ; this.setSize(0.01F, 0.01F);
//this.moveEntity(this.motionX, this.motionY, this.motionZ); this.particleScale *= this.rand.nextFloat() + 0.2F;
this.motionX = par8;
this.motionY = par10;
this.motionZ = par12;
this.particleMaxAge = (int)(16.0D / (Math.random() * 0.8D + 0.2D));
this.shaded = shaded;
}
if (this.particleMaxAge-- <= 0) /**
{ * Called to update the entity's position/logic.
this.setExpired(); */
} public void onUpdate(){
} this.prevPosX = this.posX;
this.prevPosY = this.posY;
@Override this.prevPosZ = this.posZ;
public int getBrightnessForRender(float par1) // this.moveEntity(this.motionX, this.motionY, this.motionZ);
{
return shaded ? super.getBrightnessForRender(par1) : 15728880; if(this.particleMaxAge-- <= 0){
} this.setExpired();
/* }
@Override }
public float getBrightness(float par1)
{ @Override
return shaded ? super.getBrightness(par1) : 1.0F; public int getBrightnessForRender(float par1){
} return shaded ? super.getBrightnessForRender(par1) : 15728880;
*/ }
/* @Override public float getBrightness(float par1) { return shaded ? super.getBrightness(par1) : 1.0F; } */
} }
@@ -7,44 +7,43 @@ import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ParticleGiantBubble extends Particle public class ParticleGiantBubble extends Particle {
{ /**
/** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would * The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would be
* be any, but I may as well.) */ * any, but I may as well.)
*/
public static final String NAME = Wizardry.MODID + "magicbubble"; public static final String NAME = Wizardry.MODID + "magicbubble";
public ParticleGiantBubble(World par1World, double par2, double par4, double par6, double par8, double par10, double par12)
{
super(par1World, par2, par4, par6, par8, par10, par12);
this.particleRed = 1.0F;
this.particleGreen = 1.0F;
this.particleBlue = 1.0F;
this.setParticleTextureIndex(32);
this.setSize(0.02F, 0.02F);
this.particleScale *= this.rand.nextFloat() * 0.6F + 0.2F;
this.motionX = par8 * 0.20000000298023224D + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.02F);
this.motionY = par10 * 0.20000000298023224D + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.02F);
this.motionZ = par12 * 0.20000000298023224D + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.02F);
this.particleMaxAge = (int)(8.0D / (Math.random() * 0.8D + 0.2D));
}
/** public ParticleGiantBubble(World par1World, double par2, double par4, double par6, double par8, double par10,
* Called to update the entity's position/logic. double par12){
*/ super(par1World, par2, par4, par6, par8, par10, par12);
public void onUpdate() this.particleRed = 1.0F;
{ this.particleGreen = 1.0F;
this.prevPosX = this.posX; this.particleBlue = 1.0F;
this.prevPosY = this.posY; this.setParticleTextureIndex(32);
this.prevPosZ = this.posZ; this.setSize(0.02F, 0.02F);
this.motionY += 0.002D; this.particleScale *= this.rand.nextFloat() * 0.6F + 0.2F;
this.moveEntity(this.motionX, this.motionY, this.motionZ); this.motionX = par8 * 0.20000000298023224D + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.02F);
this.motionX *= 0.8500000238418579D; this.motionY = par10 * 0.20000000298023224D + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.02F);
this.motionY *= 0.8500000238418579D; this.motionZ = par12 * 0.20000000298023224D + (double)((float)(Math.random() * 2.0D - 1.0D) * 0.02F);
this.motionZ *= 0.8500000238418579D; this.particleMaxAge = (int)(8.0D / (Math.random() * 0.8D + 0.2D));
}
if (this.particleMaxAge-- <= 0) /**
{ * Called to update the entity's position/logic.
this.setExpired(); */
} public void onUpdate(){
} this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
this.motionY += 0.002D;
this.move(this.motionX, this.motionY, this.motionZ);
this.motionX *= 0.8500000238418579D;
this.motionY *= 0.8500000238418579D;
this.motionZ *= 0.8500000238418579D;
if(this.particleMaxAge-- <= 0){
this.setExpired();
}
}
} }
@@ -9,8 +9,9 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ParticleIce extends ParticleCustomTexture { public class ParticleIce extends ParticleCustomTexture {
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/ice_particles.png"); private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
"textures/particle/ice_particles.png");
public ParticleIce(World world, double x, double y, double z, double vx, double vy, double vz){ public ParticleIce(World world, double x, double y, double z, double vx, double vy, double vz){
super(world, x, y, z, vx, vy, vz); super(world, x, y, z, vx, vy, vz);
} }
@@ -18,7 +19,7 @@ public class ParticleIce extends ParticleCustomTexture {
public ParticleIce(World world, double x, double y, double z, double vx, double vy, double vz, int maxAge){ public ParticleIce(World world, double x, double y, double z, double vx, double vy, double vz, int maxAge){
super(world, x, y, z, vx, vy, vz, maxAge); super(world, x, y, z, vx, vy, vz, maxAge);
} }
@Override @Override
public void init(){ public void init(){
this.setParticleTextureIndex(rand.nextInt(8)); this.setParticleTextureIndex(rand.nextInt(8));
@@ -28,7 +29,18 @@ public class ParticleIce extends ParticleCustomTexture {
this.fullBrightness = true; this.fullBrightness = true;
} }
@Override public ResourceLocation getTexture(){ return TEXTURE; } @Override
@Override protected int getXFrames(){ return 4; } public ResourceLocation getTexture(){
@Override protected int getYFrames(){ return 4; } return TEXTURE;
}
@Override
protected int getXFrames(){
return 4;
}
@Override
protected int getYFrames(){
return 4;
}
} }
@@ -8,9 +8,10 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ParticleLeaf extends ParticleCustomTexture { public class ParticleLeaf extends ParticleCustomTexture {
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/leaf_particles.png"); private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
"textures/particle/leaf_particles.png");
public ParticleLeaf(World world, double x, double y, double z, double vx, double vy, double vz){ public ParticleLeaf(World world, double x, double y, double z, double vx, double vy, double vz){
super(world, x, y, z, vx, vy, vz); super(world, x, y, z, vx, vy, vz);
} }
@@ -18,16 +19,27 @@ public class ParticleLeaf extends ParticleCustomTexture {
public ParticleLeaf(World world, double x, double y, double z, double vx, double vy, double vz, int maxAge){ public ParticleLeaf(World world, double x, double y, double z, double vx, double vy, double vz, int maxAge){
super(world, x, y, z, vx, vy, vz, maxAge); super(world, x, y, z, vx, vy, vz, maxAge);
} }
@Override
public void init() {
this.setParticleTextureIndex(rand.nextInt(16));
this.particleScale *= 1.4f;
this.particleGravity = 0;
this.canCollide = true;
}
@Override public ResourceLocation getTexture(){ return TEXTURE; } @Override
@Override protected int getXFrames(){ return 4; } public void init(){
@Override protected int getYFrames(){ return 4; } this.setParticleTextureIndex(rand.nextInt(16));
this.particleScale *= 1.4f;
this.particleGravity = 0;
this.canCollide = true;
}
@Override
public ResourceLocation getTexture(){
return TEXTURE;
}
@Override
protected int getXFrames(){
return 4;
}
@Override
protected int getYFrames(){
return 4;
}
} }
@@ -1,7 +1,7 @@
package electroblob.wizardry.client.particle; package electroblob.wizardry.client.particle;
import net.minecraft.client.particle.Particle; import net.minecraft.client.particle.Particle;
import net.minecraft.client.renderer.VertexBuffer; import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
@@ -9,39 +9,38 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ParticleMagicFlame extends Particle { public class ParticleMagicFlame extends Particle {
/** The scale of the flame particle */
private float flameScale;
public ParticleMagicFlame(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, int maxAge, float scale) /** The scale of the flame particle */
{ private float flameScale;
super(par1World, par2, par4, par6, par8, par10, par12);
this.motionX = this.motionX * 0.009999999776482582D + par8;
this.motionY = this.motionY * 0.009999999776482582D + par10;
this.motionZ = this.motionZ * 0.009999999776482582D + par12;
this.flameScale = scale;
this.particleRed = this.particleGreen = this.particleBlue = 1.0F;
if(maxAge == 0){
this.particleMaxAge = (int)(2.0D / (Math.random() * 0.8D + 0.2D));
}else{
this.particleMaxAge = maxAge;
}
// IDEA: Make the particles for ray spells collide properly and not spawn on the other side of stuff.
this.canCollide = false;
this.setParticleTextureIndex(48);
}
@Override public ParticleMagicFlame(World par1World, double par2, double par4, double par6, double par8, double par10,
public void renderParticle(VertexBuffer buffer, Entity entity, float partialTicks, float rotationX, float rotationZ, float rotationYZ, float rotationXY, float rotationXZ) double par12, int maxAge, float scale){
{ super(par1World, par2, par4, par6, par8, par10, par12);
float f6 = ((float)this.particleAge + partialTicks) / (float)this.particleMaxAge; this.motionX = this.motionX * 0.009999999776482582D + par8;
this.particleScale = this.flameScale * (1.0F - f6 * f6 * 0.5F); this.motionY = this.motionY * 0.009999999776482582D + par10;
super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ); this.motionZ = this.motionZ * 0.009999999776482582D + par12;
} this.flameScale = scale;
this.particleRed = this.particleGreen = this.particleBlue = 1.0F;
if(maxAge == 0){
this.particleMaxAge = (int)(2.0D / (Math.random() * 0.8D + 0.2D));
}else{
this.particleMaxAge = maxAge;
}
// IDEA: Make the particles for ray spells collide properly and not spawn on the other side of stuff.
this.canCollide = false;
this.setParticleTextureIndex(48);
}
@Override @Override
public int getBrightnessForRender(float par1) public void renderParticle(BufferBuilder buffer, Entity entity, float partialTicks, float rotationX, float rotationZ,
{ float rotationYZ, float rotationXY, float rotationXZ){
return 256; float f6 = ((float)this.particleAge + partialTicks) / (float)this.particleMaxAge;
} this.particleScale = this.flameScale * (1.0F - f6 * f6 * 0.5F);
super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ);
}
@Override
public int getBrightnessForRender(float par1){
return 256;
}
} }
@@ -13,81 +13,95 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ParticlePath extends ParticleCustomTexture { public class ParticlePath extends ParticleCustomTexture {
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/path_particles.png");
private final double originX, originY, originZ;
public ParticlePath(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g, float b){ private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
"textures/particle/path_particles.png");
private final double originX, originY, originZ;
public ParticlePath(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g,
float b){
super(world, x, y, z, vx, vy, vz); super(world, x, y, z, vx, vy, vz);
this.setRBGColorF(r, g, b); this.setRBGColorF(r, g, b);
this.originX = x; this.originX = x;
this.originY = y; this.originY = y;
this.originZ = z; this.originZ = z;
} }
public ParticlePath(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g, float b, int maxAge){ public ParticlePath(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g,
float b, int maxAge){
super(world, x, y, z, vx, vy, vz, maxAge); super(world, x, y, z, vx, vy, vz, maxAge);
this.setRBGColorF(r, g, b); this.setRBGColorF(r, g, b);
this.originX = x; this.originX = x;
this.originY = y; this.originY = y;
this.originZ = z; this.originZ = z;
} }
@Override
public void init(){
this.setParticleTextureIndex(0);
// Set to a constant to remove the randomness from Particle.
this.particleScale = 1.25f;
this.particleGravity = 0;
this.fullBrightness = true;
this.canCollide = false;
}
@Override public ResourceLocation getTexture(){ return TEXTURE; }
@Override protected int getXFrames(){ return 1; }
@Override protected int getYFrames(){ return 1; }
@Override @Override
public void onUpdate(){ public void init(){
this.setParticleTextureIndex(0);
// Set to a constant to remove the randomness from Particle.
this.particleScale = 1.25f;
this.particleGravity = 0;
this.fullBrightness = true;
this.canCollide = false;
}
@Override
public ResourceLocation getTexture(){
return TEXTURE;
}
@Override
protected int getXFrames(){
return 1;
}
@Override
protected int getYFrames(){
return 1;
}
@Override
public void onUpdate(){
this.prevPosX = this.posX; this.prevPosX = this.posX;
this.prevPosY = this.posY; this.prevPosY = this.posY;
this.prevPosZ = this.posZ; this.prevPosZ = this.posZ;
if (this.particleAge++ >= this.particleMaxAge) if(this.particleAge++ >= this.particleMaxAge){
{ this.setExpired();
this.setExpired(); }
}
this.moveEntity(this.motionX, this.motionY, this.motionZ); this.move(this.motionX, this.motionY, this.motionZ);
// Fading // Fading
if(this.particleAge > this.particleMaxAge / 2){ if(this.particleAge > this.particleMaxAge / 2){
this.setAlphaF(1.0F - 2 * (((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge)); this.setAlphaF(1.0F
} - 2 * (((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge));
}
if(this.particleAge % Clairvoyance.PARTICLE_MOVEMENT_INTERVAL == 0){
this.setPosition(this.originX, this.originY, this.originZ); if(this.particleAge % Clairvoyance.PARTICLE_MOVEMENT_INTERVAL == 0){
this.prevPosX = this.posX; this.setPosition(this.originX, this.originY, this.originZ);
this.prevPosY = this.posY; this.prevPosX = this.posX;
this.prevPosZ = this.posZ; this.prevPosY = this.posY;
} this.prevPosZ = this.posZ;
}
}
}
@Override
public void applyGLStateChanges(){ @Override
GlStateManager.enableBlend(); public void applyGLStateChanges(){
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GlStateManager.enableBlend();
// TESTME: Are these two actually necessary? GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GlStateManager.disableLighting(); // TESTME: Are these two actually necessary?
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); GlStateManager.disableLighting();
} OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
}
@Override
public void undoGLStateChanges(){ @Override
GlStateManager.disableBlend(); public void undoGLStateChanges(){
GlStateManager.enableLighting(); GlStateManager.disableBlend();
} GlStateManager.enableLighting();
}
} }
@@ -6,54 +6,56 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ParticleRotatingSparkle extends ParticleSparkle { public class ParticleRotatingSparkle extends ParticleSparkle {
private double angle;
private double radius;
private double speed;
public ParticleRotatingSparkle(World world, int maxAge, double originX, double originZ, double radius, double yPos, float r, float g , float b){ private double angle;
super(world, 0, 0, 0, 0, 0, 0, r, g, b, maxAge); private double radius;
this.angle = this.rand.nextDouble() * Math.PI * 2; private double speed;
double x = originX - Math.cos(angle)*radius;
double z = originZ + radius*Math.sin(angle);
this.radius = radius;
this.setPosition(x, yPos, z);
this.prevPosX = x;
this.prevPosY = yPos;
this.prevPosZ = z;
if(rand.nextBoolean()){
speed = rand.nextDouble()*2 + 1;
}else{
speed = rand.nextDouble()*-2 - 1;
}
this.multipleParticleScaleBy(1.5f);
}
@Override public ParticleRotatingSparkle(World world, int maxAge, double originX, double originZ, double radius, double yPos,
public void onUpdate(){ float r, float g, float b){
super(world, 0, 0, 0, 0, 0, 0, r, g, b, maxAge);
this.prevPosX = this.posX; this.angle = this.rand.nextDouble() * Math.PI * 2;
this.prevPosY = this.posY; double x = originX - Math.cos(angle) * radius;
this.prevPosZ = this.posZ; double z = originZ + radius * Math.sin(angle);
this.radius = radius;
this.setPosition(x, yPos, z);
this.prevPosX = x;
this.prevPosY = yPos;
this.prevPosZ = z;
if(rand.nextBoolean()){
speed = rand.nextDouble() * 2 + 1;
}else{
speed = rand.nextDouble() * -2 - 1;
}
this.multipleParticleScaleBy(1.5f);
}
if(this.particleAge++ >= this.particleMaxAge){ @Override
this.setExpired(); public void onUpdate(){
}
// This is in radians per tick...
double omega = Math.signum(speed) * ((Math.PI*2)/20 - speed/(20*radius));
// v = r times omega; therefore the normalised velocity vector needs to be r times the angle increment / 2 pi.
this.angle += omega;
this.motionY -= 0.04D * (double)this.particleGravity; this.prevPosX = this.posX;
this.motionZ = radius * omega * Math.cos(angle); this.prevPosY = this.posY;
this.motionX = radius * omega * Math.sin(angle); this.prevPosZ = this.posZ;
this.moveEntity(motionX, motionY, motionZ);
if(this.particleAge > this.particleMaxAge / 2){ if(this.particleAge++ >= this.particleMaxAge){
this.setAlphaF(1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge); this.setExpired();
} }
} // This is in radians per tick...
double omega = Math.signum(speed) * ((Math.PI * 2) / 20 - speed / (20 * radius));
// v = r times omega; therefore the normalised velocity vector needs to be r times the angle increment / 2 pi.
this.angle += omega;
this.motionY -= 0.04D * (double)this.particleGravity;
this.motionZ = radius * omega * Math.cos(angle);
this.motionX = radius * omega * Math.sin(angle);
this.move(motionX, motionY, motionZ);
if(this.particleAge > this.particleMaxAge / 2){
this.setAlphaF(
1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
}
}
} }
@@ -8,9 +8,10 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ParticleSnow extends ParticleCustomTexture { public class ParticleSnow extends ParticleCustomTexture {
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/snow_particles.png"); private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
"textures/particle/snow_particles.png");
public ParticleSnow(World world, double x, double y, double z, double vx, double vy, double vz){ public ParticleSnow(World world, double x, double y, double z, double vx, double vy, double vz){
super(world, x, y, z, vx, vy, vz); super(world, x, y, z, vx, vy, vz);
} }
@@ -18,16 +19,27 @@ public class ParticleSnow extends ParticleCustomTexture {
public ParticleSnow(World world, double x, double y, double z, double vx, double vy, double vz, int maxAge){ public ParticleSnow(World world, double x, double y, double z, double vx, double vy, double vz, int maxAge){
super(world, x, y, z, vx, vy, vz, maxAge); super(world, x, y, z, vx, vy, vz, maxAge);
} }
@Override @Override
public void init(){ public void init(){
this.setParticleTextureIndex(rand.nextInt(8)); this.setParticleTextureIndex(rand.nextInt(8));
this.particleScale *= 0.6f; this.particleScale *= 0.6f;
this.particleGravity = 0; this.particleGravity = 0;
this.canCollide = true; this.canCollide = true;
} }
@Override public ResourceLocation getTexture(){ return TEXTURE; } @Override
@Override protected int getXFrames(){ return 4; } public ResourceLocation getTexture(){
@Override protected int getYFrames(){ return 4; } return TEXTURE;
}
@Override
protected int getXFrames(){
return 4;
}
@Override
protected int getYFrames(){
return 4;
}
} }
@@ -12,47 +12,59 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ParticleSpark extends ParticleCustomTexture { public class ParticleSpark extends ParticleCustomTexture {
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/lightning_particles.png");
public ParticleSpark(World world, double x, double y, double z, double vx, double vy, double vz){
// Max age is always 3.
super(world, x, y, z, vx, vy, vz, 3);
}
@Override
public void init(){
// Multiplied by 4 because the index works slightly differently for spark particles.
this.setParticleTextureIndex(rand.nextInt(8)*4);
this.particleScale *= 1.4f;
this.fullBrightness = true;
this.canCollide = false;
}
@Override private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
public void onUpdate(){ "textures/particle/lightning_particles.png");
super.onUpdate();
// Well this is handy! Looks like vanilla uses the texture index like this too. public ParticleSpark(World world, double x, double y, double z, double vx, double vy, double vz){
this.nextTextureIndexX(); // Max age is always 3.
} super(world, x, y, z, vx, vy, vz, 3);
}
@Override public ResourceLocation getTexture(){ return TEXTURE; }
@Override protected int getXFrames(){ return 4; } @Override
@Override protected int getYFrames(){ return 8; } public void init(){
// Multiplied by 4 because the index works slightly differently for spark particles.
@Override this.setParticleTextureIndex(rand.nextInt(8) * 4);
public void applyGLStateChanges(){ this.particleScale *= 1.4f;
GlStateManager.enableBlend(); this.fullBrightness = true;
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); this.canCollide = false;
// TESTME: Are these two actually necessary? }
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); @Override
} public void onUpdate(){
super.onUpdate();
@Override // Well this is handy! Looks like vanilla uses the texture index like this too.
public void undoGLStateChanges(){ this.nextTextureIndexX();
GlStateManager.disableBlend(); }
GlStateManager.enableLighting();
} @Override
public ResourceLocation getTexture(){
return TEXTURE;
}
@Override
protected int getXFrames(){
return 4;
}
@Override
protected int getYFrames(){
return 8;
}
@Override
public void applyGLStateChanges(){
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
// TESTME: Are these two actually necessary?
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
}
@Override
public void undoGLStateChanges(){
GlStateManager.disableBlend();
GlStateManager.enableLighting();
}
} }
@@ -8,89 +8,104 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ParticleSparkle extends ParticleCustomTexture { public class ParticleSparkle extends ParticleCustomTexture {
/* I have now figured out what particle factories are for: they separate out the individual uses of the varargs /* I have now figured out what particle factories are for: they separate out the individual uses of the varargs
* parameter in spawnParticle so they are kept with the particle class. For my purposes, it would be easier to do * parameter in spawnParticle so they are kept with the particle class. For my purposes, it would be easier to do
* that in the particle spawning method itself. */ * that in the particle spawning method itself. */
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID, "textures/particle/sparkle_particles.png"); private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
"textures/particle/sparkle_particles.png");
// NOTE: Uncomment once 2.1.0 is released // NOTE: Uncomment once 2.1.0 is released
//private final float initialRed; // private final float initialRed;
//private final float initialGreen; // private final float initialGreen;
//private final float initialBlue; // private final float initialBlue;
// TODO: Assign these via the constructors, as part of the refactoring for particle parameters. // TODO: Assign these via the constructors, as part of the refactoring for particle parameters.
// NOTE: Uncomment once 2.1.0 is released // NOTE: Uncomment once 2.1.0 is released
// private final float fadeRed = 1; // private final float fadeRed = 1;
// private final float fadeGreen = 1; // private final float fadeGreen = 1;
// private final float fadeBlue = 0; // private final float fadeBlue = 0;
public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g, float b){ public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g,
float b){
super(world, x, y, z, vx, vy, vz); super(world, x, y, z, vx, vy, vz);
this.setRBGColorF(r, g, b); this.setRBGColorF(r, g, b);
// NOTE: Uncomment once 2.1.0 is released // NOTE: Uncomment once 2.1.0 is released
//initialRed = r; // initialRed = r;
//initialGreen = g; // initialGreen = g;
//initialBlue = b; // initialBlue = b;
this.particleMaxAge = 48 + this.rand.nextInt(12); this.particleMaxAge = 48 + this.rand.nextInt(12);
} }
public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g, float b, int maxAge){ public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g,
float b, int maxAge){
super(world, x, y, z, vx, vy, vz, maxAge); super(world, x, y, z, vx, vy, vz, maxAge);
this.setRBGColorF(r, g, b); this.setRBGColorF(r, g, b);
// NOTE: Uncomment once 2.1.0 is released // NOTE: Uncomment once 2.1.0 is released
//initialRed = r; // initialRed = r;
//initialGreen = g; // initialGreen = g;
//initialBlue = b; // initialBlue = b;
} }
public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g, float b, boolean doGravity){
this(world, x, y, z, vx, vy, vz, r, g, b);
this.particleGravity = doGravity ? 1 : 0;
}
public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g, float b, int maxAge, boolean doGravity){
this(world, x, y, z, vx, vy, vz, r, g, b, maxAge);
this.particleGravity = doGravity ? 1 : 0;
}
@Override
public void init(){
this.setParticleTextureIndex(rand.nextInt(16));
this.particleScale *= 0.75f;
this.particleGravity = 0;
this.canCollide = false;
this.fullBrightness = true;
}
@Override public ResourceLocation getTexture(){ return TEXTURE; }
@Override protected int getXFrames(){ return 4; }
@Override protected int getYFrames(){ return 4; }
@Override public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g,
public void onUpdate(){ float b, boolean doGravity){
this(world, x, y, z, vx, vy, vz, r, g, b);
super.onUpdate(); this.particleGravity = doGravity ? 1 : 0;
// Fading }
if(this.particleAge > this.particleMaxAge / 2){
this.setAlphaF(1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge); public ParticleSparkle(World world, double x, double y, double z, double vx, double vy, double vz, float r, float g,
} float b, int maxAge, boolean doGravity){
// Colour fading TODO Uncomment once 2.1.0 is released this(world, x, y, z, vx, vy, vz, r, g, b, maxAge);
// float ageFraction = (float)this.particleAge / (float)this.particleMaxAge; this.particleGravity = doGravity ? 1 : 0;
// this.setRBGColorF(this.initialRed + (this.fadeRed - this.initialRed)*ageFraction, }
// this.initialGreen + (this.fadeGreen - this.initialGreen)*ageFraction,
// this.initialBlue + (this.fadeBlue - this.initialBlue)*ageFraction); @Override
// public void init(){
// this.setParticleTextureIndex((this.particleAge * 11)/this.particleMaxAge); this.setParticleTextureIndex(rand.nextInt(16));
} this.particleScale *= 0.75f;
this.particleGravity = 0;
/* this.canCollide = false;
* As a side note, I see a lot of magic mods with fancy-looking particle effects that really seem to 'glow'. It's this.fullBrightness = true;
* actually not that hard - you simply create a reasonably high-res texture with translucency and then set the }
* OpenGL blend function to something like SRC_ALPHA, SRC_ALPHA or ONE, ONE. The thing is... they're not very
* Minecraft-y. I still maintain that part of wizardry's appeal is that it stays true to the game's pixelated charm, @Override
* rather than trying to make it something it's not. Still, the newer textures are much better than the defaults I public ResourceLocation getTexture(){
* used to use. return TEXTURE;
*/ }
@Override
protected int getXFrames(){
return 4;
}
@Override
protected int getYFrames(){
return 4;
}
@Override
public void onUpdate(){
super.onUpdate();
// Fading
if(this.particleAge > this.particleMaxAge / 2){
this.setAlphaF(
1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
}
// Colour fading TODO Uncomment once 2.1.0 is released
// float ageFraction = (float)this.particleAge / (float)this.particleMaxAge;
// this.setRBGColorF(this.initialRed + (this.fadeRed - this.initialRed)*ageFraction,
// this.initialGreen + (this.fadeGreen - this.initialGreen)*ageFraction,
// this.initialBlue + (this.fadeBlue - this.initialBlue)*ageFraction);
this.setParticleTextureIndex((this.particleAge * 11)/this.particleMaxAge);
}
/* As a side note, I see a lot of magic mods with fancy-looking particle effects that really seem to 'glow'. It's
* actually not that hard - you simply create a reasonably high-res texture with translucency and then set the
* OpenGL blend function to something like SRC_ALPHA, SRC_ALPHA or ONE, ONE. The thing is... they're not very
* Minecraft-y. I still maintain that part of wizardry's appeal is that it stays true to the game's pixelated charm,
* rather than trying to make it something it's not. Still, the newer textures are much better than the defaults I
* used to use. */
} }
@@ -9,75 +9,77 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class ParticleTornado extends ParticleDigging { public class ParticleTornado extends ParticleDigging {
private double angle;
private double radius;
private double speed;
/** Velocity of the tornado itself; in other words the velocity of the point the particle circles around. */
private double velX, velZ;
private boolean fullBrightness = false;
public ParticleTornado(World world, int maxAge, double originX, double originZ, double radius, double yPos, double velX, double velZ, IBlockState block){ private double angle;
super(world, 0, 0, 0, 0, 0, 0, block); private double radius;
this.angle = this.rand.nextDouble() * Math.PI * 2; private double speed;
double x = originX - Math.cos(angle)*radius; /** Velocity of the tornado itself; in other words the velocity of the point the particle circles around. */
double z = originZ + radius*Math.sin(angle); private double velX, velZ;
this.radius = radius; private boolean fullBrightness = false;
this.setPosition(x, yPos, z);
this.prevPosX = x;
this.prevPosY = yPos;
this.prevPosZ = z;
//this.particleScale *= 0.75F;
this.particleMaxAge = maxAge;
this.canCollide = false;
// Grass has special treatment, since it has a colourised top but the rest is normal.
// Commented out for now since vanilla does something about this now, but I'm not sure what exactly
//if(block.getBlock() != Blocks.GRASS || side == 1) this.setColour(block.getRenderColor(side));
// Blocks that emit light are rendered with full brightness.
if(block.getLightValue(world, new BlockPos(this.posX, this.posY, this.posZ)) == 0){
this.particleRed *= 0.75;
this.particleGreen *= 0.75;
this.particleBlue *= 0.75;
}else{
this.fullBrightness = true;
}
speed = rand.nextDouble()*2 + 1;
this.velX = velX;
this.velZ = velZ;
}
@Override public ParticleTornado(World world, int maxAge, double originX, double originZ, double radius, double yPos,
public void onUpdate(){ double velX, double velZ, IBlockState block){
super(world, 0, 0, 0, 0, 0, 0, block);
this.prevPosX = this.posX; this.angle = this.rand.nextDouble() * Math.PI * 2;
this.prevPosY = this.posY; double x = originX - Math.cos(angle) * radius;
this.prevPosZ = this.posZ; double z = originZ + radius * Math.sin(angle);
this.radius = radius;
this.setPosition(x, yPos, z);
this.prevPosX = x;
this.prevPosY = yPos;
this.prevPosZ = z;
// this.particleScale *= 0.75F;
this.particleMaxAge = maxAge;
this.canCollide = false;
// Grass has special treatment, since it has a colourised top but the rest is normal.
// Commented out for now since vanilla does something about this now, but I'm not sure what exactly
// if(block.getBlock() != Blocks.GRASS || side == 1) this.setColour(block.getRenderColor(side));
if(this.particleAge++ >= this.particleMaxAge){ // Blocks that emit light are rendered with full brightness.
this.setExpired(); if(block.getLightValue(world, new BlockPos(this.posX, this.posY, this.posZ)) == 0){
} this.particleRed *= 0.75;
this.particleGreen *= 0.75;
// This is in radians per tick... this.particleBlue *= 0.75;
double omega = Math.signum(speed) * ((Math.PI*2)/20 - speed/(20*radius)); }else{
this.fullBrightness = true;
}
// v = r times omega; therefore the normalised velocity vector needs to be r times the angle increment / 2 pi. speed = rand.nextDouble() * 2 + 1;
this.angle += omega; this.velX = velX;
this.velZ = velZ;
this.motionZ = radius * omega * Math.cos(angle); }
this.motionX = radius * omega * Math.sin(angle);
this.moveEntity(motionX + velX, 0, motionZ + velZ); @Override
public void onUpdate(){
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if(this.particleAge++ >= this.particleMaxAge){
this.setExpired();
}
// This is in radians per tick...
double omega = Math.signum(speed) * ((Math.PI * 2) / 20 - speed / (20 * radius));
// v = r times omega; therefore the normalised velocity vector needs to be r times the angle increment / 2 pi.
this.angle += omega;
this.motionZ = radius * omega * Math.cos(angle);
this.motionX = radius * omega * Math.sin(angle);
this.move(motionX + velX, 0, motionZ + velZ);
if(this.particleAge > this.particleMaxAge / 2){
this.setAlphaF(
1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
}
}
@Override
public int getBrightnessForRender(float partialTicks){
return fullBrightness ? 15728880 : super.getBrightnessForRender(partialTicks);
}
if(this.particleAge > this.particleMaxAge / 2){
this.setAlphaF(1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
}
}
@Override
public int getBrightnessForRender(float partialTicks){
return fullBrightness ? 15728880 : super.getBrightnessForRender(partialTicks);
}
} }
@@ -1,14 +1,9 @@
package electroblob.wizardry.client.renderer; package electroblob.wizardry.client.renderer;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.client.ClientProxy; import electroblob.wizardry.client.ClientProxy;
import electroblob.wizardry.spell.Petrify; import electroblob.wizardry.spell.Petrify;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@@ -20,172 +15,140 @@ import net.minecraft.client.renderer.GlStateManager.SourceFactor;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderLivingBase; import net.minecraft.client.renderer.entity.RenderLivingBase;
import net.minecraft.client.renderer.entity.RenderZombie;
import net.minecraft.client.renderer.entity.layers.LayerRenderer; import net.minecraft.client.renderer.entity.layers.LayerRenderer;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.monster.EntityZombie;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fml.relauncher.ReflectionHelper;
/** /**
* Layer used to render the stone texture on a petrified creature. Handles dynamic tiling of the stone texture and * Layer used to render the stone texture on a petrified creature. Handles dynamic tiling of the stone texture.
* reflective access for classes that don't play nicely (looking at you, {@link RenderZombie}). *
* @author Electroblob * @author Electroblob
* @since Wizardry 1.2 * @since Wizardry 1.2
*/ */
public class LayerStone implements LayerRenderer<EntityLivingBase> { public class LayerStone implements LayerRenderer<EntityLivingBase> {
protected ModelBase model; protected ModelBase model;
private final RenderLivingBase<?> renderer; private final RenderLivingBase<?> renderer;
private static final ResourceLocation texture = new ResourceLocation("textures/blocks/stone.png"); private static final ResourceLocation texture = new ResourceLocation("textures/blocks/stone.png");
private static final Field zombieLayers = ReflectionHelper.findField(RenderZombie.class, "defaultLayers", "field_177122_o");
private static final Field zombieVillagerLayers = ReflectionHelper.findField(RenderZombie.class, "villagerLayers", "field_177121_n");
private static final Method swapZombieModel = ReflectionHelper.findMethod(RenderZombie.class, null,
new String[]{"swapArmor", "func_82427_a"}, EntityZombie.class); // Second parameter (null) is unused
@SuppressWarnings("unchecked") // The compiler is being annoying and I know that what I'm doing is type-safe.
public static void initialiseLayers(){ public static void initialiseLayers(){
for(Entry<Class<? extends Entity>, Render<? extends Entity>> entry : Minecraft.getMinecraft().getRenderManager().entityRenderMap.entrySet()){ for(Entry<Class<? extends Entity>, Render<? extends Entity>> entry : Minecraft.getMinecraft()
// Zombies don't play nicely because they have their own, private lists of layers for the regular zombie .getRenderManager().entityRenderMap.entrySet()){
// and the zombie villager, which are assigned within the constructor for RenderZombie and swapped out // Because the zombie classes are now split properly, their renderers play nicely like everything else.
// as necessary. However, Mojang, in their infinite wisdom, haven't bothered to override addLayer to if(entry.getValue() instanceof RenderLivingBase){
// modify those internal lists, so that method is useless.
if(entry.getValue() instanceof RenderZombie){
try {
Object layers = zombieLayers.get(entry.getValue());
if(layers instanceof List<?>){
// Nice as the layer renderer system is, it doesn't lend itself to reflective access.
// I KNOW that 'layers' (which was obtained using reflection) is of the type
// List<LayerRenderer<EntityZombie>>, because that's what it's declared as. However, if I cast
// 'layers' to List<LayerRenderer<EntityZombie>>, I can't add a LayerStone because it's only a
// LayerRenderer<EntityLivingBase>, not a LayerRenderer<EntityZombie>.
((List<LayerRenderer<EntityLivingBase>>)layers).add(new LayerStone((RenderLivingBase<?>)entry.getValue()));
}
layers = zombieVillagerLayers.get(entry.getValue());
if(layers instanceof List<?>){
((List<LayerRenderer<EntityLivingBase>>)layers).add(new LayerStone((RenderLivingBase<?>)entry.getValue()));
}
} catch (IllegalArgumentException | IllegalAccessException e){
Wizardry.logger.error("Error while reflectively accessing zombie render layers");
e.printStackTrace();
}
}else if(entry.getValue() instanceof RenderLivingBase){
// Adds a stone layer to all the living entity renderers in the game. Whether it is actually rendered // Adds a stone layer to all the living entity renderers in the game. Whether it is actually rendered
// is decided in doRenderLayer below on a per-entity basis. // is decided in doRenderLayer below on a per-entity basis.
((RenderLivingBase<?>)entry.getValue()).addLayer(new LayerStone((RenderLivingBase<?>)entry.getValue())); ((RenderLivingBase<?>)entry.getValue()).addLayer(new LayerStone((RenderLivingBase<?>)entry.getValue()));
} }
// NOTE: May have to do some special stuff for players if they are to be added; see Minecraft.getMinecraft().getRenderManager().getSkinMap() // NOTE: May have to do some special stuff for players if they are to be added; see
// Minecraft.getMinecraft().getRenderManager().getSkinMap()
} }
} }
public LayerStone(RenderLivingBase<?> renderer){
this.renderer = renderer;
this.model = renderer.getMainModel();
}
@Override public LayerStone(RenderLivingBase<?> renderer){
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale){ this.renderer = renderer;
this.model = renderer.getMainModel();
if(entity.getEntityData().getBoolean(Petrify.NBT_KEY)){ }
@Override
public void doRenderLayer(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
float ageInTicks, float netHeadYaw, float headPitch, float scale){
if(entity.getEntityData().getBoolean(Petrify.NBT_KEY)){
GlStateManager.enableLighting(); GlStateManager.enableLighting();
int i = this.getBlockBrightnessForEntity(entity, partialTicks); int i = this.getBlockBrightnessForEntity(entity, partialTicks);
int j = i % 65536; int j = i % 65536;
int k = i / 65536; int k = i / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)j / 1.0F, (float)k / 1.0F); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)j / 1.0F, (float)k / 1.0F);
ResourceLocation breakingTexture = ClientProxy.renderStatue.getBlockBreakingTexture();
if(breakingTexture != null){
// Block breaking animation
// TODO: Spider eyes and enderman eyes (any others?) show through the stone when the block is being broken...
GlStateManager.enableBlend();
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
this.renderer.bindTexture(breakingTexture);
this.renderEntityModel(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
GlStateManager.disableBlend();
}else{
// Stone texture
this.renderer.bindTexture(texture);
this.renderEntityModel(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw, headPitch, scale);
}
}
}
private int getBlockBrightnessForEntity(Entity entity, float partialTicks){
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(MathHelper.floor_double(entity.posX), 0, MathHelper.floor_double(entity.posZ));
if(entity.worldObj.isBlockLoaded(pos)){ ResourceLocation breakingTexture = ClientProxy.renderStatue.getBlockBreakingTexture();
pos.setY(MathHelper.floor_double(entity.posY + (double)entity.getEyeHeight()));
return entity.worldObj.getCombinedLight(pos, 0); if(breakingTexture != null){
}else{ // Block breaking animation
return 0; // TODO: Spider eyes and enderman eyes (any others?) show through the stone when the block is being
} // broken...
} GlStateManager.enableBlend();
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
this.renderer.bindTexture(breakingTexture);
this.renderEntityModel(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw,
headPitch, scale);
GlStateManager.disableBlend();
}else{
// Stone texture
this.renderer.bindTexture(texture);
this.renderEntityModel(entity, limbSwing, limbSwingAmount, partialTicks, ageInTicks, netHeadYaw,
headPitch, scale);
}
}
}
private int getBlockBrightnessForEntity(Entity entity, float partialTicks){
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(MathHelper.floor(entity.posX), 0,
MathHelper.floor(entity.posZ));
if(entity.world.isBlockLoaded(pos)){
pos.setY(MathHelper.floor(entity.posY + (double)entity.getEyeHeight()));
return entity.world.getCombinedLight(pos, 0);
}else{
return 0;
}
}
private void renderEntityModel(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks,
float ageInTicks, float netHeadYaw, float headPitch, float scale){
private void renderEntityModel(EntityLivingBase entity, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch, float scale){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
// Enables tiling (Also used for guardian beam, beacon beam and ender crystal beam) // Enables tiling (Also used for guardian beam, beacon beam and ender crystal beam)
// TODO: Backport this improvement // TODO: Backport this improvement
GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT); GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT); GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GlStateManager.depthMask(true); // Some entities set depth mask to false (i.e. no sorting of faces by depth) GlStateManager.depthMask(true); // Some entities set depth mask to false (i.e. no sorting of faces by depth)
// In particular, LayerSpiderEyes sets it to false when the spider is invisible, for some reason. // In particular, LayerSpiderEyes sets it to false when the spider is invisible, for some reason.
// Changes the scale at which the texture is applied to the model. See LayerCreeper for a similar example, // Changes the scale at which the texture is applied to the model. See LayerCreeper for a similar example,
// but with translation instead of scaling. // but with translation instead of scaling.
// NOTE: You can do all sorts of fun stuff with this, just by applying transformations in the 2D texture space.
GlStateManager.matrixMode(GL11.GL_TEXTURE); GlStateManager.matrixMode(GL11.GL_TEXTURE);
GlStateManager.loadIdentity(); GlStateManager.loadIdentity();
double scaleX = 1, scaleY = 1; double scaleX = 1, scaleY = 1;
// It's more logical to use the model's texture size, but some classes don't bother setting it properly // It's more logical to use the model's texture size, but some classes don't bother setting it properly
// (e.g. ModelVillager), so to get the correct dimensions I'm getting them from the first box instead. // (e.g. ModelVillager), so to get the correct dimensions I'm getting them from the first box instead.
if(model.boxList != null && model.boxList.get(0) != null){ if(model.boxList != null && model.boxList.get(0) != null){
scaleX = (double)model.boxList.get(0).textureWidth/16d; scaleX = (double)model.boxList.get(0).textureWidth / 16d;
scaleY = (double)model.boxList.get(0).textureHeight/16d; scaleY = (double)model.boxList.get(0).textureHeight / 16d;
}else{ // Fallback to model fields; should never be needed }else{ // Fallback to model fields; should never be needed
scaleX = (double)model.textureWidth/16d; scaleX = (double)model.textureWidth / 16d;
scaleY = (double)model.textureHeight/16d; scaleY = (double)model.textureHeight / 16d;
} }
GlStateManager.scale(scaleX, scaleY, 1); GlStateManager.scale(scaleX, scaleY, 1);
GlStateManager.matrixMode(GL11.GL_MODELVIEW); GlStateManager.matrixMode(GL11.GL_MODELVIEW);
// Lets RenderZombie do its (stupid and inflexible) model switching thing
if(this.renderer instanceof RenderZombie && entity instanceof EntityZombie){
try {
swapZombieModel.invoke(this.renderer, entity);
this.model = this.renderer.getMainModel();
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
Wizardry.logger.error("Error while reflectively calling RenderZombie#swapArmor");
e.printStackTrace();
}
}
// Hides the hat layer for bipeds
if(this.model instanceof ModelBiped) ((ModelBiped) this.model).bipedHeadwear.isHidden = true;
// Hides the hat layer for bipeds
if(this.model instanceof ModelBiped) ((ModelBiped)this.model).bipedHeadwear.isHidden = true;
this.model.setLivingAnimations(entity, limbSwing, limbSwingAmount, partialTicks); this.model.setLivingAnimations(entity, limbSwing, limbSwingAmount, partialTicks);
this.model.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale); this.model.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale);
if(this.model instanceof ModelBiped) ((ModelBiped) this.model).bipedHeadwear.isHidden = false; if(this.model instanceof ModelBiped) ((ModelBiped)this.model).bipedHeadwear.isHidden = false;
// Undoes the texture scaling // Undoes the texture scaling
GlStateManager.matrixMode(GL11.GL_TEXTURE); GlStateManager.matrixMode(GL11.GL_TEXTURE);
GlStateManager.loadIdentity(); GlStateManager.loadIdentity();
GlStateManager.matrixMode(GL11.GL_MODELVIEW); GlStateManager.matrixMode(GL11.GL_MODELVIEW);
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
@Override @Override
public boolean shouldCombineTextures(){ public boolean shouldCombineTextures(){
return false; return false;
} }
} }
@@ -7,8 +7,9 @@ class RayHelper implements Comparable<RayHelper> {
double x1, y1, z1; double x1, y1, z1;
double x2, y2, z2; double x2, y2, z2;
double offsetX, offsetY, offsetZ; double offsetX, offsetY, offsetZ;
RayHelper(int ordinal, double x1, double y1, double z1, double x2, double y2, double z2, double offsetX, double offsetY, double offsetZ){ RayHelper(int ordinal, double x1, double y1, double z1, double x2, double y2, double z2, double offsetX,
double offsetY, double offsetZ){
this.ordinal = ordinal; this.ordinal = ordinal;
this.x1 = x1; this.x1 = x1;
this.y1 = y1; this.y1 = y1;
@@ -20,20 +21,20 @@ class RayHelper implements Comparable<RayHelper> {
this.offsetY = offsetY; this.offsetY = offsetY;
this.offsetZ = offsetZ; this.offsetZ = offsetZ;
} }
double getDistanceFromViewpoint(){ double getDistanceFromViewpoint(){
double midX = (x1+x2)/2; double midX = (x1 + x2) / 2;
double midY = (y1+y2)/2; double midY = (y1 + y2) / 2;
double midZ = (z1+z2)/2; double midZ = (z1 + z2) / 2;
double absoluteX = offsetX+midX; double absoluteX = offsetX + midX;
double absoluteY = offsetY+midY; double absoluteY = offsetY + midY;
double absoluteZ = offsetZ+midZ; double absoluteZ = offsetZ + midZ;
return Math.sqrt(absoluteX*absoluteX + absoluteY*absoluteY + absoluteZ*absoluteZ); return Math.sqrt(absoluteX * absoluteX + absoluteY * absoluteY + absoluteZ * absoluteZ);
} }
@Override @Override
public int compareTo(RayHelper ray){ public int compareTo(RayHelper ray){
if(this.getDistanceFromViewpoint() > ray.getDistanceFromViewpoint()){ if(this.getDistanceFromViewpoint() > ray.getDistanceFromViewpoint()){
@@ -4,10 +4,10 @@ import org.lwjgl.opengl.GL11;
import electroblob.wizardry.Wizardry; import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.EntityArc; import electroblob.wizardry.entity.EntityArc;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@@ -19,26 +19,26 @@ public class RenderArc extends Render<EntityArc> {
public RenderArc(RenderManager renderManager){ public RenderArc(RenderManager renderManager){
super(renderManager); super(renderManager);
for(int i=0;i<16;i++){ for(int i = 0; i < 16; i++){
textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/arc_" + i + ".png"); textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/arc_" + i + ".png");
} }
} }
@Override @Override
public void doRender(EntityArc arc, double d0, double d1, double d2, public void doRender(EntityArc arc, double d0, double d1, double d2, float fa, float fb){
float fa, float fb) {
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.translate((float)d0, (float)d1, (float)d2); GlStateManager.translate((float)d0, (float)d1, (float)d2);
GlStateManager.disableLighting(); GlStateManager.disableLighting();
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); //This line fixes the weird brightness bug. GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); // This line fixes the weird
// brightness bug.
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
//System.out.println("Entity coords: " + entity.posX + ", " + entity.posY + ", " + entity.posZ); // System.out.println("Entity coords: " + entity.posX + ", " + entity.posY + ", " + entity.posZ);
//System.out.println("doRender parameters: " + d0 + ", " + d1 + ", " + d2 + ", " + fa + ", " + fb); // System.out.println("doRender parameters: " + d0 + ", " + d1 + ", " + d2 + ", " + fa + ", " + fb);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
bindTexture(textures[arc.textureIndex]); // This MUST be after the tessellator declaration and the gl stuff bindTexture(textures[arc.textureIndex]); // This MUST be after the tessellator declaration and the gl stuff
@@ -57,62 +57,66 @@ public class RenderArc extends Render<EntityArc> {
dy = arc.y1 - arc.posY + 0.3; dy = arc.y1 - arc.posY + 0.3;
dz = arc.z1 - arc.posZ;// + d0/lengthOffsetRatio; dz = arc.z1 - arc.posZ;// + d0/lengthOffsetRatio;
// The distance from caster to target
double arcLength = Math.sqrt(dz * dz + dx * dx);
//The distance from caster to target // The ratio between the length of the arc and the offset of the start point from the player's centre (which
double arcLength = Math.sqrt(dz*dz+dx*dx); // is always 0.3).
// double lengthOffsetRatio = arcLength/0.3;
//The ratio between the length of the arc and the offset of the start point from the player's centre (which is always 0.3). // EntityClientPlayerMP player = Minecraft.getMinecraft().player;
//double lengthOffsetRatio = arcLength/0.3;
//EntityClientPlayerMP player = Minecraft.getMinecraft().thePlayer; // double xViewDist = player.posX - d0;
// double yViewDist = player.posY + player.eyeHeight - d1;
// double zViewDist = player.posZ - d2;
//double xViewDist = player.posX - d0; // double xzViewDist = Math.sqrt(xViewDist * xViewDist + zViewDist * zViewDist);
//double yViewDist = player.posY + player.eyeHeight - d1;
//double zViewDist = player.posZ - d2;
//double xzViewDist = Math.sqrt(xViewDist * xViewDist + zViewDist * zViewDist); // The angle above the horizontal that this particular player is viewing the arc from
// double viewAngle = Math.atan(yViewDist/xzViewDist);
//The angle above the horizontal that this particular player is viewing the arc from // Half the width of the arc
//double viewAngle = Math.atan(yViewDist/xzViewDist);
//Half the width of the arc
double arcWidth = 0.3d; double arcWidth = 0.3d;
//Right hand side of vertical plane // Right hand side of vertical plane
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
//Target end // Target end
buffer.pos(0, -0.5, 0).tex(1, 1).endVertex(); buffer.pos(0, -0.5, 0).tex(1, 1).endVertex();
buffer.pos(0, 0.5, 0).tex(1, 0).endVertex(); buffer.pos(0, 0.5, 0).tex(1, 0).endVertex();
//Caster end // Caster end
buffer.pos(dx, dy, dz).tex(0, 0).endVertex(); buffer.pos(dx, dy, dz).tex(0, 0).endVertex();
buffer.pos(dx, dy-1, dz).tex(0, 1).endVertex(); buffer.pos(dx, dy - 1, dz).tex(0, 1).endVertex();
tessellator.draw(); tessellator.draw();
//Left // Left
buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX);
//Target end // Target end
buffer.pos(0, -0.5, 0).tex(1, 1).endVertex(); buffer.pos(0, -0.5, 0).tex(1, 1).endVertex();
//Caster end // Caster end
buffer.pos(dx, dy-1, dz).tex(0, 1).endVertex(); buffer.pos(dx, dy - 1, dz).tex(0, 1).endVertex();
buffer.pos(dx, dy, dz).tex(0, 0).endVertex(); buffer.pos(dx, dy, dz).tex(0, 0).endVertex();
//Target end // Target end
buffer.pos(0, 0.5, 0).tex(1, 0).endVertex(); buffer.pos(0, 0.5, 0).tex(1, 0).endVertex();
tessellator.draw(); tessellator.draw();
//Bottom of horizontal plane // Bottom of horizontal plane
buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX);
buffer.pos((arcWidth/arcLength)*dz, 0, (-arcWidth/arcLength)*dx).tex(1, 1).endVertex(); buffer.pos((arcWidth / arcLength) * dz, 0, (-arcWidth / arcLength) * dx).tex(1, 1).endVertex();
buffer.pos(dx + (arcWidth/arcLength)*dz, dy-0.5, dz - (arcWidth/arcLength)*dx).tex(0, 1).endVertex(); buffer.pos(dx + (arcWidth / arcLength) * dz, dy - 0.5, dz - (arcWidth / arcLength) * dx).tex(0, 1)
buffer.pos(dx - (arcWidth/arcLength)*dz, dy-0.5, dz + (arcWidth/arcLength)*dx).tex(0, 0).endVertex(); .endVertex();
buffer.pos((-arcWidth/arcLength)*dz, 0, (arcWidth/arcLength)*dx).tex(1, 0).endVertex(); buffer.pos(dx - (arcWidth / arcLength) * dz, dy - 0.5, dz + (arcWidth / arcLength) * dx).tex(0, 0)
.endVertex();
buffer.pos((-arcWidth / arcLength) * dz, 0, (arcWidth / arcLength) * dx).tex(1, 0).endVertex();
tessellator.draw(); tessellator.draw();
//Top // Top
buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX);
buffer.pos((arcWidth/arcLength)*dz, 0, (-arcWidth/arcLength)*dx).tex(1, 1).endVertex(); buffer.pos((arcWidth / arcLength) * dz, 0, (-arcWidth / arcLength) * dx).tex(1, 1).endVertex();
buffer.pos((-arcWidth/arcLength)*dz, 0, (arcWidth/arcLength)*dx).tex(1, 0).endVertex(); buffer.pos((-arcWidth / arcLength) * dz, 0, (arcWidth / arcLength) * dx).tex(1, 0).endVertex();
buffer.pos(dx - (arcWidth/arcLength)*dz, dy-0.5, dz + (arcWidth/arcLength)*dx).tex(0, 0).endVertex(); buffer.pos(dx - (arcWidth / arcLength) * dz, dy - 0.5, dz + (arcWidth / arcLength) * dx).tex(0, 0)
buffer.pos(dx + (arcWidth/arcLength)*dz, dy-0.5, dz - (arcWidth/arcLength)*dx).tex(0, 1).endVertex(); .endVertex();
buffer.pos(dx + (arcWidth / arcLength) * dz, dy - 0.5, dz - (arcWidth / arcLength) * dx).tex(0, 1)
.endVertex();
tessellator.draw(); tessellator.draw();
} }
@@ -122,7 +126,7 @@ public class RenderArc extends Render<EntityArc> {
} }
@Override @Override
protected ResourceLocation getEntityTexture(EntityArc entity) { protected ResourceLocation getEntityTexture(EntityArc entity){
return textures[entity.textureIndex]; return textures[entity.textureIndex];
} }
@@ -6,10 +6,10 @@ import electroblob.wizardry.Wizardry;
import electroblob.wizardry.tileentity.ContainerArcaneWorkbench; import electroblob.wizardry.tileentity.ContainerArcaneWorkbench;
import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench; import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@@ -19,81 +19,80 @@ import net.minecraft.util.ResourceLocation;
public class RenderArcaneWorkbench extends TileEntitySpecialRenderer<TileEntityArcaneWorkbench> { public class RenderArcaneWorkbench extends TileEntitySpecialRenderer<TileEntityArcaneWorkbench> {
private static final ResourceLocation runeTexture = new ResourceLocation(Wizardry.MODID, "textures/entity/rune.png"); private static final ResourceLocation runeTexture = new ResourceLocation(Wizardry.MODID, "textures/entity/rune.png");
public RenderArcaneWorkbench(){}
@Override
public void renderTileEntityAt(TileEntityArcaneWorkbench tileentity, double x, double y, double z, float partialTicks, int destroyStage) {
GlStateManager.pushMatrix(); public RenderArcaneWorkbench(){}
// This line makes stuff render in the same place relative to the world wherever the player is.
@Override
public void render(TileEntityArcaneWorkbench tileentity, double x, double y, double z, float partialTicks, int destroyStage, float alpha){
GlStateManager.pushMatrix();
// This line makes stuff render in the same place relative to the world wherever the player is.
GlStateManager.translate((float)x + 0.5F, (float)y + 1.5F, (float)z + 0.5F); GlStateManager.translate((float)x + 0.5F, (float)y + 1.5F, (float)z + 0.5F);
GlStateManager.rotate(180, 0F, 0F, 1F); GlStateManager.rotate(180, 0F, 0F, 1F);
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
double angle = 0.0d; double angle = 0.0d;
if(x < -0.5){ if(x < -0.5){
angle = Math.toDegrees(Math.atan((z+0.5)/(x+0.5))) + 180; angle = Math.toDegrees(Math.atan((z + 0.5) / (x + 0.5))) + 180;
}else{ }else{
angle = Math.toDegrees(Math.atan((z+0.5)/(x+0.5))); angle = Math.toDegrees(Math.atan((z + 0.5) / (x + 0.5)));
} }
this.renderEffect(tileentity); this.renderEffect(tileentity);
this.renderWand(tileentity, angle); this.renderWand(tileentity, angle);
GlStateManager.popMatrix(); GlStateManager.popMatrix();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
private void renderEffect(TileEntityArcaneWorkbench tileentity) {
ItemStack itemstack = tileentity.getStackInSlot(ContainerArcaneWorkbench.WAND_SLOT); private void renderEffect(TileEntityArcaneWorkbench tileentity){
if(itemstack != null){ ItemStack itemstack = tileentity.getStackInSlot(ContainerArcaneWorkbench.WAND_SLOT);
GlStateManager.pushMatrix();
GlStateManager.disableLighting(); if(!itemstack.isEmpty()){
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); GlStateManager.pushMatrix();
GlStateManager.enableBlend(); GlStateManager.disableLighting();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); //This line fixes the weird brightness bug. OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
GlStateManager.rotate(tileentity.timer, 0.0f, 1.0f, 0.0f); GlStateManager.enableBlend();
GlStateManager.translate(0.0f, 0.65f, 0.0f); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); // This line fixes the weird brightness bug.
GlStateManager.rotate(tileentity.timer, 0.0f, 1.0f, 0.0f);
GlStateManager.translate(0.0f, 0.65f, 0.0f);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
bindTexture(runeTexture); bindTexture(runeTexture);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-0.5f, 0, -0.5f).tex(0, 0).endVertex(); buffer.pos(-0.5f, 0, -0.5f).tex(0, 0).endVertex();
buffer.pos(0.5f, 0, -0.5f).tex(1, 0).endVertex(); buffer.pos(0.5f, 0, -0.5f).tex(1, 0).endVertex();
buffer.pos(0.5f, 0, 0.5f).tex(1, 1).endVertex(); buffer.pos(0.5f, 0, 0.5f).tex(1, 1).endVertex();
buffer.pos(-0.5f, 0, 0.5f).tex(0, 1).endVertex(); buffer.pos(-0.5f, 0, 0.5f).tex(0, 1).endVertex();
tessellator.draw(); tessellator.draw();
GlStateManager.disableBlend(); GlStateManager.disableBlend();
GlStateManager.enableLighting(); GlStateManager.enableLighting();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
} }
/** /**
* Renders the wand on the workbench as 3D on the model. Currently doesn't do much on 'fast' graphics! * Renders the wand on the workbench as 3D on the model. Currently doesn't do much on 'fast' graphics!
*
* @param tileentity The instance of the workbench tile entity * @param tileentity The instance of the workbench tile entity
*/ */
private void renderWand(TileEntityArcaneWorkbench tileentity, double viewAngle) private void renderWand(TileEntityArcaneWorkbench tileentity, double viewAngle){
{ ItemStack stack = tileentity.getStackInSlot(ContainerArcaneWorkbench.WAND_SLOT);
ItemStack stack = tileentity.getStackInSlot(ContainerArcaneWorkbench.WAND_SLOT);
if(!stack.isEmpty()){
if(stack != null){
GlStateManager.pushMatrix();
GlStateManager.pushMatrix(); //GlStateManager.rotate(180.0F, 1.0F, 0.0F, 0.0F);
GlStateManager.rotate(180.0F, 1.0F, 0.0F, 0.0F); GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F);
GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F);
GlStateManager.rotate(180, 0, 1, 0);
GlStateManager.rotate(180, 0, 1, 0); GlStateManager.rotate((float)(viewAngle - 90f), 0, 0, 1);
// View angle is negated because of the 180 flip. // Does the floaty thing
GlStateManager.rotate((float)(-viewAngle-90f), 0, 0, 1); GlStateManager.translate(0.0F, 0.0F, (float)tileentity.yOffset / 5000.0F + 0.55f);
// Does the floaty thing GlStateManager.scale(0.75F, 0.75F, 0.75F);
GlStateManager.translate(0.0F, 0.0F, (float)tileentity.yOffset/5000.0F - 0.55f); // This is what the item frame uses so it's definitely what we want.
GlStateManager.scale(0.75F, 0.75F, 0.75F); Minecraft.getMinecraft().getRenderItem().renderItem(stack, TransformType.FIXED);
// This is what the item frame uses so it's definitely what we want. GlStateManager.popMatrix();
Minecraft.getMinecraft().getRenderItem().renderItem(stack, TransformType.FIXED); }
GlStateManager.popMatrix(); }
}
}
} }
@@ -8,11 +8,11 @@ import org.lwjgl.opengl.GL11;
import electroblob.wizardry.Wizardry; import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.construct.EntityBlackHole; import electroblob.wizardry.entity.construct.EntityBlackHole;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@@ -20,15 +20,17 @@ import net.minecraft.util.ResourceLocation;
public class RenderBlackHole extends Render<EntityBlackHole> { public class RenderBlackHole extends Render<EntityBlackHole> {
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/dark_ray.png"); private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID,
private static final ResourceLocation texture2 = new ResourceLocation(Wizardry.MODID, "textures/entity/black_hole.png"); "textures/entity/dark_ray.png");
private static final ResourceLocation texture2 = new ResourceLocation(Wizardry.MODID,
"textures/entity/black_hole.png");
public RenderBlackHole(RenderManager renderManager) { public RenderBlackHole(RenderManager renderManager){
super(renderManager); super(renderManager);
} }
@Override @Override
public void doRender(EntityBlackHole blackhole, double x, double y, double z, float fa, float fb) { public void doRender(EntityBlackHole blackhole, double x, double y, double z, float fa, float fb){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
@@ -42,19 +44,22 @@ public class RenderBlackHole extends Render<EntityBlackHole> {
GlStateManager.translate(x, y, z); GlStateManager.translate(x, y, z);
//float pitch = (float) Math.toDegrees(Math.atan(y/(x*x+z*z))); // float pitch = (float) Math.toDegrees(Math.atan(y/(x*x+z*z)));
//float yaw = (float) Math.toDegrees(Math.atan(x/z)); // float yaw = (float) Math.toDegrees(Math.atan(x/z));
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
if(blackhole.ticksExisted < 10){ if(blackhole.ticksExisted < 10){
GlStateManager.scale((float)blackhole.ticksExisted/10, (float)blackhole.ticksExisted/10, (float)blackhole.ticksExisted/10); GlStateManager.scale((float)blackhole.ticksExisted / 10, (float)blackhole.ticksExisted / 10,
(float)blackhole.ticksExisted / 10);
} }
if(blackhole.ticksExisted > blackhole.lifetime - 10){ if(blackhole.ticksExisted > blackhole.lifetime - 10){
GlStateManager.scale((float)(blackhole.lifetime-blackhole.ticksExisted)/10, (float)(blackhole.lifetime-blackhole.ticksExisted)/10, (float)(blackhole.lifetime-blackhole.ticksExisted)/10); GlStateManager.scale((float)(blackhole.lifetime - blackhole.ticksExisted) / 10,
(float)(blackhole.lifetime - blackhole.ticksExisted) / 10,
(float)(blackhole.lifetime - blackhole.ticksExisted) / 10);
} }
this.bindTexture(texture); this.bindTexture(texture);
@@ -67,7 +72,7 @@ public class RenderBlackHole extends Render<EntityBlackHole> {
ArrayList<RayHelper> rays = new ArrayList<RayHelper>(1); ArrayList<RayHelper> rays = new ArrayList<RayHelper>(1);
for(int j=0; j<30; j++){ for(int j = 0; j < 30; j++){
float scale = 3.0f; float scale = 3.0f;
@@ -76,33 +81,29 @@ public class RenderBlackHole extends Render<EntityBlackHole> {
int sliceAngle = 20 + a; int sliceAngle = 20 + a;
double x1 = scale*Math.sin((blackhole.ticksExisted + 40*j)*(Math.PI/180)); double x1 = scale * Math.sin((blackhole.ticksExisted + 40 * j) * (Math.PI / 180));
//double y1 = 0.7*Math.cos((blackhole.timer - 40*j)*(Math.PI/180))*j/10; // double y1 = 0.7*Math.cos((blackhole.timer - 40*j)*(Math.PI/180))*j/10;
double z1 = scale*Math.cos((blackhole.ticksExisted + 40*j)*(Math.PI/180)); double z1 = scale * Math.cos((blackhole.ticksExisted + 40 * j) * (Math.PI / 180));
double x2 = scale*Math.sin((blackhole.ticksExisted + 40*j - sliceAngle)*(Math.PI/180)); double x2 = scale * Math.sin((blackhole.ticksExisted + 40 * j - sliceAngle) * (Math.PI / 180));
//double y2 = 0.7*Math.sin((blackhole.timer - 40*j)*(Math.PI/180))*j/10; // double y2 = 0.7*Math.sin((blackhole.timer - 40*j)*(Math.PI/180))*j/10;
double z2 = scale*Math.cos((blackhole.ticksExisted + 40*j - sliceAngle)*(Math.PI/180)); double z2 = scale * Math.cos((blackhole.ticksExisted + 40 * j - sliceAngle) * (Math.PI / 180));
double absoluteX = x1*Math.cos(31*b); double absoluteX = x1 * Math.cos(31 * b);
double absoluteY = z1*Math.sin(31*a) + x1*Math.cos(31*a)*Math.sin(31*b); double absoluteY = z1 * Math.sin(31 * a) + x1 * Math.cos(31 * a) * Math.sin(31 * b);
double absoluteZ = z1*Math.cos(31*a); double absoluteZ = z1 * Math.cos(31 * a);
double absoluteX2 = x2*Math.cos(31*b); double absoluteX2 = x2 * Math.cos(31 * b);
double absoluteY2 = z2*Math.sin(31*a) + x2*Math.cos(31*a)*Math.sin(31*b); double absoluteY2 = z2 * Math.sin(31 * a) + x2 * Math.cos(31 * a) * Math.sin(31 * b);
double absoluteZ2 = z2*Math.cos(31*a); double absoluteZ2 = z2 * Math.cos(31 * a);
/* /* buffer.begin(0, DefaultVertexFormats.POSITION_TEX);
buffer.begin(0, DefaultVertexFormats.POSITION_TEX); *
* tessellator.setColorOpaque(255, 255, 255); GL11.glPointSize(5);
tessellator.setColorOpaque(255, 255, 255); *
GL11.glPointSize(5); * tessellator.addVertex(absoluteX-x, 0, 0); tessellator.addVertex(0, absoluteY-y, 0);
* tessellator.addVertex(0, 0, absoluteZ-z);
tessellator.addVertex(absoluteX-x, 0, 0); *
tessellator.addVertex(0, absoluteY-y, 0); * tessellator.draw(); */
tessellator.addVertex(0, 0, absoluteZ-z);
tessellator.draw();
*/
rays.add(new RayHelper(j, absoluteX, absoluteY, absoluteZ, absoluteX2, absoluteY2, absoluteZ2, x, y, z)); rays.add(new RayHelper(j, absoluteX, absoluteY, absoluteZ, absoluteX2, absoluteY2, absoluteZ2, x, y, z));
} }
@@ -112,16 +113,16 @@ public class RenderBlackHole extends Render<EntityBlackHole> {
for(RayHelper ray : rays){ for(RayHelper ray : rays){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
//GlStateManager.rotate(31*blackhole.randomiser[ray.ordinal], 1, 0, 0); // GlStateManager.rotate(31*blackhole.randomiser[ray.ordinal], 1, 0, 0);
//GlStateManager.rotate(31*blackhole.randomiser2[ray.ordinal], 0, 0, 1); // GlStateManager.rotate(31*blackhole.randomiser2[ray.ordinal], 0, 0, 1);
buffer.begin(5, DefaultVertexFormats.POSITION_TEX); buffer.begin(5, DefaultVertexFormats.POSITION_TEX);
//tessellator.setColorRGBA(255, 255, 255, 0); // tessellator.setColorRGBA(255, 255, 255, 0);
buffer.pos(0, 0, 0).tex(0, 0).endVertex(); buffer.pos(0, 0, 0).tex(0, 0).endVertex();
buffer.pos(0, 0, 0).tex(0, 1).endVertex(); buffer.pos(0, 0, 0).tex(0, 1).endVertex();
//tessellator.setColorRGBA(0, 0, 0, 255); // tessellator.setColorRGBA(0, 0, 0, 255);
buffer.pos(ray.x1, ray.y1, ray.z1).tex(1, 0).endVertex(); buffer.pos(ray.x1, ray.y1, ray.z1).tex(1, 0).endVertex();
buffer.pos(ray.x2, ray.y2, ray.z2).tex(1, 1).endVertex(); buffer.pos(ray.x2, ray.y2, ray.z2).tex(1, 1).endVertex();
@@ -132,20 +133,15 @@ public class RenderBlackHole extends Render<EntityBlackHole> {
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
/* Deprecated in favour of particle style method. /* Deprecated in favour of particle style method. GlStateManager.rotate(yaw, 0, 1, 0); // GL transformations are
GlStateManager.rotate(yaw, 0, 1, 0); * relative, hence only x rotation if(z < 0){ GlStateManager.rotate(pitch, 1, 0, 0); }else{
// GL transformations are relative, hence only x rotation * GlStateManager.rotate(-1*pitch, 1, 0, 0); } */
if(z < 0){
GlStateManager.rotate(pitch, 1, 0, 0);
}else{
GlStateManager.rotate(-1*pitch, 1, 0, 0);
}
*/
// Renders the aura effect // Renders the aura effect
// This counteracts the reverse rotation behaviour when in front f5 view. Vanilla now has this fix too. // This counteracts the reverse rotation behaviour when in front f5 view. Vanilla now has this fix too.
float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? this.renderManager.playerViewX : -this.renderManager.playerViewX; float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? this.renderManager.playerViewX
: -this.renderManager.playerViewX;
GlStateManager.rotate(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); GlStateManager.rotate(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F); GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
@@ -162,7 +158,6 @@ public class RenderBlackHole extends Render<EntityBlackHole> {
GlStateManager.popMatrix(); GlStateManager.popMatrix();
GlStateManager.shadeModel(GL11.GL_FLAT); GlStateManager.shadeModel(GL11.GL_FLAT);
GlStateManager.enableCull(); GlStateManager.enableCull();
GlStateManager.disableBlend(); GlStateManager.disableBlend();
@@ -173,7 +168,7 @@ public class RenderBlackHole extends Render<EntityBlackHole> {
} }
@Override @Override
protected ResourceLocation getEntityTexture(EntityBlackHole entity) { protected ResourceLocation getEntityTexture(EntityBlackHole entity){
return texture; return texture;
} }
@@ -7,18 +7,17 @@ import net.minecraft.util.ResourceLocation;
public class RenderBlank extends Render<Entity> { public class RenderBlank extends Render<Entity> {
public RenderBlank(RenderManager renderManager) { public RenderBlank(RenderManager renderManager){
super(renderManager); super(renderManager);
} }
@Override @Override
public void doRender(Entity entity, double d0, double d1, double d2, public void doRender(Entity entity, double d0, double d1, double d2, float f, float f1){
float f, float f1) {
} }
@Override @Override
protected ResourceLocation getEntityTexture(Entity entity) { protected ResourceLocation getEntityTexture(Entity entity){
return null; return null;
} }
@@ -6,10 +6,10 @@ import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.construct.EntityBubble; import electroblob.wizardry.entity.construct.EntityBubble;
import electroblob.wizardry.util.WizardryUtilities; import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@@ -18,9 +18,10 @@ import net.minecraft.util.ResourceLocation;
public class RenderBubble extends Render<EntityBubble> { public class RenderBubble extends Render<EntityBubble> {
private static final ResourceLocation particleTextures = new ResourceLocation("textures/particle/particles.png"); private static final ResourceLocation particleTextures = new ResourceLocation("textures/particle/particles.png");
private static final ResourceLocation darkOrbTexture = new ResourceLocation(Wizardry.MODID, "textures/entity/dark_orb.png"); private static final ResourceLocation darkOrbTexture = new ResourceLocation(Wizardry.MODID,
"textures/entity/dark_orb.png");
public RenderBubble(RenderManager renderManager) { public RenderBubble(RenderManager renderManager){
super(renderManager); super(renderManager);
} }
@@ -34,7 +35,7 @@ public class RenderBubble extends Render<EntityBubble> {
float yOffset = 0; float yOffset = 0;
if(WizardryUtilities.getRider(entity) != null){ if(WizardryUtilities.getRider(entity) != null){
yOffset = WizardryUtilities.getRider(entity).height/2; yOffset = WizardryUtilities.getRider(entity).height / 2;
} }
GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6); GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6);
@@ -48,7 +49,7 @@ public class RenderBubble extends Render<EntityBubble> {
GlStateManager.disableLighting(); GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
}else{ }else{
int j = entity.getBrightnessForRender(par9); int j = entity.getBrightnessForRender();
int k = j % 65536; int k = j % 65536;
int l = j / 65536; int l = j / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F);
@@ -58,20 +59,21 @@ public class RenderBubble extends Render<EntityBubble> {
// This counteracts the reverse rotation behaviour when in front f5 view. // This counteracts the reverse rotation behaviour when in front f5 view.
// Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example. // Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example.
float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? this.renderManager.playerViewX : -this.renderManager.playerViewX; float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? this.renderManager.playerViewX
: -this.renderManager.playerViewX;
GlStateManager.rotate(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); GlStateManager.rotate(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F); GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
float f11 = 3.0F; float f11 = 3.0F;
GlStateManager.scale(f11, f11, f11); GlStateManager.scale(f11, f11, f11);
double pixelwidth = (1.0d/128); double pixelwidth = (1.0d / 128);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
//tessellator.setColorRGBA_I(k1, 128); // tessellator.setColorRGBA_I(k1, 128);
//buffer.normal(0.0F, 1.0F, 0.0F); // buffer.normal(0.0F, 1.0F, 0.0F);
if(((EntityBubble)entity).isDarkOrb){ if(((EntityBubble)entity).isDarkOrb){
buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.0D).tex(0, 1).endVertex(); buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.0D).tex(0, 1).endVertex();
@@ -80,8 +82,8 @@ public class RenderBubble extends Render<EntityBubble> {
buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.0D).tex(0, 0).endVertex(); buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.0D).tex(0, 0).endVertex();
}else{ }else{
buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.0D).tex(pixelwidth, pixelwidth * 24).endVertex(); buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.0D).tex(pixelwidth, pixelwidth * 24).endVertex();
buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.0D).tex(pixelwidth*8, pixelwidth * 24).endVertex(); buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.0D).tex(pixelwidth * 8, pixelwidth * 24).endVertex();
buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.0D).tex(pixelwidth*8, pixelwidth * 17).endVertex(); buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.0D).tex(pixelwidth * 8, pixelwidth * 17).endVertex();
buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.0D).tex(pixelwidth, pixelwidth * 17).endVertex(); buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.0D).tex(pixelwidth, pixelwidth * 17).endVertex();
} }
@@ -97,7 +99,7 @@ public class RenderBubble extends Render<EntityBubble> {
} }
@Override @Override
protected ResourceLocation getEntityTexture(EntityBubble entity) { protected ResourceLocation getEntityTexture(EntityBubble entity){
return null; return null;
} }
@@ -4,10 +4,10 @@ import org.lwjgl.opengl.GL11;
import electroblob.wizardry.Wizardry; import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.construct.EntityDecay; import electroblob.wizardry.entity.construct.EntityDecay;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@@ -16,58 +16,58 @@ import net.minecraft.util.ResourceLocation;
public class RenderDecay extends Render<EntityDecay> { public class RenderDecay extends Render<EntityDecay> {
private static final ResourceLocation[] textures = new ResourceLocation[10]; private static final ResourceLocation[] textures = new ResourceLocation[10];
public RenderDecay(RenderManager renderManager){ public RenderDecay(RenderManager renderManager){
super(renderManager); super(renderManager);
for(int i=0;i<10;i++){ for(int i = 0; i < 10; i++){
textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/decay_" + i + ".png"); textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/decay_" + i + ".png");
} }
} }
@Override @Override
public void doRender(EntityDecay entity, double par2, double par4, double par6, float par8, float par9){ public void doRender(EntityDecay entity, double par2, double par4, double par6, float par8, float par9){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.disableLighting(); GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
float yOffset = 0; float yOffset = 0;
GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6); GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6);
this.bindTexture(textures[((EntityDecay)entity).textureIndex]); this.bindTexture(textures[((EntityDecay)entity).textureIndex]);
float f6 = 1.0F; float f6 = 1.0F;
float f7 = 0.5F; float f7 = 0.5F;
float f8 = 0.5F; float f8 = 0.5F;
GlStateManager.rotate(-90, 1, 0, 0); GlStateManager.rotate(-90, 1, 0, 0);
float scale = 2*Math.min(1, (float)(EntityDecay.LIFETIME - entity.ticksExisted)/50f); float scale = 2 * Math.min(1, (float)(EntityDecay.LIFETIME - entity.ticksExisted) / 50f);
GlStateManager.scale(scale, scale, scale); GlStateManager.scale(scale, scale, scale);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
//tessellator.setColorRGBA_I(k1, 128); // tessellator.setColorRGBA_I(k1, 128);
//buffer.normal(0.0F, 1.0F, 0.0F); // buffer.normal(0.0F, 1.0F, 0.0F);
buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex(); buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex(); buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex(); buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex();
buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex(); buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex();
tessellator.draw(); tessellator.draw();
GlStateManager.disableBlend(); GlStateManager.disableBlend();
GlStateManager.enableLighting(); GlStateManager.enableLighting();
GlStateManager.disableRescaleNormal(); GlStateManager.disableRescaleNormal();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
@Override @Override
protected ResourceLocation getEntityTexture(EntityDecay entity) { protected ResourceLocation getEntityTexture(EntityDecay entity){
return null; return null;
} }
@@ -15,26 +15,25 @@ import net.minecraftforge.fml.relauncher.ReflectionHelper;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
// TODO: Backport the rewrite of this entire class.
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class RenderDecoy extends RenderBiped<EntityDecoy> { public class RenderDecoy extends RenderBiped<EntityDecoy> {
private static final ResourceLocation steveTextures = new ResourceLocation("textures/entity/steve.png"); private static final ResourceLocation steveTextures = new ResourceLocation("textures/entity/steve.png");
private static final Method getEntityTexture = ReflectionHelper.findMethod(Render.class, null, private static final Method getEntityTexture = ReflectionHelper.findMethod(Render.class, "getEntityTexture",
new String[]{"getEntityTexture", "func_110775_a"}, Entity.class); // Generic parameter T is erased to Entity at runtime. "func_110775_a", Entity.class); // Generic parameter T is erased to Entity at runtime.
public RenderDecoy(RenderManager manager){ public RenderDecoy(RenderManager manager){
super(manager, new ModelBiped(0.0f), 0.5f); super(manager, new ModelBiped(0.0f), 0.5f);
} }
@Override @Override
public void doRender(EntityDecoy entity, double x, double y, double z, float entityYaw, float partialTicks) { public void doRender(EntityDecoy entity, double x, double y, double z, float entityYaw, float partialTicks){
if(entity.getCaster() != null){ if(entity.getCaster() != null){
this.renderName(entity, x, y, z); this.renderName(entity, x, y, z);
// Save relevant animation fields from the caster to local variables // Save relevant animation fields from the caster to local variables
float pitch = entity.getCaster().rotationPitch; float pitch = entity.getCaster().rotationPitch;
float prevPitch = entity.getCaster().prevRotationPitch; float prevPitch = entity.getCaster().prevRotationPitch;
@@ -50,7 +49,7 @@ public class RenderDecoy extends RenderBiped<EntityDecoy> {
int hurtTime = entity.getCaster().hurtTime; int hurtTime = entity.getCaster().hurtTime;
boolean sneak = entity.getCaster().isSneaking(); boolean sneak = entity.getCaster().isSneaking();
Entity mount = entity.getCaster().getRidingEntity(); Entity mount = entity.getCaster().getRidingEntity();
// Assign decoy's animation fields to the caster // Assign decoy's animation fields to the caster
entity.getCaster().rotationPitch = entity.rotationPitch; entity.getCaster().rotationPitch = entity.rotationPitch;
entity.getCaster().prevRotationPitch = entity.prevRotationPitch; entity.getCaster().prevRotationPitch = entity.prevRotationPitch;
@@ -66,10 +65,11 @@ public class RenderDecoy extends RenderBiped<EntityDecoy> {
entity.getCaster().hurtTime = entity.hurtTime; entity.getCaster().hurtTime = entity.hurtTime;
entity.getCaster().setSneaking(false); // Decoys can't sneak FIXME Not working! entity.getCaster().setSneaking(false); // Decoys can't sneak FIXME Not working!
entity.getCaster().dismountRidingEntity(); // Decoys can't ride anything entity.getCaster().dismountRidingEntity(); // Decoys can't ride anything
// Do the rendering // Do the rendering
renderManager.getEntityRenderObject(entity.getCaster()).doRender(entity.getCaster(), x, y, z, entityYaw, partialTicks); renderManager.getEntityRenderObject(entity.getCaster()).doRender(entity.getCaster(), x, y, z, entityYaw,
partialTicks);
// Reset caster's animation fields to their original values // Reset caster's animation fields to their original values
entity.getCaster().rotationPitch = pitch; entity.getCaster().rotationPitch = pitch;
entity.getCaster().prevRotationPitch = prevPitch; entity.getCaster().prevRotationPitch = prevPitch;
@@ -85,19 +85,22 @@ public class RenderDecoy extends RenderBiped<EntityDecoy> {
entity.getCaster().hurtTime = hurtTime; entity.getCaster().hurtTime = hurtTime;
entity.getCaster().setSneaking(sneak); entity.getCaster().setSneaking(sneak);
if(mount != null) entity.getCaster().startRiding(mount); if(mount != null) entity.getCaster().startRiding(mount);
}else{ }else{
super.doRender(entity, x, y, z, entityYaw, partialTicks); super.doRender(entity, x, y, z, entityYaw, partialTicks);
} }
} }
@Override @Override
protected ResourceLocation getEntityTexture(EntityDecoy entity){ protected ResourceLocation getEntityTexture(EntityDecoy entity){
if(entity.getCaster() != null){ if(entity.getCaster() != null){
try { try{
return (ResourceLocation)getEntityTexture.invoke(renderManager.getEntityRenderObject(entity.getCaster())); return (ResourceLocation)getEntityTexture
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | ClassCastException e){ .invoke(renderManager.getEntityRenderObject(entity.getCaster()));
Wizardry.logger.error("Error while reflectively calling Render#getEntityTexture as part of decoy rendering"); }catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
| ClassCastException e){
Wizardry.logger
.error("Error while reflectively calling Render#getEntityTexture as part of decoy rendering");
e.printStackTrace(); e.printStackTrace();
} }
} }
@@ -11,24 +11,23 @@ import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class RenderEvilWizard extends RenderBiped<EntityEvilWizard> public class RenderEvilWizard extends RenderBiped<EntityEvilWizard> {
{ static final ResourceLocation[] textures = new ResourceLocation[6];
static final ResourceLocation[] textures = new ResourceLocation[6];
public RenderEvilWizard(RenderManager renderManager){ public RenderEvilWizard(RenderManager renderManager){
super(renderManager, new ModelWizard(), 0.5F); super(renderManager, new ModelWizard(), 0.5F);
for(int i=0;i<6;i++){ for(int i = 0; i < 6; i++){
textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/evil_wizard_" + i + ".png"); textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/evil_wizard_" + i + ".png");
} }
// Just using the default without overriding models, since the armour sets its own model anyway. // Just using the default without overriding models, since the armour sets its own model anyway.
this.addLayer(new LayerBipedArmor(this)); this.addLayer(new LayerBipedArmor(this));
} }
@Override @Override
protected ResourceLocation getEntityTexture(EntityEvilWizard wizard) { protected ResourceLocation getEntityTexture(EntityEvilWizard wizard){
return textures[wizard.textureIndex]; return textures[wizard.textureIndex];
} }
} }
@@ -4,10 +4,10 @@ import org.lwjgl.opengl.GL11;
import electroblob.wizardry.entity.construct.EntityFireRing; import electroblob.wizardry.entity.construct.EntityFireRing;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.renderer.texture.TextureAtlasSprite;
@@ -17,163 +17,170 @@ import net.minecraft.init.Blocks;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
public class RenderFireRing extends Render<EntityFireRing> { public class RenderFireRing extends Render<EntityFireRing> {
private final ResourceLocation texture; private final ResourceLocation texture;
private float scale = 1.0f; private float scale = 1.0f;
public RenderFireRing(RenderManager renderManager, ResourceLocation texture, float scale) { public RenderFireRing(RenderManager renderManager, ResourceLocation texture, float scale){
super(renderManager); super(renderManager);
this.texture = texture; this.texture = texture;
this.scale = scale; this.scale = scale;
} }
@Override @Override
public void doRender(EntityFireRing entity, double par2, double par4, double par6, float par8, float par9){ public void doRender(EntityFireRing entity, double par2, double par4, double par6, float par8, float par9){
GlStateManager.pushMatrix();
GlStateManager.enableBlend();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
float yOffset = 0;
GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6);
this.bindTexture(texture);
float f6 = 1.0F;
float f7 = 0.5F;
float f8 = 0.5F;
GlStateManager.rotate(-90, 1, 0, 0);
GlStateManager.scale(scale, scale, scale);
Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex();
buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex();
tessellator.draw();
GlStateManager.disableBlend();
GlStateManager.enableLighting();
GlStateManager.disableRescaleNormal();
GlStateManager.popMatrix();
// Fire
GlStateManager.disableLighting();
TextureAtlasSprite icon = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(Blocks.FIRE.getDefaultState()).getParticleTexture();
int sides = 16;
float height = 1.0f;
for(int k=0; k<sides; k++){
GlStateManager.pushMatrix();
GlStateManager.translate((float)par2, (float)par4 + 0.05f, (float)par6);
float f1 = 1.0f;
GlStateManager.scale(f1, f1, f1);
float f2 = 0.5F;
float f3 = 0.0F;
float f4 = 0.2f;
float f5 = (float)(entity.posY - entity.getEntityBoundingBox().minY);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
float f61 = 0.0F;
int i = 0;
GlStateManager.rotate((360f/(float)sides)*k, 0, 1, 0);
GlStateManager.translate(0, 0, -2.3f);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
while (f4 > 0.0F){
this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
float f71 = icon.getMinU();
float f81 = icon.getMinV();
float f9 = icon.getMaxU();
float f10 = icon.getMaxV();
if (i / 2 % 2 == 0)
{
float f11 = f9;
f9 = f71;
f71 = f11;
}
buffer.pos((double)(f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f9, (double)f10).endVertex();
buffer.pos((double)(-f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f71, (double)f10).endVertex();
buffer.pos((double)(-f2 - f3), (double)(height - f5), (double)f61).tex((double)f71, (double)f81).endVertex();
buffer.pos((double)(f2 - f3), (double)(height - f5), (double)f61).tex((double)f9, (double)f81).endVertex();
f4 -= 0.45F;
f5 -= 0.45F;
f2 *= 0.9F;
f61 += 0.03F;
++i;
}
tessellator.draw();
GlStateManager.popMatrix();
}
for(int k=0; k<sides; k++){ GlStateManager.pushMatrix();
GlStateManager.enableBlend();
GlStateManager.pushMatrix(); GlStateManager.disableLighting();
GlStateManager.translate((float)par2, (float)par4 + 0.05f, (float)par6); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
float f1 = 1.0f; GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GlStateManager.scale(f1, f1, f1);
float f2 = 0.5F; float yOffset = 0;
float f3 = 0.0F;
float f4 = 0.2f; GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6);
float f5 = (float)(entity.posY - entity.getEntityBoundingBox().minY);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); this.bindTexture(texture);
float f61 = 0.0F; float f6 = 1.0F;
int i = 0; float f7 = 0.5F;
float f8 = 0.5F;
GlStateManager.rotate((360f/(float)sides)*k, 0, 1, 0);
GlStateManager.translate(0, 0, 2.3f); GlStateManager.rotate(-90, 1, 0, 0);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); GlStateManager.scale(scale, scale, scale);
while (f4 > 0.0F){ Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
float f71 = icon.getMinU(); buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex();
float f81 = icon.getMinV(); buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex();
float f9 = icon.getMaxU(); buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex();
float f10 = icon.getMaxV(); buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex();
if (i / 2 % 2 == 0) tessellator.draw();
{
float f11 = f9; GlStateManager.disableBlend();
f9 = f71; GlStateManager.enableLighting();
f71 = f11; GlStateManager.disableRescaleNormal();
} GlStateManager.popMatrix();
buffer.pos((double)(f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f9, (double)f10).endVertex(); // Fire
buffer.pos((double)(-f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f71, (double)f10).endVertex();
buffer.pos((double)(-f2 - f3), (double)(height - f5), (double)f61).tex((double)f71, (double)f81).endVertex(); GlStateManager.disableLighting();
buffer.pos((double)(f2 - f3), (double)(height - f5), (double)f61).tex((double)f9, (double)f81).endVertex(); TextureAtlasSprite icon = Minecraft.getMinecraft().getBlockRendererDispatcher()
f4 -= 0.45F; .getModelForState(Blocks.FIRE.getDefaultState()).getParticleTexture();
f5 -= 0.45F; int sides = 16;
f2 *= 0.9F; float height = 1.0f;
f61 += 0.03F;
++i; for(int k = 0; k < sides; k++){
}
GlStateManager.pushMatrix();
tessellator.draw(); GlStateManager.translate((float)par2, (float)par4 + 0.05f, (float)par6);
GlStateManager.popMatrix(); float f1 = 1.0f;
} GlStateManager.scale(f1, f1, f1);
float f2 = 0.5F;
GlStateManager.enableLighting(); float f3 = 0.0F;
} float f4 = 0.2f;
float f5 = (float)(entity.posY - entity.getEntityBoundingBox().minY);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
float f61 = 0.0F;
int i = 0;
GlStateManager.rotate((360f / (float)sides) * k, 0, 1, 0);
GlStateManager.translate(0, 0, -2.3f);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
while(f4 > 0.0F){
this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
float f71 = icon.getMinU();
float f81 = icon.getMinV();
float f9 = icon.getMaxU();
float f10 = icon.getMaxV();
if(i / 2 % 2 == 0){
float f11 = f9;
f9 = f71;
f71 = f11;
}
buffer.pos((double)(f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f9, (double)f10)
.endVertex();
buffer.pos((double)(-f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f71, (double)f10)
.endVertex();
buffer.pos((double)(-f2 - f3), (double)(height - f5), (double)f61).tex((double)f71, (double)f81)
.endVertex();
buffer.pos((double)(f2 - f3), (double)(height - f5), (double)f61).tex((double)f9, (double)f81)
.endVertex();
f4 -= 0.45F;
f5 -= 0.45F;
f2 *= 0.9F;
f61 += 0.03F;
++i;
}
tessellator.draw();
GlStateManager.popMatrix();
}
for(int k = 0; k < sides; k++){
GlStateManager.pushMatrix();
GlStateManager.translate((float)par2, (float)par4 + 0.05f, (float)par6);
float f1 = 1.0f;
GlStateManager.scale(f1, f1, f1);
float f2 = 0.5F;
float f3 = 0.0F;
float f4 = 0.2f;
float f5 = (float)(entity.posY - entity.getEntityBoundingBox().minY);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
float f61 = 0.0F;
int i = 0;
GlStateManager.rotate((360f / (float)sides) * k, 0, 1, 0);
GlStateManager.translate(0, 0, 2.3f);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
while(f4 > 0.0F){
this.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE);
float f71 = icon.getMinU();
float f81 = icon.getMinV();
float f9 = icon.getMaxU();
float f10 = icon.getMaxV();
if(i / 2 % 2 == 0){
float f11 = f9;
f9 = f71;
f71 = f11;
}
buffer.pos((double)(f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f9, (double)f10)
.endVertex();
buffer.pos((double)(-f2 - f3), (double)(0.0F - f5), (double)f61).tex((double)f71, (double)f10)
.endVertex();
buffer.pos((double)(-f2 - f3), (double)(height - f5), (double)f61).tex((double)f71, (double)f81)
.endVertex();
buffer.pos((double)(f2 - f3), (double)(height - f5), (double)f61).tex((double)f9, (double)f81)
.endVertex();
f4 -= 0.45F;
f5 -= 0.45F;
f2 *= 0.9F;
f61 += 0.03F;
++i;
}
tessellator.draw();
GlStateManager.popMatrix();
}
GlStateManager.enableLighting();
}
@Override @Override
protected ResourceLocation getEntityTexture(EntityFireRing entity) { protected ResourceLocation getEntityTexture(EntityFireRing entity){
return null; return null;
} }
@@ -4,10 +4,10 @@ import org.lwjgl.opengl.GL11;
import electroblob.wizardry.Wizardry; import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.projectile.EntityForceArrow; import electroblob.wizardry.entity.projectile.EntityForceArrow;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@@ -17,111 +17,111 @@ import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class RenderForceArrow extends Render<EntityForceArrow>{ public class RenderForceArrow extends Render<EntityForceArrow> {
private static final ResourceLocation arrowTextures = new ResourceLocation(Wizardry.MODID, "textures/entity/force_arrow.png"); private static final ResourceLocation arrowTextures = new ResourceLocation(Wizardry.MODID,
"textures/entity/force_arrow.png");
public RenderForceArrow(RenderManager renderManager){ public RenderForceArrow(RenderManager renderManager){
super(renderManager); super(renderManager);
} }
@Override
public void doRender(EntityForceArrow arrow, double par2, double par4, double par6, float par8, float par9){
this.bindEntityTexture(arrow);
GlStateManager.pushMatrix();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GlStateManager.translate((float)par2, (float)par4, (float)par6);
GlStateManager.rotate(arrow.prevRotationYaw + (arrow.rotationYaw - arrow.prevRotationYaw) * par9 - 90.0F, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(arrow.prevRotationPitch + (arrow.rotationPitch - arrow.prevRotationPitch) * par9, 0.0F, 0.0F, 1.0F);
GlStateManager.rotate(180, 0, 1, 0);
Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer();
float pixel = 1.0f/32.0f;
float u1 = 0.0f;
float u2 = pixel*14;
float v1 = 0.0f;
float v2 = pixel*7;
float u3 = pixel*16;
float u4 = 1.0f;
float v3 = 0.0f;
float v4 = pixel*16;
float u5 = 0.0f;
float u6 = pixel*7;
float v5 = pixel*25;
float v6 = 1.0f;
float scale = 0.05625F;
float f11 = 0.0f;
GlStateManager.enableRescaleNormal();
//f11 = (float)par1EntityArrow.arrowShake - par9;
if (f11 > 0.0F)
{
float f12 = -MathHelper.sin(f11 * 3.0F) * f11;
GlStateManager.rotate(f12, 0.0F, 0.0F, 1.0F);
}
scale*=0.8f;
GlStateManager.rotate(45.0F, 1.0F, 0.0F, 0.0F); @Override
GlStateManager.scale(scale, scale, scale); public void doRender(EntityForceArrow arrow, double par2, double par4, double par6, float par8, float par9){
GlStateManager.translate(-4.0F, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); this.bindEntityTexture(arrow);
buffer.pos(-5, 3.5, -3.5).tex((double)u5, (double)v5).endVertex(); GlStateManager.pushMatrix();
buffer.pos(-5, 3.5, 3.5).tex((double)u6, (double)v5).endVertex(); GlStateManager.disableLighting();
buffer.pos(-5, -3.5, 3.5).tex((double)u6, (double)v6).endVertex(); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
buffer.pos(-5, -3.5, -3.5).tex((double)u5, (double)v6);
tessellator.draw();
for(int i=0; i<5; i++){
GlStateManager.color(1, 1, 1, 1 - i*0.2f);
double j = i + ((double)arrow.ticksExisted%3)/3;
double width = 2.0d + (Math.sqrt(j*2)-0.6)*2;
GL11.glNormal3f(scale, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-10 + j*4, -width, -width).tex((double)u3, (double)v3).endVertex();
buffer.pos(-10 + j*4, -width, width).tex((double)u4, (double)v3).endVertex();
buffer.pos(-10 + j*4, width, width).tex((double)u4, (double)v4).endVertex();
buffer.pos(-10 + j*4, width, -width).tex((double)u3, (double)v4).endVertex();
tessellator.draw();
GL11.glNormal3f(-scale, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-10 + j*4, width, -width).tex((double)u3, (double)v3).endVertex();
buffer.pos(-10 + j*4, width, width).tex((double)u4, (double)v3).endVertex();
buffer.pos(-10 + j*4, -width, width).tex((double)u4, (double)v4).endVertex();
buffer.pos(-10 + j*4, -width, -width).tex((double)u3, (double)v4).endVertex();
tessellator.draw();
}
GlStateManager.color(1, 1, 1, 1); GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
for (int i = 0; i < 4; ++i) GlStateManager.translate((float)par2, (float)par4, (float)par6);
{ GlStateManager.rotate(arrow.prevRotationYaw + (arrow.rotationYaw - arrow.prevRotationYaw) * par9 - 90.0F, 0.0F,
GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); 1.0F, 0.0F);
GL11.glNormal3f(0.0F, 0.0F, scale); GlStateManager.rotate(arrow.prevRotationPitch + (arrow.rotationPitch - arrow.prevRotationPitch) * par9, 0.0F,
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); 0.0F, 1.0F);
buffer.pos(-10.0D, -4.0D, 0.0D).tex((double)u1, (double)v1).endVertex(); GlStateManager.rotate(180, 0, 1, 0);
buffer.pos(10.0D, -4.0D, 0.0D).tex((double)u2, (double)v1).endVertex(); Tessellator tessellator = Tessellator.getInstance();
buffer.pos(10.0D, 4.0D, 0.0D).tex((double)u2, (double)v2).endVertex(); BufferBuilder buffer = tessellator.getBuffer();
buffer.pos(-10.0D, 4.0D, 0.0D).tex((double)u1, (double)v2).endVertex(); float pixel = 1.0f / 32.0f;
tessellator.draw(); float u1 = 0.0f;
} float u2 = pixel * 14;
float v1 = 0.0f;
float v2 = pixel * 7;
float u3 = pixel * 16;
float u4 = 1.0f;
float v3 = 0.0f;
float v4 = pixel * 16;
float u5 = 0.0f;
float u6 = pixel * 7;
float v5 = pixel * 25;
float v6 = 1.0f;
float scale = 0.05625F;
float f11 = 0.0f;
GlStateManager.enableRescaleNormal();
// f11 = (float)par1EntityArrow.arrowShake - par9;
if(f11 > 0.0F){
float f12 = -MathHelper.sin(f11 * 3.0F) * f11;
GlStateManager.rotate(f12, 0.0F, 0.0F, 1.0F);
}
GlStateManager.disableBlend(); scale *= 0.8f;
GlStateManager.disableRescaleNormal();
GlStateManager.enableLighting();
GlStateManager.popMatrix();
}
@Override GlStateManager.rotate(45.0F, 1.0F, 0.0F, 0.0F);
protected ResourceLocation getEntityTexture(EntityForceArrow par1Entity) GlStateManager.scale(scale, scale, scale);
{ GlStateManager.translate(-4.0F, 0.0F, 0.0F);
return arrowTextures;
} buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-5, 3.5, -3.5).tex((double)u5, (double)v5).endVertex();
buffer.pos(-5, 3.5, 3.5).tex((double)u6, (double)v5).endVertex();
buffer.pos(-5, -3.5, 3.5).tex((double)u6, (double)v6).endVertex();
buffer.pos(-5, -3.5, -3.5).tex((double)u5, (double)v6);
tessellator.draw();
for(int i = 0; i < 5; i++){
GlStateManager.color(1, 1, 1, 1 - i * 0.2f);
double j = i + ((double)arrow.ticksExisted % 3) / 3;
double width = 2.0d + (Math.sqrt(j * 2) - 0.6) * 2;
GL11.glNormal3f(scale, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-10 + j * 4, -width, -width).tex((double)u3, (double)v3).endVertex();
buffer.pos(-10 + j * 4, -width, width).tex((double)u4, (double)v3).endVertex();
buffer.pos(-10 + j * 4, width, width).tex((double)u4, (double)v4).endVertex();
buffer.pos(-10 + j * 4, width, -width).tex((double)u3, (double)v4).endVertex();
tessellator.draw();
GL11.glNormal3f(-scale, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-10 + j * 4, width, -width).tex((double)u3, (double)v3).endVertex();
buffer.pos(-10 + j * 4, width, width).tex((double)u4, (double)v3).endVertex();
buffer.pos(-10 + j * 4, -width, width).tex((double)u4, (double)v4).endVertex();
buffer.pos(-10 + j * 4, -width, -width).tex((double)u3, (double)v4).endVertex();
tessellator.draw();
}
GlStateManager.color(1, 1, 1, 1);
for(int i = 0; i < 4; ++i){
GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F);
GL11.glNormal3f(0.0F, 0.0F, scale);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-10.0D, -4.0D, 0.0D).tex((double)u1, (double)v1).endVertex();
buffer.pos(10.0D, -4.0D, 0.0D).tex((double)u2, (double)v1).endVertex();
buffer.pos(10.0D, 4.0D, 0.0D).tex((double)u2, (double)v2).endVertex();
buffer.pos(-10.0D, 4.0D, 0.0D).tex((double)u1, (double)v2).endVertex();
tessellator.draw();
}
GlStateManager.disableBlend();
GlStateManager.disableRescaleNormal();
GlStateManager.enableLighting();
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityForceArrow par1Entity){
return arrowTextures;
}
} }
@@ -9,30 +9,31 @@ import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
public class RenderHammer extends Render<EntityHammer> { public class RenderHammer extends Render<EntityHammer> {
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_hammer.png"); private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID,
"textures/entity/lightning_hammer.png");
private ModelHammer model = new ModelHammer(); private ModelHammer model = new ModelHammer();
public RenderHammer(RenderManager renderManager){ public RenderHammer(RenderManager renderManager){
super(renderManager); super(renderManager);
} }
@Override @Override
public void doRender(EntityHammer entity, double x, double y, double z, float f, float f1) { public void doRender(EntityHammer entity, double x, double y, double z, float f, float f1){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.translate(x, y+1.5, z); GlStateManager.translate(x, y + 1.5, z);
GlStateManager.rotate(180, 0F, 0F, 1F); GlStateManager.rotate(180, 0F, 0F, 1F);
this.bindTexture(texture); this.bindTexture(texture);
model.render(entity, 0, 0, 0, 0, 0, 0.0625f); model.render(entity, 0, 0, 0, 0, 0, 0.0625f);
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
@Override @Override
protected ResourceLocation getEntityTexture(EntityHammer entity) { protected ResourceLocation getEntityTexture(EntityHammer entity){
return texture; return texture;
} }
@@ -12,28 +12,29 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class RenderIceGiant extends RenderLiving<EntityIceGiant> { public class RenderIceGiant extends RenderLiving<EntityIceGiant> {
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/ice_giant.png");
public RenderIceGiant(RenderManager renderManager){ private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID,
super(renderManager, new ModelIceGiant(), 0.5F); "textures/entity/ice_giant.png");
}
public RenderIceGiant(RenderManager renderManager){
super(renderManager, new ModelIceGiant(), 0.5F);
}
@Override @Override
protected ResourceLocation getEntityTexture(EntityIceGiant entity){ protected ResourceLocation getEntityTexture(EntityIceGiant entity){
return texture; return texture;
} }
@Override @Override
protected void rotateCorpse(EntityIceGiant entityLiving, float pitch, float yaw, float partialTicks){ protected void applyRotations(EntityIceGiant entityLiving, float pitch, float yaw, float partialTicks){
super.rotateCorpse(entityLiving, pitch, yaw, partialTicks); super.applyRotations(entityLiving, pitch, yaw, partialTicks);
if ((double)entityLiving.limbSwingAmount >= 0.01D){ if((double)entityLiving.limbSwingAmount >= 0.01D){
float f3 = 13.0F; float f3 = 13.0F;
float f4 = entityLiving.limbSwing - entityLiving.limbSwingAmount * (1.0F - partialTicks) + 6.0F; float f4 = entityLiving.limbSwing - entityLiving.limbSwingAmount * (1.0F - partialTicks) + 6.0F;
float f5 = (Math.abs(f4 % f3 - f3 * 0.5F) - f3 * 0.25F) / (f3 * 0.25F); float f5 = (Math.abs(f4 % f3 - f3 * 0.5F) - f3 * 0.25F) / (f3 * 0.25F);
GlStateManager.rotate(6.5F * f5, 0.0F, 0.0F, 1.0F); GlStateManager.rotate(6.5F * f5, 0.0F, 0.0F, 1.0F);
} }
} }
} }
@@ -4,10 +4,10 @@ import org.lwjgl.opengl.GL11;
import electroblob.wizardry.Wizardry; import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.construct.EntityIceSpike; import electroblob.wizardry.entity.construct.EntityIceSpike;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@@ -15,45 +15,46 @@ import net.minecraft.util.ResourceLocation;
public class RenderIceSpike extends Render<EntityIceSpike> { public class RenderIceSpike extends Render<EntityIceSpike> {
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/ice_spike.png"); private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID,
"textures/entity/ice_spike.png");
public RenderIceSpike(RenderManager renderManager){ public RenderIceSpike(RenderManager renderManager){
super(renderManager); super(renderManager);
} }
@Override @Override
public void doRender(EntityIceSpike entity, double x, double y, double z, float fa, float partialTickTime) { public void doRender(EntityIceSpike entity, double x, double y, double z, float fa, float partialTickTime){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.translate((float)x, (float)y, (float)z); GlStateManager.translate((float)x, (float)y, (float)z);
// Apparently, disabling lighting... doesn't disable lighting. Or at least, you can still set the brightness // Apparently, disabling lighting... doesn't disable lighting. Or at least, you can still set the brightness
// with setLightmapTextureCoords. // with setLightmapTextureCoords.
GlStateManager.disableLighting(); GlStateManager.disableLighting();
int j = entity.getBrightnessForRender(partialTickTime); int j = entity.getBrightnessForRender();
int k = j % 65536; int k = j % 65536;
int l = j / 65536; int l = j / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F);
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
bindTexture(texture); bindTexture(texture);
// West face // West face
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(0, 0, 0.5).tex(1, 1).endVertex(); buffer.pos(0, 0, 0.5).tex(1, 1).endVertex();
buffer.pos(0, 1, 0.5).tex(1, 0).endVertex(); buffer.pos(0, 1, 0.5).tex(1, 0).endVertex();
buffer.pos(0, 1, -0.5).tex(0, 0).endVertex(); buffer.pos(0, 1, -0.5).tex(0, 0).endVertex();
buffer.pos(0, 0, -0.5).tex(0, 1).endVertex(); buffer.pos(0, 0, -0.5).tex(0, 1).endVertex();
tessellator.draw(); tessellator.draw();
// South face // South face
buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX);
buffer.pos( 0.5, 0, 0).tex(1, 1).endVertex(); buffer.pos(0.5, 0, 0).tex(1, 1).endVertex();
buffer.pos( 0.5, 1, 0).tex(1, 0).endVertex(); buffer.pos(0.5, 1, 0).tex(1, 0).endVertex();
buffer.pos(-0.5, 1, 0).tex(0, 0).endVertex(); buffer.pos(-0.5, 1, 0).tex(0, 0).endVertex();
buffer.pos(-0.5, 0, 0).tex(0, 1).endVertex(); buffer.pos(-0.5, 0, 0).tex(0, 1).endVertex();
tessellator.draw(); tessellator.draw();
@@ -61,23 +62,23 @@ public class RenderIceSpike extends Render<EntityIceSpike> {
buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX);
buffer.pos(0, 0, -0.5).tex(0, 1).endVertex(); buffer.pos(0, 0, -0.5).tex(0, 1).endVertex();
buffer.pos(0, 1, -0.5).tex(0, 0).endVertex(); buffer.pos(0, 1, -0.5).tex(0, 0).endVertex();
buffer.pos(0, 1, 0.5).tex(1, 0).endVertex(); buffer.pos(0, 1, 0.5).tex(1, 0).endVertex();
buffer.pos(0, 0, 0.5).tex(1, 1).endVertex(); buffer.pos(0, 0, 0.5).tex(1, 1).endVertex();
tessellator.draw(); tessellator.draw();
// North face // North face
buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX);
buffer.pos(-0.5, 0, 0).tex(0, 1).endVertex(); buffer.pos(-0.5, 0, 0).tex(0, 1).endVertex();
buffer.pos(-0.5, 1, 0).tex(0, 0).endVertex(); buffer.pos(-0.5, 1, 0).tex(0, 0).endVertex();
buffer.pos( 0.5, 1, 0).tex(1, 0).endVertex(); buffer.pos(0.5, 1, 0).tex(1, 0).endVertex();
buffer.pos( 0.5, 0, 0).tex(1, 1).endVertex(); buffer.pos(0.5, 0, 0).tex(1, 1).endVertex();
tessellator.draw(); tessellator.draw();
GlStateManager.enableLighting(); GlStateManager.enableLighting();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
@Override @Override
protected ResourceLocation getEntityTexture(EntityIceSpike entity) { protected ResourceLocation getEntityTexture(EntityIceSpike entity){
return texture; return texture;
} }
@@ -3,79 +3,79 @@ package electroblob.wizardry.client.renderer;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import electroblob.wizardry.entity.projectile.EntityLightningDisc; import electroblob.wizardry.entity.projectile.EntityLightningDisc;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
public class RenderLightningDisc extends Render<EntityLightningDisc> { public class RenderLightningDisc extends Render<EntityLightningDisc> {
private final ResourceLocation texture; private final ResourceLocation texture;
private float scale = 1.0f; private float scale = 1.0f;
public RenderLightningDisc(RenderManager renderManager, ResourceLocation texture, float scale) { public RenderLightningDisc(RenderManager renderManager, ResourceLocation texture, float scale){
super(renderManager); super(renderManager);
this.texture = texture; this.texture = texture;
this.scale = scale; this.scale = scale;
} }
@Override @Override
public void doRender(EntityLightningDisc entity, double par2, double par4, double par6, float par8, float par9){ public void doRender(EntityLightningDisc entity, double par2, double par4, double par6, float par8, float par9){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.disableLighting(); GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
float yOffset = 0; float yOffset = 0;
GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6); GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6);
this.bindTexture(texture); this.bindTexture(texture);
float f6 = 1.0F; float f6 = 1.0F;
float f7 = 0.5F; float f7 = 0.5F;
float f8 = 0.5F; float f8 = 0.5F;
GlStateManager.rotate(-90, 1, 0, 0); GlStateManager.rotate(-90, 1, 0, 0);
GlStateManager.rotate(entity.ticksExisted*8, 0, 0, 1); GlStateManager.rotate(entity.ticksExisted * 8, 0, 0, 1);
GlStateManager.scale(scale, scale, scale); GlStateManager.scale(scale, scale, scale);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
//tessellator.setColorRGBA_I(k1, 128); // tessellator.setColorRGBA_I(k1, 128);
//buffer.normal(0.0F, 1.0F, 0.0F); // buffer.normal(0.0F, 1.0F, 0.0F);
buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex(); buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex(); buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex(); buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex();
buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex(); buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex();
tessellator.draw(); tessellator.draw();
buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX);
//buffer.normal(0.0F, 1.0F, 0.0F); // buffer.normal(0.0F, 1.0F, 0.0F);
buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex(); buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex();
buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex(); buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex();
buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex(); buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex();
buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex(); buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex();
tessellator.draw(); tessellator.draw();
GlStateManager.disableBlend(); GlStateManager.disableBlend();
GlStateManager.enableLighting(); GlStateManager.enableLighting();
GlStateManager.disableRescaleNormal(); GlStateManager.disableRescaleNormal();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
@Override @Override
protected ResourceLocation getEntityTexture(EntityLightningDisc entity) { protected ResourceLocation getEntityTexture(EntityLightningDisc entity){
return null; return null;
} }
@@ -4,68 +4,68 @@ import org.lwjgl.opengl.GL11;
import electroblob.wizardry.Wizardry; import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.construct.EntityLightningPulse; import electroblob.wizardry.entity.construct.EntityLightningPulse;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
public class RenderLightningPulse extends Render<EntityLightningPulse> { public class RenderLightningPulse extends Render<EntityLightningPulse> {
private final ResourceLocation[] textures = new ResourceLocation[8]; private final ResourceLocation[] textures = new ResourceLocation[8];
private float scale = 1.0f; private float scale = 1.0f;
public RenderLightningPulse(RenderManager renderManager, float scale) { public RenderLightningPulse(RenderManager renderManager, float scale){
super(renderManager); super(renderManager);
for(int i=0; i<textures.length; i++){ for(int i = 0; i < textures.length; i++){
textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_pulse_" + i + ".png"); textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/lightning_pulse_" + i + ".png");
} }
this.scale = scale; this.scale = scale;
} }
@Override @Override
public void doRender(EntityLightningPulse entity, double par2, double par4, double par6, float par8, float par9){ public void doRender(EntityLightningPulse entity, double par2, double par4, double par6, float par8, float par9){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.disableLighting(); GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
float yOffset = 0; float yOffset = 0;
GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6); GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6);
this.bindTexture(textures[entity.ticksExisted]); this.bindTexture(textures[entity.ticksExisted]);
float f6 = 1.0F; float f6 = 1.0F;
float f7 = 0.5F; float f7 = 0.5F;
float f8 = 0.5F; float f8 = 0.5F;
GlStateManager.rotate(-90, 1, 0, 0); GlStateManager.rotate(-90, 1, 0, 0);
GlStateManager.scale(scale, scale, scale); GlStateManager.scale(scale, scale, scale);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex(); buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex(); buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex(); buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex();
buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex(); buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex();
tessellator.draw(); tessellator.draw();
GlStateManager.disableBlend(); GlStateManager.disableBlend();
GlStateManager.enableLighting(); GlStateManager.enableLighting();
GlStateManager.disableRescaleNormal(); GlStateManager.disableRescaleNormal();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
@Override @Override
protected ResourceLocation getEntityTexture(EntityLightningPulse entity) { protected ResourceLocation getEntityTexture(EntityLightningPulse entity){
return null; return null;
} }
@@ -3,10 +3,10 @@ package electroblob.wizardry.client.renderer;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import electroblob.wizardry.entity.projectile.EntityMagicArrow; import electroblob.wizardry.entity.projectile.EntityMagicArrow;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@@ -18,105 +18,106 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class RenderMagicArrow extends Render<EntityMagicArrow> { public class RenderMagicArrow extends Render<EntityMagicArrow> {
private final ResourceLocation texture; private final ResourceLocation texture;
private boolean blend; private boolean blend;
private boolean renderEnds; private boolean renderEnds;
private double length = 8.0, width = 2.0; private double length = 8.0, width = 2.0;
private int pixelsLong = 16, pixelsWide = 5; private int pixelsLong = 16, pixelsWide = 5;
public RenderMagicArrow(RenderManager renderManager, ResourceLocation texture, boolean blend, double length, double width, int pixelsLong, int pixelsWide, boolean renderEnds){ public RenderMagicArrow(RenderManager renderManager, ResourceLocation texture, boolean blend, double length,
super(renderManager); double width, int pixelsLong, int pixelsWide, boolean renderEnds){
this.texture = texture; super(renderManager);
this.blend = blend; this.texture = texture;
this.renderEnds = renderEnds; this.blend = blend;
this.length = length; this.renderEnds = renderEnds;
this.width = width; this.length = length;
this.pixelsLong = pixelsLong; this.width = width;
this.pixelsWide = pixelsWide; this.pixelsLong = pixelsLong;
} this.pixelsWide = pixelsWide;
}
@Override
public void doRender(EntityMagicArrow entity, double par2, double par4, double par6, float par8, float par9){
this.bindEntityTexture(entity);
GlStateManager.pushMatrix();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
if(this.blend){
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
}
GlStateManager.translate((float)par2, (float)par4, (float)par6);
GlStateManager.rotate(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * par9 - 90.0F, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * par9, 0.0F, 0.0F, 1.0F);
Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer();
float f2 = 0.0F;
float f3 = pixelsLong / 32.0F;
float f4 = 0.0F;
float f5 = pixelsWide / 32.0F;
float f6 = 0.0F;
float f7 = 0.15625F;
float f8 = (float)5 / 32.0F;
float f9 = (float)10 / 32.0F;
float f10 = 0.05625F;
float f11 = 0.0f;
GlStateManager.enableRescaleNormal();
//f11 = (float)par1EntityArrow.arrowShake - par9;
if (f11 > 0.0F)
{
float f12 = -MathHelper.sin(f11 * 3.0F) * f11;
GlStateManager.rotate(f12, 0.0F, 0.0F, 1.0F);
}
GlStateManager.rotate(45.0F, 1.0F, 0.0F, 0.0F); @Override
GlStateManager.scale(f10, f10, f10); public void doRender(EntityMagicArrow entity, double par2, double par4, double par6, float par8, float par9){
GlStateManager.translate(-4.0F, 0.0F, 0.0F);
GL11.glNormal3f(f10, 0.0F, 0.0F);
if(renderEnds){ this.bindEntityTexture(entity);
// Ends GlStateManager.pushMatrix();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); GlStateManager.disableLighting();
buffer.pos(-7.0D, -width, -width).tex((double)f6, (double)f8).endVertex(); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
buffer.pos(-7.0D, -width, width).tex((double)f7, (double)f8).endVertex();
buffer.pos(-7.0D, width, width).tex((double)f7, (double)f9).endVertex();
buffer.pos(-7.0D, width, -width).tex((double)f6, (double)f9).endVertex();
tessellator.draw();
GL11.glNormal3f(-f10, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-7.0D, width, -width).tex((double)f6, (double)f8).endVertex();
buffer.pos(-7.0D, width, width).tex((double)f7, (double)f8).endVertex();
buffer.pos(-7.0D, -width, width).tex((double)f7, (double)f9).endVertex();
buffer.pos(-7.0D, -width, -width).tex((double)f6, (double)f9).endVertex();
tessellator.draw();
}
for (int i = 0; i < 4; ++i){ if(this.blend){
// Sides GlStateManager.enableBlend();
GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glNormal3f(0.0F, 0.0F, f10); }
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-length, -width, 0.0D).tex((double)f2, (double)f4).endVertex();
buffer.pos(length, -width, 0.0D).tex((double)f3, (double)f4).endVertex();
buffer.pos(length, width, 0.0D).tex((double)f3, (double)f5).endVertex();
buffer.pos(-length, width, 0.0D).tex((double)f2, (double)f5).endVertex();
tessellator.draw();
}
if(this.blend){ GlStateManager.translate((float)par2, (float)par4, (float)par6);
GlStateManager.disableBlend(); GlStateManager.rotate(entity.prevRotationYaw + (entity.rotationYaw - entity.prevRotationYaw) * par9 - 90.0F,
} 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(entity.prevRotationPitch + (entity.rotationPitch - entity.prevRotationPitch) * par9, 0.0F,
GlStateManager.disableRescaleNormal(); 0.0F, 1.0F);
GlStateManager.enableLighting(); Tessellator tessellator = Tessellator.getInstance();
GlStateManager.popMatrix(); BufferBuilder buffer = tessellator.getBuffer();
} float f2 = 0.0F;
float f3 = pixelsLong / 32.0F;
float f4 = 0.0F;
float f5 = pixelsWide / 32.0F;
float f6 = 0.0F;
float f7 = 0.15625F;
float f8 = (float)5 / 32.0F;
float f9 = (float)10 / 32.0F;
float f10 = 0.05625F;
float f11 = 0.0f;
GlStateManager.enableRescaleNormal();
// f11 = (float)par1EntityArrow.arrowShake - par9;
if(f11 > 0.0F){
float f12 = -MathHelper.sin(f11 * 3.0F) * f11;
GlStateManager.rotate(f12, 0.0F, 0.0F, 1.0F);
}
@Override GlStateManager.rotate(45.0F, 1.0F, 0.0F, 0.0F);
protected ResourceLocation getEntityTexture(EntityMagicArrow arrow) GlStateManager.scale(f10, f10, f10);
{ GlStateManager.translate(-4.0F, 0.0F, 0.0F);
return texture; GL11.glNormal3f(f10, 0.0F, 0.0F);
}
if(renderEnds){
// Ends
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-7.0D, -width, -width).tex((double)f6, (double)f8).endVertex();
buffer.pos(-7.0D, -width, width).tex((double)f7, (double)f8).endVertex();
buffer.pos(-7.0D, width, width).tex((double)f7, (double)f9).endVertex();
buffer.pos(-7.0D, width, -width).tex((double)f6, (double)f9).endVertex();
tessellator.draw();
GL11.glNormal3f(-f10, 0.0F, 0.0F);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-7.0D, width, -width).tex((double)f6, (double)f8).endVertex();
buffer.pos(-7.0D, width, width).tex((double)f7, (double)f8).endVertex();
buffer.pos(-7.0D, -width, width).tex((double)f7, (double)f9).endVertex();
buffer.pos(-7.0D, -width, -width).tex((double)f6, (double)f9).endVertex();
tessellator.draw();
}
for(int i = 0; i < 4; ++i){
// Sides
GlStateManager.rotate(90.0F, 1.0F, 0.0F, 0.0F);
GL11.glNormal3f(0.0F, 0.0F, f10);
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
buffer.pos(-length, -width, 0.0D).tex((double)f2, (double)f4).endVertex();
buffer.pos(length, -width, 0.0D).tex((double)f3, (double)f4).endVertex();
buffer.pos(length, width, 0.0D).tex((double)f3, (double)f5).endVertex();
buffer.pos(-length, width, 0.0D).tex((double)f2, (double)f5).endVertex();
tessellator.draw();
}
if(this.blend){
GlStateManager.disableBlend();
}
GlStateManager.disableRescaleNormal();
GlStateManager.enableLighting();
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityMagicArrow arrow){
return texture;
}
} }
@@ -5,22 +5,25 @@ import org.lwjgl.opengl.GL11;
import electroblob.wizardry.Wizardry; import electroblob.wizardry.Wizardry;
import electroblob.wizardry.tileentity.TileEntityMagicLight; import electroblob.wizardry.tileentity.TileEntityMagicLight;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
public class RenderMagicLight extends TileEntitySpecialRenderer<TileEntityMagicLight> { public class RenderMagicLight extends TileEntitySpecialRenderer<TileEntityMagicLight> {
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/light_ray.png"); private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID,
private static final ResourceLocation texture2 = new ResourceLocation(Wizardry.MODID, "textures/entity/light_aura.png"); "textures/entity/light_ray.png");
private static final ResourceLocation texture2 = new ResourceLocation(Wizardry.MODID,
"textures/entity/light_aura.png");
@Override @Override
public void renderTileEntityAt(TileEntityMagicLight tileentity, double x, double y, double z, float f, int destroyStage){ public void render(TileEntityMagicLight tileentity, double x, double y, double z, float f,
int destroyStage, float alpha){
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
@@ -34,16 +37,19 @@ public class RenderMagicLight extends TileEntitySpecialRenderer<TileEntityMagicL
GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5); GlStateManager.translate(x + 0.5, y + 0.5, z + 0.5);
if(tileentity.timer < 10){ if(tileentity.timer < 10){
GlStateManager.scale((float)tileentity.timer/10, (float)tileentity.timer/10, (float)tileentity.timer/10); GlStateManager.scale((float)tileentity.timer / 10, (float)tileentity.timer / 10,
(float)tileentity.timer / 10);
} }
if(tileentity.timer > tileentity.maxTimer-10){ if(tileentity.timer > tileentity.maxTimer - 10){
GlStateManager.scale((float)(tileentity.maxTimer-tileentity.timer)/10, (float)(tileentity.maxTimer-tileentity.timer)/10, (float)(tileentity.maxTimer-tileentity.timer)/10); GlStateManager.scale((float)(tileentity.maxTimer - tileentity.timer) / 10,
(float)(tileentity.maxTimer - tileentity.timer) / 10,
(float)(tileentity.maxTimer - tileentity.timer) / 10);
} }
// Renders the aura effect // Renders the aura effect
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
@@ -51,7 +57,9 @@ public class RenderMagicLight extends TileEntitySpecialRenderer<TileEntityMagicL
// This counteracts the reverse rotation behaviour when in front f5 view. // This counteracts the reverse rotation behaviour when in front f5 view.
// Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example. // Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example.
float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? Minecraft.getMinecraft().getRenderManager().playerViewX : -Minecraft.getMinecraft().getRenderManager().playerViewX; float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2
? Minecraft.getMinecraft().getRenderManager().playerViewX
: -Minecraft.getMinecraft().getRenderManager().playerViewX;
GlStateManager.rotate(180.0F - Minecraft.getMinecraft().getRenderManager().playerViewY, 0.0F, 1.0F, 0.0F); GlStateManager.rotate(180.0F - Minecraft.getMinecraft().getRenderManager().playerViewY, 0.0F, 1.0F, 0.0F);
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F); GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
@@ -75,45 +83,41 @@ public class RenderMagicLight extends TileEntitySpecialRenderer<TileEntityMagicL
GlStateManager.blendFunc(GL11.GL_ONE, GL11.GL_SRC_ALPHA); GlStateManager.blendFunc(GL11.GL_ONE, GL11.GL_SRC_ALPHA);
this.bindTexture(texture); this.bindTexture(texture);
if(tileentity.randomiser.length >= 30){ if(tileentity.randomiser.length >= 30){
for(int j=0; j<30; j++){ for(int j = 0; j < 30; j++){
int sliceAngle = 20 + tileentity.randomiser[j]; int sliceAngle = 20 + tileentity.randomiser[j];
float scale = 0.5f; float scale = 0.5f;
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.rotate(31*tileentity.randomiser[j], 1, 0, 0); GlStateManager.rotate(31 * tileentity.randomiser[j], 1, 0, 0);
GlStateManager.rotate(31*tileentity.randomiser2[j], 0, 0, 1); GlStateManager.rotate(31 * tileentity.randomiser2[j], 0, 0, 1);
/* /* OK, so here are the changes to rendering as far as I know: Vertex formats specify how the methods are
* OK, so here are the changes to rendering as far as I know: * arranged Color has to be called for every vertex, I think. The new methods thing is a bit weird,
* Vertex formats specify how the methods are arranged * because other than the number of arguments there is essentially no difference between pos, tex,
* Color has to be called for every vertex, I think. * color, normal and lightmap. At least they make the code more readable. */
* The new methods thing is a bit weird, because other than the number of arguments there is
* essentially no difference between pos, tex, color, normal and lightmap. At least they make
* the code more readable.
*/
buffer.begin(5, DefaultVertexFormats.POSITION_TEX_COLOR); buffer.begin(5, DefaultVertexFormats.POSITION_TEX_COLOR);
buffer.pos(0, 0, 0).tex(0, 0).color(255, 255, 255, 0).endVertex(); buffer.pos(0, 0, 0).tex(0, 0).color(255, 255, 255, 0).endVertex();
buffer.pos(0, 0, 0).tex(0, 1).color(255, 255, 255, 0).endVertex(); buffer.pos(0, 0, 0).tex(0, 1).color(255, 255, 255, 0).endVertex();
double x1 = scale*Math.sin((tileentity.timer + 40*j)*(Math.PI/180)); double x1 = scale * Math.sin((tileentity.timer + 40 * j) * (Math.PI / 180));
//double y1 = 0.7*Math.cos((timerentity.timer - 40*j)*(Math.PI/180))*j/10; // double y1 = 0.7*Math.cos((timerentity.timer - 40*j)*(Math.PI/180))*j/10;
double z1 = scale*Math.cos((tileentity.timer + 40*j)*(Math.PI/180)); double z1 = scale * Math.cos((tileentity.timer + 40 * j) * (Math.PI / 180));
double x2 = scale*Math.sin((tileentity.timer + 40*j - sliceAngle)*(Math.PI/180)); double x2 = scale * Math.sin((tileentity.timer + 40 * j - sliceAngle) * (Math.PI / 180));
//double y2 = 0.7*Math.sin((timerentity.timer - 40*j)*(Math.PI/180))*j/10; // double y2 = 0.7*Math.sin((timerentity.timer - 40*j)*(Math.PI/180))*j/10;
double z2 = scale*Math.cos((tileentity.timer + 40*j - sliceAngle)*(Math.PI/180)); double z2 = scale * Math.cos((tileentity.timer + 40 * j - sliceAngle) * (Math.PI / 180));
buffer.pos(x1, 0, z1).tex(1, 0).color(0, 0, 0, 255).endVertex(); buffer.pos(x1, 0, z1).tex(1, 0).color(0, 0, 0, 255).endVertex();
buffer.pos(x2, 0, z2).tex(1, 1).color(0, 0, 0, 255).endVertex(); buffer.pos(x2, 0, z2).tex(1, 1).color(0, 0, 0, 255).endVertex();
tessellator.draw(); tessellator.draw();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
} }
@@ -16,37 +16,37 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class RenderPhoenix extends RenderLiving<EntityPhoenix> { public class RenderPhoenix extends RenderLiving<EntityPhoenix> {
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/phoenix.png"); private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/phoenix.png");
public RenderPhoenix(RenderManager renderManager){ public RenderPhoenix(RenderManager renderManager){
super(renderManager, new ModelPhoenix(), 1.0f); super(renderManager, new ModelPhoenix(), 1.0f);
} }
@Override @Override
protected ResourceLocation getEntityTexture(EntityPhoenix entity){ protected ResourceLocation getEntityTexture(EntityPhoenix entity){
return texture; return texture;
} }
@Override @Override
protected void rotateCorpse(EntityPhoenix par1EntityPhoenix, float par2, float par3, float par4){ protected void applyRotations(EntityPhoenix par1EntityPhoenix, float par2, float par3, float par4){
GlStateManager.translate(0.0F, -0.1F, 0.0F); GlStateManager.translate(0.0F, -0.1F, 0.0F);
super.rotateCorpse(par1EntityPhoenix, par2, par3, par4); super.applyRotations(par1EntityPhoenix, par2, par3, par4);
} }
@Override @Override
public void doRender(EntityPhoenix phoenix, double par2, double par4, double par6, float par8, float par9){ public void doRender(EntityPhoenix phoenix, double par2, double par4, double par6, float par8, float par9){
GlStateManager.pushMatrix();
GlStateManager.disableLighting();
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
super.doRender(phoenix, par2, par4, par6, par8, par9);
GlStateManager.enableLighting(); GlStateManager.pushMatrix();
GlStateManager.disableBlend();
GlStateManager.popMatrix(); GlStateManager.disableLighting();
} GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
super.doRender(phoenix, par2, par4, par6, par8, par9);
GlStateManager.enableLighting();
GlStateManager.disableBlend();
GlStateManager.popMatrix();
}
} }
@@ -4,10 +4,10 @@ import org.lwjgl.opengl.GL11;
import electroblob.wizardry.entity.projectile.EntityMagicProjectile; import electroblob.wizardry.entity.projectile.EntityMagicProjectile;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@@ -18,71 +18,71 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class RenderProjectile extends Render<EntityMagicProjectile> { public class RenderProjectile extends Render<EntityMagicProjectile> {
private float scale; private float scale;
private boolean blend = false; private boolean blend = false;
private final ResourceLocation texture;
public RenderProjectile(RenderManager renderManager, float scale, ResourceLocation texture, boolean doBlending) private final ResourceLocation texture;
{
super(renderManager);
this.scale = scale;
this.texture = texture;
this.blend = doBlending;
}
@Override public RenderProjectile(RenderManager renderManager, float scale, ResourceLocation texture, boolean doBlending){
public void doRender(EntityMagicProjectile entity, double par2, double par4, double par6, float par8, float par9){ super(renderManager);
this.scale = scale;
GlStateManager.pushMatrix(); this.texture = texture;
this.bindTexture(texture); this.blend = doBlending;
GlStateManager.translate((float)par2, (float)par4, (float)par6); }
GlStateManager.enableRescaleNormal();
if(blend){ @Override
GlStateManager.enableBlend(); public void doRender(EntityMagicProjectile entity, double par2, double par4, double par6, float par8, float par9){
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
} GlStateManager.pushMatrix();
GlStateManager.disableLighting(); this.bindTexture(texture);
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); GlStateManager.translate((float)par2, (float)par4, (float)par6);
GlStateManager.enableRescaleNormal();
float f2 = this.scale; if(blend){
GlStateManager.scale(f2 / 1.0F, f2 / 1.0F, f2 / 1.0F); GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
Tessellator tessellator = Tessellator.getInstance(); }
VertexBuffer buffer = tessellator.getBuffer(); GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
float f3 = 0.0f;
float f4 = 1.0f; float f2 = this.scale;
float f5 = 0.0f; GlStateManager.scale(f2 / 1.0F, f2 / 1.0F, f2 / 1.0F);
float f6 = 1.0f;
float f7 = 1.0F; Tessellator tessellator = Tessellator.getInstance();
float f8 = 0.5F; BufferBuilder buffer = tessellator.getBuffer();
float f9 = 0.25F;
float f3 = 0.0f;
// This counteracts the reverse rotation behaviour when in front f5 view. float f4 = 1.0f;
// Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example. float f5 = 0.0f;
float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? this.renderManager.playerViewX : -this.renderManager.playerViewX; float f6 = 1.0f;
GlStateManager.rotate(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); float f7 = 1.0F;
GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F); float f8 = 0.5F;
float f9 = 0.25F;
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
//buffer.normal(0.0F, 1.0F, 0.0F); // This counteracts the reverse rotation behaviour when in front f5 view.
buffer.pos((double)(0.0F - f8), (double)(0.0F - f9), 0.0D).tex((double)f3, (double)f6).endVertex(); // Fun fact: this is a bug with vanilla too! Look at a snowball in front f5 view, for example.
buffer.pos((double)(f7 - f8), (double)(0.0F - f9), 0.0D).tex((double)f4, (double)f6).endVertex(); float yaw = Minecraft.getMinecraft().gameSettings.thirdPersonView == 2 ? this.renderManager.playerViewX
buffer.pos((double)(f7 - f8), (double)(1.0F - f9), 0.0D).tex((double)f4, (double)f5).endVertex(); : -this.renderManager.playerViewX;
buffer.pos((double)(0.0F - f8), (double)(1.0F - f9), 0.0D).tex((double)f3, (double)f5).endVertex(); GlStateManager.rotate(180.0F - this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F);
tessellator.draw(); GlStateManager.rotate(yaw, 1.0F, 0.0F, 0.0F);
GlStateManager.disableRescaleNormal(); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
if(blend){ // buffer.normal(0.0F, 1.0F, 0.0F);
GlStateManager.disableBlend(); buffer.pos((double)(0.0F - f8), (double)(0.0F - f9), 0.0D).tex((double)f3, (double)f6).endVertex();
} buffer.pos((double)(f7 - f8), (double)(0.0F - f9), 0.0D).tex((double)f4, (double)f6).endVertex();
GlStateManager.enableLighting(); buffer.pos((double)(f7 - f8), (double)(1.0F - f9), 0.0D).tex((double)f4, (double)f5).endVertex();
GlStateManager.popMatrix(); buffer.pos((double)(0.0F - f8), (double)(1.0F - f9), 0.0D).tex((double)f3, (double)f5).endVertex();
} tessellator.draw();
@Override GlStateManager.disableRescaleNormal();
protected ResourceLocation getEntityTexture(EntityMagicProjectile par1Entity){ if(blend){
return texture; GlStateManager.disableBlend();
} }
GlStateManager.enableLighting();
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityMagicProjectile par1Entity){
return texture;
}
} }
@@ -6,10 +6,10 @@ import electroblob.wizardry.entity.construct.EntityHealAura;
import electroblob.wizardry.entity.construct.EntityMagicConstruct; import electroblob.wizardry.entity.construct.EntityMagicConstruct;
import electroblob.wizardry.util.WizardryUtilities; import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.entity.Render; import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
@@ -17,12 +17,12 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
public class RenderSigil extends Render<EntityMagicConstruct> { public class RenderSigil extends Render<EntityMagicConstruct> {
private final ResourceLocation texture; private final ResourceLocation texture;
private float scale = 1.0f; private float scale = 1.0f;
private boolean invisibleToEnemies; private boolean invisibleToEnemies;
public RenderSigil(RenderManager renderManager, ResourceLocation texture, float scale, boolean invisibleToEnemies) { public RenderSigil(RenderManager renderManager, ResourceLocation texture, float scale, boolean invisibleToEnemies){
super(renderManager); super(renderManager);
this.texture = texture; this.texture = texture;
this.scale = scale; this.scale = scale;
@@ -30,59 +30,59 @@ public class RenderSigil extends Render<EntityMagicConstruct> {
} }
@Override @Override
public void doRender(EntityMagicConstruct entity, double par2, double par4, double par6, float par8, float par9){ public void doRender(EntityMagicConstruct entity, double par2, double par4, double par6, float par8, float par9){
// Makes the sigil invisible to enemies of the player that created it // Makes the sigil invisible to enemies of the player that created it
if(this.invisibleToEnemies){ if(this.invisibleToEnemies){
if(entity.getCaster() instanceof EntityPlayer if(entity.getCaster() instanceof EntityPlayer && !WizardryUtilities
&& !WizardryUtilities.isPlayerAlly((EntityPlayer)entity.getCaster(), Minecraft.getMinecraft().thePlayer)){ .isPlayerAlly((EntityPlayer)entity.getCaster(), Minecraft.getMinecraft().player)){
return; return;
} }
} }
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
GlStateManager.enableBlend(); GlStateManager.enableBlend();
GlStateManager.disableLighting(); GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
float yOffset = 0; float yOffset = 0;
GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6); GlStateManager.translate((float)par2, (float)par4 + yOffset, (float)par6);
this.bindTexture(texture); this.bindTexture(texture);
float f6 = 1.0F; float f6 = 1.0F;
float f7 = 0.5F; float f7 = 0.5F;
float f8 = 0.5F; float f8 = 0.5F;
GlStateManager.rotate(-90, 1, 0, 0); GlStateManager.rotate(-90, 1, 0, 0);
// Healing aura rotates slowly // Healing aura rotates slowly
if(entity instanceof EntityHealAura) GlStateManager.rotate(entity.ticksExisted/3.0f, 0, 0, 1); if(entity instanceof EntityHealAura) GlStateManager.rotate(entity.ticksExisted / 3.0f, 0, 0, 1);
GlStateManager.scale(scale, scale, scale); GlStateManager.scale(scale, scale, scale);
Tessellator tessellator = Tessellator.getInstance(); Tessellator tessellator = Tessellator.getInstance();
VertexBuffer buffer = tessellator.getBuffer(); BufferBuilder buffer = tessellator.getBuffer();
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX); buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
//tessellator.setColorRGBA_I(k1, 128); // tessellator.setColorRGBA_I(k1, 128);
//buffer.normal(0.0F, 1.0F, 0.0F); // buffer.normal(0.0F, 1.0F, 0.0F);
buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex(); buffer.pos((double)(0.0F - f7), (double)(0.0F - f8), 0.01).tex(0, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex(); buffer.pos((double)(f6 - f7), (double)(0.0F - f8), 0.01).tex(1, 1).endVertex();
buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex(); buffer.pos((double)(f6 - f7), (double)(1.0F - f8), 0.01).tex(1, 0).endVertex();
buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex(); buffer.pos((double)(0.0F - f7), (double)(1.0F - f8), 0.01).tex(0, 0).endVertex();
tessellator.draw(); tessellator.draw();
GlStateManager.disableBlend(); GlStateManager.disableBlend();
GlStateManager.enableLighting(); GlStateManager.enableLighting();
GlStateManager.disableRescaleNormal(); GlStateManager.disableRescaleNormal();
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
@Override @Override
protected ResourceLocation getEntityTexture(EntityMagicConstruct entity) { protected ResourceLocation getEntityTexture(EntityMagicConstruct entity){
return null; return null;
} }
@@ -3,7 +3,6 @@ package electroblob.wizardry.client.renderer;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import electroblob.wizardry.Wizardry; import electroblob.wizardry.Wizardry;
import net.minecraft.client.model.ModelHorse;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderHorse; import net.minecraft.client.renderer.entity.RenderHorse;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
@@ -14,23 +13,24 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class RenderSpiritHorse extends RenderHorse { public class RenderSpiritHorse extends RenderHorse {
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/spirit_horse.png");
public RenderSpiritHorse(RenderManager renderManager, float par2){ private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID,
super(renderManager, new ModelHorse(), par2); "textures/entity/spirit_horse.png");
}
@Override
protected ResourceLocation getEntityTexture(EntityHorse entity) {
return texture;
}
@Override public RenderSpiritHorse(RenderManager renderManager){
protected void preRenderCallback(EntityHorse entitylivingbaseIn, float partialTickTime){ super(renderManager);
super.preRenderCallback(entitylivingbaseIn, partialTickTime); }
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); @Override
} protected ResourceLocation getEntityTexture(EntityHorse entity){
return texture;
}
@Override
protected void preRenderCallback(EntityHorse entitylivingbaseIn, float partialTickTime){
super.preRenderCallback(entitylivingbaseIn, partialTickTime);
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
}
} }
@@ -3,7 +3,6 @@ package electroblob.wizardry.client.renderer;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import electroblob.wizardry.Wizardry; import electroblob.wizardry.Wizardry;
import net.minecraft.client.model.ModelWolf;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.entity.RenderWolf; import net.minecraft.client.renderer.entity.RenderWolf;
@@ -14,22 +13,23 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class RenderSpiritWolf extends RenderWolf { public class RenderSpiritWolf extends RenderWolf {
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/entity/spirit_wolf.png");
public RenderSpiritWolf(RenderManager renderManager, float par3){ private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID,
super(renderManager, new ModelWolf(), par3); "textures/entity/spirit_wolf.png");
}
@Override public RenderSpiritWolf(RenderManager renderManager){
protected ResourceLocation getEntityTexture(EntityWolf entity) { super(renderManager);
return texture; }
}
@Override @Override
protected void preRenderCallback(EntityWolf entity, float partialTickTime){ protected ResourceLocation getEntityTexture(EntityWolf entity){
super.preRenderCallback(entity, partialTickTime); return texture;
GlStateManager.enableBlend(); }
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
} @Override
protected void preRenderCallback(EntityWolf entity, float partialTickTime){
super.preRenderCallback(entity, partialTickTime);
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
}
} }
@@ -9,35 +9,37 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
public class RenderStatue extends TileEntitySpecialRenderer<TileEntityStatue> { public class RenderStatue extends TileEntitySpecialRenderer<TileEntityStatue> {
private int destroyStage = 0; // Gets set each time a statue is rendered to allow access from the layer renderer private int destroyStage = 0; // Gets set each time a statue is rendered to allow access from the layer renderer
@Override @Override
public void renderTileEntityAt(TileEntityStatue statue, double x, double y, double z, float partialTicks, int destroyStage){ public void render(TileEntityStatue statue, double x, double y, double z, float partialTicks,
int destroyStage, float alpha){
// Multiblock support for the breaking animation. The chest has its own way of doing this in // Multiblock support for the breaking animation. The chest has its own way of doing this in
// TileEntityRendererDispatcher, but I don't have access to that. // TileEntityRendererDispatcher, but I don't have access to that.
if(statue.position != 1 && destroyStage >= 0){ if(statue.position != 1 && destroyStage >= 0){
TileEntity tileentity = statue.getWorld().getTileEntity(statue.getPos().down(statue.position-1)); TileEntity tileentity = statue.getWorld().getTileEntity(statue.getPos().down(statue.position - 1));
//System.out.println(tileentity); // System.out.println(tileentity);
if(tileentity instanceof TileEntityStatue){ if(tileentity instanceof TileEntityStatue){
// If this is the block breaking animation pass and this isn't the bottom block, divert the call to // If this is the block breaking animation pass and this isn't the bottom block, divert the call to
// the bottom block. // the bottom block.
this.renderTileEntityAt((TileEntityStatue)tileentity, x, y - (statue.position-1), z, partialTicks, destroyStage); this.render((TileEntityStatue)tileentity, x, y - (statue.position - 1), z, partialTicks,
destroyStage, alpha);
} }
} }
if(statue.creature != null && statue.position == 1){ if(statue.creature != null && statue.position == 1){
this.destroyStage = destroyStage; this.destroyStage = destroyStage;
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
// The next line makes stuff render in the same place relative to the world wherever the player is. // The next line makes stuff render in the same place relative to the world wherever the player is.
GlStateManager.translate((float)x + 0.5F, (float)y, (float)z + 0.5F); GlStateManager.translate((float)x + 0.5F, (float)y, (float)z + 0.5F);
GlStateManager.enableLighting(); GlStateManager.enableLighting();
float yaw = statue.creature.prevRotationYaw; float yaw = statue.creature.prevRotationYaw;
int i = statue.creature.getBrightnessForRender(0); int i = statue.creature.getBrightnessForRender();
int j = i % 65536; int j = i % 65536;
int k = i / 65536; int k = i / 65536;
@@ -49,14 +51,14 @@ public class RenderStatue extends TileEntitySpecialRenderer<TileEntityStatue> {
if(!statue.isIce) statue.creature.setInvisible(true); if(!statue.isIce) statue.creature.setInvisible(true);
// Setting the last parameter to true prevents the debug bounding box from rendering. // Setting the last parameter to true prevents the debug bounding box from rendering.
// For some reason, passing in the partialTicks causes the entity to spin round really fast // For some reason, passing in the partialTicks causes the entity to spin round really fast
Minecraft.getMinecraft().getRenderManager().doRenderEntity(statue.creature, 0, 0, 0, 0, 0, true); Minecraft.getMinecraft().getRenderManager().renderEntity(statue.creature, 0, 0, 0, 0, 0, true);
if(!statue.isIce) statue.creature.setInvisible(false); if(!statue.isIce) statue.creature.setInvisible(false);
GlStateManager.popMatrix(); GlStateManager.popMatrix();
} }
} }
public ResourceLocation getBlockBreakingTexture(){ public ResourceLocation getBlockBreakingTexture(){
return destroyStage < 0 ? null : DESTROY_STAGES[destroyStage]; return destroyStage < 0 ? null : DESTROY_STAGES[destroyStage];
} }
@@ -13,22 +13,22 @@ import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class RenderWizard extends RenderBiped<EntityWizard> { public class RenderWizard extends RenderBiped<EntityWizard> {
static final ResourceLocation[] textures = new ResourceLocation[6]; static final ResourceLocation[] textures = new ResourceLocation[6];
public RenderWizard(RenderManager renderManager){ public RenderWizard(RenderManager renderManager){
super(renderManager, new ModelWizard(), 0.5F); super(renderManager, new ModelWizard(), 0.5F);
for(int i=0;i<6;i++){ for(int i = 0; i < 6; i++){
textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/wizard_" + i + ".png"); textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/wizard_" + i + ".png");
} }
// Just using the default without overriding models, since the armour sets its own model anyway. // Just using the default without overriding models, since the armour sets its own model anyway.
this.addLayer(new LayerBipedArmor(this)); this.addLayer(new LayerBipedArmor(this));
} }
@Override @Override
protected ResourceLocation getEntityTexture(EntityWizard wizard) { protected ResourceLocation getEntityTexture(EntityWizard wizard){
return textures[wizard.textureIndex]; return textures[wizard.textureIndex];
} }
} }
@@ -9,18 +9,15 @@ import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public class RenderWraithMinion extends RenderLiving<EntityBlazeMinion> public class RenderWraithMinion extends RenderLiving<EntityBlazeMinion> {
{
private ResourceLocation texture = new ResourceLocation("textures/entity/blaze.png"); private ResourceLocation texture = new ResourceLocation("textures/entity/blaze.png");
public RenderWraithMinion(RenderManager renderManagerIn) public RenderWraithMinion(RenderManager renderManagerIn){
{ super(renderManagerIn, new ModelBlaze(), 0.5F);
super(renderManagerIn, new ModelBlaze(), 0.5F); }
}
@Override @Override
protected ResourceLocation getEntityTexture(EntityBlazeMinion entity) protected ResourceLocation getEntityTexture(EntityBlazeMinion entity){
{ return texture;
return texture; }
}
} }
@@ -32,165 +32,177 @@ import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
public class CommandCastSpell extends CommandBase { public class CommandCastSpell extends CommandBase {
@Override @Override
public String getCommandName(){ public String getName(){
return Wizardry.settings.castCommandName; return Wizardry.settings.castCommandName;
} }
@Override @Override
public int getRequiredPermissionLevel(){ public int getRequiredPermissionLevel(){
// I *think* it's something like 0 = everyone, 1 = moderator, 2 = op/admin, 3 = op/console... // I *think* it's something like 0 = everyone, 1 = moderator, 2 = op/admin, 3 = op/console...
return 2; return 2;
} }
@Override @Override
public String getCommandUsage(ICommandSender p_71518_1_){ public String getUsage(ICommandSender sender){
// Not ideal, but the way this is implemented means I have no choice. Only used in the help command, so in there // Not ideal, but the way this is implemented means I have no choice. Only used in the help command, so in there
// the custom command name will not display. // the custom command name will not display.
return "commands.wizardry:cast.usage"; return "commands." + Wizardry.MODID + ":cast.usage";
//return I18n.format("commands.wizardry:cast.usage", Wizardry.settings.castCommandName); // return I18n.format("commands." + Wizardry.MODID + ":cast.usage", Wizardry.settings.castCommandName);
} }
@Override @Override
public List<String> getTabCompletionOptions(MinecraftServer server, ICommandSender sender, String[] arguments, BlockPos pos) { public List<String> getTabCompletions(MinecraftServer server, ICommandSender sender, String[] arguments,
BlockPos pos){
switch(arguments.length){ switch(arguments.length){
case 1: return getListOfStringsMatchingLastWord(arguments, Spell.getSpellNames()); case 1:
case 2: return getListOfStringsMatchingLastWord(arguments, server.getAllUsernames()); return getListOfStringsMatchingLastWord(arguments, Spell.getSpellNames());
case 2:
return getListOfStringsMatchingLastWord(arguments, server.getOnlinePlayerNames());
} }
return super.getTabCompletionOptions(server, sender, arguments, pos); return super.getTabCompletions(server, sender, arguments, pos);
} }
@Override @Override
public void execute(MinecraftServer server, ICommandSender sender, String[] arguments) throws CommandException { public void execute(MinecraftServer server, ICommandSender sender, String[] arguments) throws CommandException{
if(arguments.length < 1){ if(arguments.length < 1){
throw new WrongUsageException("commands.wizardry:cast.usage", Wizardry.settings.castCommandName); throw new WrongUsageException("commands." + Wizardry.MODID + ":cast.usage", Wizardry.settings.castCommandName);
}else{ }else{
// ===== Parameter retrieval =====
int i=0;
EntityPlayerMP caster = null;
try{
caster = getCommandSenderAsPlayer(sender);
}catch(PlayerNotFoundException exception){
// Nothing here since the player specifying is done later, I just don't want it to throw an exception here.
}
Spell spell = Spell.get(arguments[i++]);
if(spell == null){
throw new NumberInvalidException("commands.wizardry:cast.not_found", new Object[]{arguments[i-1]});
}
boolean castAsOtherPlayer = false;
if(i < arguments.length){
try{
// If the second argument is a player and is not the player that gave the command, the spell is cast
// as the given player rather than the command sender, and there is a different chat readout.
EntityPlayerMP entityplayermp = getPlayer(server, sender, arguments[i++]);
if(caster != entityplayermp){
castAsOtherPlayer = true;
caster = entityplayermp;
}
}catch(PlayerNotFoundException exception){
// If no player was found, rather than give an error it simply assumes the player was unspecified.
i--;
}
}
// If, after this point, the player is still null, the sender must be a command block or the console and the
// player must not have been specified, meaning an exception should be thrown.
if(caster == null) throw new PlayerNotFoundException("You must specify which player you wish to perform this action on.");
SpellModifiers modifiers = new SpellModifiers();
if(i < arguments.length){
// Copied from CommandGive. Why it doesn't just use arguments[i] itself I don't know.
String nbt = getChatComponentFromNthArg(sender, arguments, i++).getUnformattedText();
try{ // ===== Parameter retrieval =====
modifiers = SpellModifiers.fromNBT(JsonToNBT.getTagFromJson(nbt));
}catch(NBTException nbtexception){
throw new CommandException("commands.wizardry:cast.tag_error", nbtexception.getMessage());
}
for(float multiplier : modifiers.getModifiers().values()){
if(multiplier < 0){
throw new NumberInvalidException("commands.generic.double.tooSmall", multiplier, 0);
}else if(multiplier > Wizardry.settings.maxSpellCommandMultiplier){
throw new NumberInvalidException("commands.generic.double.tooBig", multiplier, Wizardry.settings.maxSpellCommandMultiplier);
}
}
}
// ===== Spell casting =====
// If anything stops the spell working at this point, nothing else happens.
if(MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Pre(caster, spell, modifiers, Source.COMMAND))){
displayFailMessage(sender, spell);
return;
}
WizardData data = WizardData.get((EntityPlayer)caster);
if(spell.isContinuous){
// Events for continuous spell casting via commands are dealt with in WizardData.
if(data != null){
if(data.isCasting()){
data.stopCastingContinuousSpell();
}else{
data.startCastingContinuousSpell(spell, modifiers);
if(castAsOtherPlayer){
sender.addChatMessage(new TextComponentTranslation("commands.wizardry:cast.success_remote_continuous", spell.getNameForTranslationFormatted(), caster.getName()));
}else{
sender.addChatMessage(new TextComponentTranslation("commands.wizardry:cast.success_continuous", spell.getNameForTranslationFormatted()));
}
}
return;
}
}else{
if(spell.cast(caster.worldObj, caster, EnumHand.MAIN_HAND, 0, modifiers)){ int i = 0;
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(caster, spell, modifiers, Source.COMMAND)); EntityPlayerMP caster = null;
if(spell.doesSpellRequirePacket()){ try{
caster = getCommandSenderAsPlayer(sender);
}catch (PlayerNotFoundException exception){
// Nothing here since the player specifying is done later, I just don't want it to throw an exception
// here.
}
Spell spell = Spell.get(arguments[i++]);
if(spell == null){
throw new NumberInvalidException("commands." + Wizardry.MODID + ":cast.not_found", new Object[]{arguments[i - 1]});
}
boolean castAsOtherPlayer = false;
if(i < arguments.length){
try{
// If the second argument is a player and is not the player that gave the command, the spell is cast
// as the given player rather than the command sender, and there is a different chat readout.
EntityPlayerMP entityplayermp = getPlayer(server, sender, arguments[i++]);
if(caster != entityplayermp){
castAsOtherPlayer = true;
caster = entityplayermp;
}
}catch (PlayerNotFoundException exception){
// If no player was found, rather than give an error it simply assumes the player was unspecified.
i--;
}
}
// If, after this point, the player is still null, the sender must be a command block or the console and the
// player must not have been specified, meaning an exception should be thrown.
if(caster == null)
throw new PlayerNotFoundException("You must specify which player you wish to perform this action on.");
SpellModifiers modifiers = new SpellModifiers();
if(i < arguments.length){
// Copied from CommandGive. Why it doesn't just use arguments[i] itself I don't know.
String nbt = getChatComponentFromNthArg(sender, arguments, i++).getUnformattedText();
try{
modifiers = SpellModifiers.fromNBT(JsonToNBT.getTagFromJson(nbt));
}catch (NBTException nbtexception){
throw new CommandException("commands." + Wizardry.MODID + ":cast.tag_error", nbtexception.getMessage());
}
for(float multiplier : modifiers.getModifiers().values()){
if(multiplier < 0){
throw new NumberInvalidException("commands.generic.double.tooSmall", multiplier, 0);
}else if(multiplier > Wizardry.settings.maxSpellCommandMultiplier){
throw new NumberInvalidException("commands.generic.double.tooBig", multiplier,
Wizardry.settings.maxSpellCommandMultiplier);
}
}
}
// ===== Spell casting =====
// If anything stops the spell working at this point, nothing else happens.
if(MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Pre(caster, spell, modifiers, Source.COMMAND))){
displayFailMessage(sender, spell);
return;
}
WizardData data = WizardData.get((EntityPlayer)caster);
if(spell.isContinuous){
// Events for continuous spell casting via commands are dealt with in WizardData.
if(data != null){
if(data.isCasting()){
data.stopCastingContinuousSpell();
}else{
data.startCastingContinuousSpell(spell, modifiers);
if(castAsOtherPlayer){
sender.sendMessage(
new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.success_remote_continuous",
spell.getNameForTranslationFormatted(), caster.getName()));
}else{
sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.success_continuous",
spell.getNameForTranslationFormatted()));
}
}
return;
}
}else{
if(spell.cast(caster.world, caster, EnumHand.MAIN_HAND, 0, modifiers)){
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post(caster, spell, modifiers, Source.COMMAND));
if(spell.doesSpellRequirePacket()){
// Sends a packet to all players in dimension to tell them to spawn particles. // Sends a packet to all players in dimension to tell them to spawn particles.
// Only sent if the spell succeeded, because if the spell failed, you wouldn't // Only sent if the spell succeeded, because if the spell failed, you wouldn't
// need to spawn any particles! // need to spawn any particles!
IMessage msg = new PacketCastSpell.Message(caster.getEntityId(), null, spell.id(), modifiers); IMessage msg = new PacketCastSpell.Message(caster.getEntityId(), null, spell.id(), modifiers);
WizardryPacketHandler.net.sendToDimension(msg, caster.worldObj.provider.getDimension()); WizardryPacketHandler.net.sendToDimension(msg, caster.world.provider.getDimension());
} }
if(castAsOtherPlayer){ if(castAsOtherPlayer){
sender.addChatMessage(new TextComponentTranslation("commands.wizardry:cast.success_remote", spell.getNameForTranslationFormatted(), caster.getName())); sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.success_remote",
}else{ spell.getNameForTranslationFormatted(), caster.getName()));
sender.addChatMessage(new TextComponentTranslation("commands.wizardry:cast.success", spell.getNameForTranslationFormatted())); }else{
} sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.success",
return; spell.getNameForTranslationFormatted()));
} }
} return;
}
displayFailMessage(sender, spell); }
}
displayFailMessage(sender, spell);
}
} }
/** Displays the "Unable to cast [spell]" message in the chat. */ /** Displays the "Unable to cast [spell]" message in the chat. */
private void displayFailMessage(ICommandSender sender, Spell spell){ private void displayFailMessage(ICommandSender sender, Spell spell){
ITextComponent message = new TextComponentTranslation("commands.wizardry:cast.fail", spell.getNameForTranslationFormatted()); ITextComponent message = new TextComponentTranslation("commands." + Wizardry.MODID + ":cast.fail",
message.getStyle().setColor(TextFormatting.RED); spell.getNameForTranslationFormatted());
sender.addChatMessage(message); message.getStyle().setColor(TextFormatting.RED);
sender.sendMessage(message);
} }
} }
@@ -22,7 +22,7 @@ import net.minecraftforge.common.MinecraftForge;
public class CommandDiscoverSpell extends CommandBase { public class CommandDiscoverSpell extends CommandBase {
@Override @Override
public String getCommandName(){ public String getName(){
return Wizardry.settings.discoverspellCommandName; return Wizardry.settings.discoverspellCommandName;
} }
@@ -32,39 +32,40 @@ public class CommandDiscoverSpell extends CommandBase {
return 2; return 2;
} }
/* /* @Override public boolean checkPermission(MinecraftServer server, ICommandSender sender){ // Only ops
@Override * (multiplayer) or players with cheats enabled (singleplayer/LAN) can use /discoverspell. return !(sender
public boolean checkPermission(MinecraftServer server, ICommandSender sender){ * instanceof EntityPlayer) ||
// Only ops (multiplayer) or players with cheats enabled (singleplayer/LAN) can use /discoverspell. * server.getServer().getConfigurationManager().func_152596_g(((EntityPlayer)sender).getGameProfile()); } */
return !(sender instanceof EntityPlayer) || server.getServer().getConfigurationManager().func_152596_g(((EntityPlayer)sender).getGameProfile());
}
*/
@Override @Override
public String getCommandUsage(ICommandSender p_71518_1_){ public String getUsage(ICommandSender sender){
// Not ideal, but the way this is implemented means I have no choice. Only used in the help command, so in there // Not ideal, but the way this is implemented means I have no choice. Only used in the help command, so in there
// the custom command name will not display. // the custom command name will not display.
return "commands.wizardry:discoverspell.usage"; return "commands." + Wizardry.MODID + ":discoverspell.usage";
//return I18n.format("commands.wizardry:discoverspell.usage", Wizardry.settings.discoverspellCommandName); // return I18n.format("commands." + Wizardry.MODID + ":discoverspell.usage", Wizardry.settings.discoverspellCommandName);
} }
@Override @Override
public List<String> getTabCompletionOptions(MinecraftServer server, ICommandSender sender, String[] arguments, BlockPos pos) { public List<String> getTabCompletions(MinecraftServer server, ICommandSender sender, String[] arguments,
BlockPos pos){
switch(arguments.length){ switch(arguments.length){
case 1: return getListOfStringsMatchingLastWord(arguments, Spell.getSpellNames()); case 1:
case 2: return getListOfStringsMatchingLastWord(arguments, server.getAllUsernames()); return getListOfStringsMatchingLastWord(arguments, Spell.getSpellNames());
case 2:
return getListOfStringsMatchingLastWord(arguments, server.getOnlinePlayerNames());
} }
return super.getTabCompletionOptions(server, sender, arguments, pos); return super.getTabCompletions(server, sender, arguments, pos);
} }
@Override @Override
public void execute(MinecraftServer server, ICommandSender sender, String[] arguments) throws CommandException { public void execute(MinecraftServer server, ICommandSender sender, String[] arguments) throws CommandException{
if(arguments.length < 1){ if(arguments.length < 1){
throw new WrongUsageException("commands.wizardry:discoverspell.usage", Wizardry.settings.discoverspellCommandName); throw new WrongUsageException("commands." + Wizardry.MODID + ":discoverspell.usage",
Wizardry.settings.discoverspellCommandName);
}else{ }else{
int i=0; int i = 0;
boolean clear = false; boolean clear = false;
boolean all = false; boolean all = false;
@@ -72,8 +73,9 @@ public class CommandDiscoverSpell extends CommandBase {
try{ try{
player = getCommandSenderAsPlayer(sender); player = getCommandSenderAsPlayer(sender);
}catch(PlayerNotFoundException exception){ }catch (PlayerNotFoundException exception){
// Nothing here since the player specifying is done later, I just don't want it to throw an exception here. // Nothing here since the player specifying is done later, I just don't want it to throw an exception
// here.
} }
Spell spell = Spells.none; Spell spell = Spells.none;
@@ -89,7 +91,8 @@ public class CommandDiscoverSpell extends CommandBase {
spell = Spell.get(arguments[i++]); spell = Spell.get(arguments[i++]);
if(spell == null){ if(spell == null){
throw new NumberInvalidException("commands.wizardry:discoverspell.not_found", new Object[]{arguments[i-1]}); throw new NumberInvalidException("commands." + Wizardry.MODID + ":discoverspell.not_found",
new Object[]{arguments[i - 1]});
} }
} }
@@ -104,25 +107,31 @@ public class CommandDiscoverSpell extends CommandBase {
// If, after this point, the player is still null, the sender must be a command block or the console and the // If, after this point, the player is still null, the sender must be a command block or the console and the
// player must not have been specified, meaning an exception should be thrown. // player must not have been specified, meaning an exception should be thrown.
if(player == null) throw new PlayerNotFoundException("You must specify which player you wish to perform this action on."); if(player == null)
throw new PlayerNotFoundException("You must specify which player you wish to perform this action on.");
WizardData properties = WizardData.get(player); WizardData properties = WizardData.get(player);
if(properties != null){ if(properties != null){
if(clear){ if(clear){
properties.spellsDiscovered.clear(); properties.spellsDiscovered.clear();
sender.addChatMessage(new TextComponentTranslation("commands.wizardry:discoverspell.clear", player.getName())); sender.sendMessage(
new TextComponentTranslation("commands." + Wizardry.MODID + ":discoverspell.clear", player.getName()));
}else if(all){ }else if(all){
properties.spellsDiscovered.addAll(Spell.getSpells(Spell.allSpells)); properties.spellsDiscovered.addAll(Spell.getSpells(Spell.allSpells));
sender.addChatMessage(new TextComponentTranslation("commands.wizardry:discoverspell.all", player.getName())); sender.sendMessage(
new TextComponentTranslation("commands." + Wizardry.MODID + ":discoverspell.all", player.getName()));
}else{ }else{
if(properties.hasSpellBeenDiscovered(spell)){ if(properties.hasSpellBeenDiscovered(spell)){
properties.spellsDiscovered.remove(spell); properties.spellsDiscovered.remove(spell);
sender.addChatMessage(new TextComponentTranslation("commands.wizardry:discoverspell.removespell", spell.getNameForTranslationFormatted(), player.getName())); sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":discoverspell.removespell",
spell.getNameForTranslationFormatted(), player.getName()));
}else{ }else{
if(!MinecraftForge.EVENT_BUS.post(new DiscoverSpellEvent(player, spell, DiscoverSpellEvent.Source.COMMAND))){ if(!MinecraftForge.EVENT_BUS
.post(new DiscoverSpellEvent(player, spell, DiscoverSpellEvent.Source.COMMAND))){
properties.discoverSpell(spell); properties.discoverSpell(spell);
sender.addChatMessage(new TextComponentTranslation("commands.wizardry:discoverspell.addspell", spell.getNameForTranslationFormatted(), player.getName())); sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":discoverspell.addspell",
spell.getNameForTranslationFormatted(), player.getName()));
} }
} }
} }
@@ -21,7 +21,7 @@ import net.minecraft.util.text.TextFormatting;
public class CommandSetAlly extends CommandBase { public class CommandSetAlly extends CommandBase {
@Override @Override
public String getCommandName(){ public String getName(){
return Wizardry.settings.allyCommandName; return Wizardry.settings.allyCommandName;
} }
@@ -32,41 +32,44 @@ public class CommandSetAlly extends CommandBase {
} }
@Override @Override
public boolean checkPermission(MinecraftServer server, ICommandSender p_71519_1_) public boolean checkPermission(MinecraftServer server, ICommandSender p_71519_1_){
{
return true; return true;
} }
@Override @Override
public String getCommandUsage(ICommandSender p_71518_1_){ public String getUsage(ICommandSender p_71518_1_){
// Not ideal, but the way this is implemented means I have no choice. Only used in the help command, so in there // Not ideal, but the way this is implemented means I have no choice. Only used in the help command, so in there
// the custom command name will not display. // the custom command name will not display.
return "commands.wizardry:ally.usage"; return "commands." + Wizardry.MODID + ":ally.usage";
//return I18n.format("commands.wizardry:ally.usage", Wizardry.settings.allyCommandName); // return I18n.format("commands." + Wizardry.MODID + ":ally.usage", Wizardry.settings.allyCommandName);
} }
@Override @Override
public List<String> getTabCompletionOptions(MinecraftServer server, ICommandSender sender, String[] arguments, BlockPos pos) { public List<String> getTabCompletions(MinecraftServer server, ICommandSender sender, String[] arguments,
BlockPos pos){
switch(arguments.length){ switch(arguments.length){
case 1: return getListOfStringsMatchingLastWord(arguments, server.getAllUsernames()); case 1:
case 2: return getListOfStringsMatchingLastWord(arguments, server.getAllUsernames()); return getListOfStringsMatchingLastWord(arguments, server.getOnlinePlayerNames());
case 2:
return getListOfStringsMatchingLastWord(arguments, server.getOnlinePlayerNames());
} }
return super.getTabCompletionOptions(server, sender, arguments, pos); return super.getTabCompletions(server, sender, arguments, pos);
} }
@Override @Override
public void execute(MinecraftServer server, ICommandSender sender, String[] arguments) throws CommandException { public void execute(MinecraftServer server, ICommandSender sender, String[] arguments) throws CommandException{
if(arguments.length < 1){ if(arguments.length < 1){
throw new WrongUsageException("commands.wizardry:ally.usage", Wizardry.settings.allyCommandName); throw new WrongUsageException("commands." + Wizardry.MODID + ":ally.usage", Wizardry.settings.allyCommandName);
}else{ }else{
EntityPlayerMP allyOf = null; EntityPlayerMP allyOf = null;
try{ try{
allyOf = getCommandSenderAsPlayer(sender); allyOf = getCommandSenderAsPlayer(sender);
}catch(PlayerNotFoundException exception){ }catch (PlayerNotFoundException exception){
// Nothing here since the player specifying is done later, I just don't want it to throw an exception here. // Nothing here since the player specifying is done later, I just don't want it to throw an exception
// here.
} }
boolean executeAsOtherPlayer = false; boolean executeAsOtherPlayer = false;
@@ -79,11 +82,13 @@ public class CommandSetAlly extends CommandBase {
allyOf = getPlayer(server, sender, arguments[1]); allyOf = getPlayer(server, sender, arguments[1]);
// Don't want to catch the exception here either, because there can be no other second argument. // Don't want to catch the exception here either, because there can be no other second argument.
if(allyOf != sender && sender instanceof EntityPlayer && !WizardryUtilities.isPlayerOp((EntityPlayer)sender, server)){ if(allyOf != sender && sender instanceof EntityPlayer
&& !WizardryUtilities.isPlayerOp((EntityPlayer)sender, server)){
// Displays a chat message if a non-op tries to modify another player's allies. // Displays a chat message if a non-op tries to modify another player's allies.
TextComponentTranslation TextComponentTranslation2 = new TextComponentTranslation("commands.wizardry:ally.permission"); TextComponentTranslation TextComponentTranslation2 = new TextComponentTranslation(
"commands." + Wizardry.MODID + ":ally.permission");
TextComponentTranslation2.getStyle().setColor(TextFormatting.RED); TextComponentTranslation2.getStyle().setColor(TextFormatting.RED);
allyOf.addChatMessage(TextComponentTranslation2); allyOf.sendMessage(TextComponentTranslation2);
return; return;
} }
@@ -92,18 +97,20 @@ public class CommandSetAlly extends CommandBase {
// If, after this point, allyOf is still null, the sender must be a command block or the console and two // If, after this point, allyOf is still null, the sender must be a command block or the console and two
// players must not have been specified, meaning an exception should be thrown. // players must not have been specified, meaning an exception should be thrown.
if(allyOf == null) throw new PlayerNotFoundException("You must specify which player you wish to perform this action on."); if(allyOf == null)
throw new PlayerNotFoundException("You must specify which player you wish to perform this action on.");
if(allyOf == ally) throw new NumberInvalidException("commands.wizardry:ally.self"); if(allyOf == ally) throw new NumberInvalidException("commands." + Wizardry.MODID + ":ally.self");
if(WizardData.get(allyOf) != null){ if(WizardData.get(allyOf) != null){
String string = WizardData.get(allyOf).toggleAlly(ally) ? "add" : "remove"; String string = WizardData.get(allyOf).toggleAlly(ally) ? "add" : "remove";
if(executeAsOtherPlayer){ if(executeAsOtherPlayer){
sender.addChatMessage(new TextComponentTranslation("commands.wizardry:ally." + string + "ally", ally.getName(), allyOf.getName())); sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":ally." + string + "ally",
ally.getName(), allyOf.getName()));
// In this case, the player whose allies have been modified is also notified. // In this case, the player whose allies have been modified is also notified.
allyOf.addChatMessage(new TextComponentTranslation("item.wand." + string + "ally", ally.getName())); allyOf.sendMessage(new TextComponentTranslation("item.wand." + string + "ally", ally.getName()));
}else{ }else{
sender.addChatMessage(new TextComponentTranslation("item.wand." + string + "ally", ally.getName())); sender.sendMessage(new TextComponentTranslation("item.wand." + string + "ally", ally.getName()));
} }
} }
@@ -21,7 +21,7 @@ import net.minecraft.util.text.TextFormatting;
public class CommandViewAllies extends CommandBase { public class CommandViewAllies extends CommandBase {
@Override @Override
public String getCommandName(){ public String getName(){
return Wizardry.settings.alliesCommandName; return Wizardry.settings.alliesCommandName;
} }
@@ -30,37 +30,38 @@ public class CommandViewAllies extends CommandBase {
// I *think* it's something like 0 = everyone, 1 = moderator, 2 = op/admin, 3 = op/console... // I *think* it's something like 0 = everyone, 1 = moderator, 2 = op/admin, 3 = op/console...
return 0; return 0;
} }
@Override
public boolean checkPermission(MinecraftServer server, ICommandSender p_71519_1_)
{
return true;
}
@Override @Override
public String getCommandUsage(ICommandSender p_71518_1_){ public boolean checkPermission(MinecraftServer server, ICommandSender p_71519_1_){
return true;
}
@Override
public String getUsage(ICommandSender p_71518_1_){
// Not ideal, but the way this is implemented means I have no choice. Only used in the help command, so in there // Not ideal, but the way this is implemented means I have no choice. Only used in the help command, so in there
// the custom command name will not display. // the custom command name will not display.
return "commands.wizardry:allies.usage"; return "commands." + Wizardry.MODID + ":allies.usage";
//return I18n.format("commands.wizardry:allies.usage", Wizardry.settings.alliesCommandName); // return I18n.format("commands." + Wizardry.MODID + ":allies.usage", Wizardry.settings.alliesCommandName);
} }
@Override @Override
public List<String> getTabCompletionOptions(MinecraftServer server, ICommandSender sender, String[] arguments, BlockPos pos) { public List<String> getTabCompletions(MinecraftServer server, ICommandSender sender, String[] arguments,
BlockPos pos){
switch(arguments.length){ switch(arguments.length){
case 1: return getListOfStringsMatchingLastWord(arguments, server.getAllUsernames()); case 1:
return getListOfStringsMatchingLastWord(arguments, server.getOnlinePlayerNames());
} }
return super.getTabCompletionOptions(server, sender, arguments, pos); return super.getTabCompletions(server, sender, arguments, pos);
} }
@Override @Override
public void execute(MinecraftServer server, ICommandSender sender, String[] arguments) throws CommandException { public void execute(MinecraftServer server, ICommandSender sender, String[] arguments) throws CommandException{
EntityPlayerMP player = null; EntityPlayerMP player = null;
try{ try{
player = getCommandSenderAsPlayer(sender); player = getCommandSenderAsPlayer(sender);
}catch(PlayerNotFoundException exception){ }catch (PlayerNotFoundException exception){
// Nothing here since the player specifying is done later, I just don't want it to throw an exception here. // Nothing here since the player specifying is done later, I just don't want it to throw an exception here.
} }
@@ -70,12 +71,14 @@ public class CommandViewAllies extends CommandBase {
player = getPlayer(server, sender, arguments[0]); player = getPlayer(server, sender, arguments[0]);
// Don't want to catch the exception here either, because there can be no other first argument. // Don't want to catch the exception here either, because there can be no other first argument.
if(player != sender && sender instanceof EntityPlayer && !WizardryUtilities.isPlayerOp((EntityPlayer)sender, server)){ if(player != sender && sender instanceof EntityPlayer
// Displays a chat message if a non-op tries to view another player's allies. && !WizardryUtilities.isPlayerOp((EntityPlayer)sender, server)){
TextComponentTranslation TextComponentTranslation2 = new TextComponentTranslation("commands.wizardry:allies.permission"); // Displays a chat message if a non-op tries to view another player's allies.
TextComponentTranslation TextComponentTranslation2 = new TextComponentTranslation(
"commands." + Wizardry.MODID + ":allies.permission");
TextComponentTranslation2.getStyle().setColor(TextFormatting.RED); TextComponentTranslation2.getStyle().setColor(TextFormatting.RED);
player.addChatMessage(TextComponentTranslation2); player.sendMessage(TextComponentTranslation2);
return; return;
} }
@@ -84,7 +87,8 @@ public class CommandViewAllies extends CommandBase {
// If, after this point, player is still null, the sender must be a command block or the console and the // If, after this point, player is still null, the sender must be a command block or the console and the
// player must not have been specified, meaning an exception should be thrown. // player must not have been specified, meaning an exception should be thrown.
if(player == null) throw new PlayerNotFoundException("You must specify which player you wish to perform this action on."); if(player == null)
throw new PlayerNotFoundException("You must specify which player you wish to perform this action on.");
if(WizardData.get(player) != null){ if(WizardData.get(player) != null){
@@ -98,13 +102,14 @@ public class CommandViewAllies extends CommandBase {
// Cuts the last " ," off of the string. // Cuts the last " ," off of the string.
string = string.substring(0, string.length() - 2); string = string.substring(0, string.length() - 2);
}else{ }else{
string = I18n.format("commands.wizardry:allies.none"); string = I18n.format("commands." + Wizardry.MODID + ":allies.none");
} }
if(executeAsOtherPlayer){ if(executeAsOtherPlayer){
sender.addChatMessage(new TextComponentTranslation("commands.wizardry:allies.list_other", player.getName(), string)); sender.sendMessage(
new TextComponentTranslation("commands." + Wizardry.MODID + ":allies.list_other", player.getName(), string));
}else{ }else{
sender.addChatMessage(new TextComponentTranslation("commands.wizardry:allies.list", string)); sender.sendMessage(new TextComponentTranslation("commands." + Wizardry.MODID + ":allies.list", string));
} }
} }
} }
@@ -15,10 +15,12 @@ public final class Constants {
public static final float COOLDOWN_REDUCTION_PER_LEVEL = 0.15f; public static final float COOLDOWN_REDUCTION_PER_LEVEL = 0.15f;
/** The fraction by which maximum charge is increased for each level of storage upgrade. */ /** The fraction by which maximum charge is increased for each level of storage upgrade. */
public static final float STORAGE_INCREASE_PER_LEVEL = 0.15f; public static final float STORAGE_INCREASE_PER_LEVEL = 0.15f;
/** The fraction by which damage is increased for each tier of matching wand. */ /** The fraction by which damage is increased for each tier of matching wand. */
public static final float DAMAGE_INCREASE_PER_TIER = 0.15f; public static final float DAMAGE_INCREASE_PER_TIER = 0.15f;
/** The fraction by which costs are reduced for each piece of matching armour. Note that changing this value will not /**
* affect continuous spells, since they are handled differently. */ * The fraction by which costs are reduced for each piece of matching armour. Note that changing this value will not
* affect continuous spells, since they are handled differently.
*/
public static final float COST_REDUCTION_PER_ARMOUR = 0.2f; public static final float COST_REDUCTION_PER_ARMOUR = 0.2f;
/** The fraction by which spell duration is increased for each level of duration upgrade. */ /** 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 final float DURATION_INCREASE_PER_LEVEL = 0.25f;
@@ -34,11 +36,15 @@ public final class Constants {
public static final float FROST_FATIGUE_PER_LEVEL = 0.45f; public static final float FROST_FATIGUE_PER_LEVEL = 0.45f;
/** The number of ticks between each mana increase for wands with the condenser upgrade. */ /** The number of ticks between each mana increase for wands with the condenser upgrade. */
public static final int CONDENSER_TICK_INTERVAL = 50; public static final int CONDENSER_TICK_INTERVAL = 50;
/** The amount of mana given for a kill for each level of siphon upgrade. A random amount from 0 to this number - 1 /**
* is also added. See {@link WizardryEventHandler#onLivingDeathEvent} for more details. */ * The amount of mana given for a kill for each level of siphon upgrade. A random amount from 0 to this number - 1
* is also added. See {@link WizardryEventHandler#onLivingDeathEvent} for more details.
*/
public static final int SIPHON_MANA_PER_LEVEL = 3; public static final int SIPHON_MANA_PER_LEVEL = 3;
/** The number of ticks between the spawning of patches of decay when an entity has the decay effect. /**
* Note that decay won't spawn again if something is already standing in it. */ * The number of ticks between the spawning of patches of decay when an entity has the decay effect. Note that decay
* won't spawn again if something is already standing in it.
*/
public static final int DECAY_SPREAD_INTERVAL = 8; public static final int DECAY_SPREAD_INTERVAL = 8;
} }
@@ -1,6 +1,7 @@
package electroblob.wizardry.constants; package electroblob.wizardry.constants;
import electroblob.wizardry.Wizardry; import electroblob.wizardry.Wizardry;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.Style; import net.minecraft.util.text.Style;
@@ -10,8 +11,10 @@ import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
public enum Element { public enum Element {
/** The 'default' element, with {@link electroblob.wizardry.spell.MagicMissile MagicMissile} being its only spell. */ /**
* The 'default' element, with {@link electroblob.wizardry.spell.MagicMissile MagicMissile} being its only spell.
*/
MAGIC(new Style().setColor(TextFormatting.GRAY), "simple", Wizardry.MODID), MAGIC(new Style().setColor(TextFormatting.GRAY), "simple", Wizardry.MODID),
FIRE(new Style().setColor(TextFormatting.DARK_RED), "fire", Wizardry.MODID), FIRE(new Style().setColor(TextFormatting.DARK_RED), "fire", Wizardry.MODID),
ICE(new Style().setColor(TextFormatting.AQUA), "ice", Wizardry.MODID), ICE(new Style().setColor(TextFormatting.AQUA), "ice", Wizardry.MODID),
@@ -20,14 +23,14 @@ public enum Element {
EARTH(new Style().setColor(TextFormatting.DARK_GREEN), "earth", Wizardry.MODID), EARTH(new Style().setColor(TextFormatting.DARK_GREEN), "earth", Wizardry.MODID),
SORCERY(new Style().setColor(TextFormatting.GREEN), "sorcery", Wizardry.MODID), SORCERY(new Style().setColor(TextFormatting.GREEN), "sorcery", Wizardry.MODID),
HEALING(new Style().setColor(TextFormatting.YELLOW), "healing", Wizardry.MODID); HEALING(new Style().setColor(TextFormatting.YELLOW), "healing", Wizardry.MODID);
/** Display colour for this element */ /** Display colour for this element */
private final Style colour; private final Style colour;
/** Unlocalised name for this element */ /** Unlocalised name for this element */
private final String unlocalisedName; private final String unlocalisedName;
/** The {@link ResourceLocation} for this element's 8x8 icon (displayed in the arcane workbench GUI) */ /** The {@link ResourceLocation} for this element's 8x8 icon (displayed in the arcane workbench GUI) */
private final ResourceLocation icon; private final ResourceLocation icon;
private Element(Style colour, String name, String modid){ private Element(Style colour, String name, String modid){
this.colour = colour; this.colour = colour;
this.unlocalisedName = name; this.unlocalisedName = name;
@@ -37,9 +40,9 @@ public enum Element {
/** Returns the translated display name of this element, without formatting. */ /** Returns the translated display name of this element, without formatting. */
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public String getDisplayName(){ public String getDisplayName(){
return net.minecraft.client.resources.I18n.format("element." + getUnlocalisedName()); return I18n.format("element." + getUnlocalisedName());
} }
/** Returns the {@link Style} object representing the colour of this element. */ /** Returns the {@link Style} object representing the colour of this element. */
public Style getColour(){ public Style getColour(){
return colour; return colour;
@@ -1,23 +1,21 @@
package electroblob.wizardry.constants; package electroblob.wizardry.constants;
import net.minecraft.client.resources.I18n;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
public enum SpellType { public enum SpellType {
ATTACK("attack"), ATTACK("attack"), DEFENCE("defence"), UTILITY("utility"), MINION("minion");
DEFENCE("defence"),
UTILITY("utility"),
MINION("minion");
private final String unlocalisedName; private final String unlocalisedName;
SpellType(String name){ SpellType(String name){
this.unlocalisedName = name; this.unlocalisedName = name;
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public String getDisplayName(){ public String getDisplayName(){
return net.minecraft.client.resources.I18n.format("spelltype." + unlocalisedName); return I18n.format("spelltype." + unlocalisedName);
} }
} }
@@ -2,18 +2,19 @@ package electroblob.wizardry.constants;
import java.util.Random; import java.util.Random;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.text.Style; import net.minecraft.util.text.Style;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.fml.relauncher.SideOnly;
public enum Tier { public enum Tier {
BASIC(700, 3, 12, new Style().setColor(TextFormatting.WHITE), "basic"), BASIC(700, 3, 12, new Style().setColor(TextFormatting.WHITE), "basic"), APPRENTICE(1000, 4, 5,
APPRENTICE(1000, 4, 5, new Style().setColor(TextFormatting.AQUA), "apprentice"), new Style().setColor(TextFormatting.AQUA), "apprentice"), ADVANCED(1500, 5, 2,
ADVANCED(1500, 5, 2, new Style().setColor(TextFormatting.DARK_BLUE), "advanced"), new Style().setColor(TextFormatting.DARK_BLUE),
MASTER(2500, 6, 1, new Style().setColor(TextFormatting.DARK_PURPLE), "master"); "advanced"), MASTER(2500, 6, 1, new Style().setColor(TextFormatting.DARK_PURPLE), "master");
/** Maximum mana a wand of this tier can store. */ /** Maximum mana a wand of this tier can store. */
public final int maxCharge; public final int maxCharge;
/** Just an ordinal. Shouldn't really be needed but no point changing it now. */ /** Just an ordinal. Shouldn't really be needed but no point changing it now. */
@@ -25,9 +26,9 @@ public enum Tier {
/** The colour of text associated with this tier. */ /** The colour of text associated with this tier. */
// Changed to a Style object for consistency. // Changed to a Style object for consistency.
private final Style colour; private final Style colour;
private final String unlocalisedName; private final String unlocalisedName;
private Tier(int maxCharge, int upgradeLimit, int weight, Style colour, String name){ private Tier(int maxCharge, int upgradeLimit, int weight, Style colour, String name){
this.maxCharge = maxCharge; this.maxCharge = maxCharge;
this.level = ordinal(); this.level = ordinal();
@@ -38,15 +39,15 @@ public enum Tier {
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public String getDisplayName() { public String getDisplayName(){
return net.minecraft.client.resources.I18n.format("tier." + unlocalisedName); return I18n.format("tier." + unlocalisedName);
} }
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public String getDisplayNameWithFormatting() { public String getDisplayNameWithFormatting(){
return this.getFormattingCode() + net.minecraft.client.resources.I18n.format("tier." + unlocalisedName); return this.getFormattingCode() + I18n.format("tier." + unlocalisedName);
} }
public String getUnlocalisedName(){ public String getUnlocalisedName(){
return unlocalisedName; return unlocalisedName;
} }
@@ -54,28 +55,31 @@ public enum Tier {
public String getFormattingCode(){ public String getFormattingCode(){
return colour.getFormattingCode(); return colour.getFormattingCode();
} }
/** Returns a random tier based on the standard weighting. Currently, the standard weighting is: Basic (Novice) 60%, /**
* Returns a random tier based on the standard weighting. Currently, the standard weighting is: Basic (Novice) 60%,
* Apprentice 25%, Advanced 10%, Master 5%. If an array of tiers is given, it picks a tier from the array, with the * Apprentice 25%, Advanced 10%, Master 5%. If an array of tiers is given, it picks a tier from the array, with the
* same relative weights for each. For example, if the array contains APPRENTICE and MASTER, then the weighting will * same relative weights for each. For example, if the array contains APPRENTICE and MASTER, then the weighting will
* become: Apprentice 83.3%, Master 16.7%. */ * become: Apprentice 83.3%, Master 16.7%.
*/
public static Tier getWeightedRandomTier(Random random, Tier... tiers){ public static Tier getWeightedRandomTier(Random random, Tier... tiers){
if(tiers.length == 0) tiers = values(); if(tiers.length == 0) tiers = values();
int totalWeight = 0; int totalWeight = 0;
for(Tier tier : tiers) totalWeight += tier.weight; for(Tier tier : tiers)
totalWeight += tier.weight;
int randomiser = random.nextInt(totalWeight); int randomiser = random.nextInt(totalWeight);
int cumulativeWeight = 0; int cumulativeWeight = 0;
for(Tier tier : tiers){ for(Tier tier : tiers){
cumulativeWeight += tier.weight; cumulativeWeight += tier.weight;
if(randomiser < cumulativeWeight) return tier; if(randomiser < cumulativeWeight) return tier;
} }
// This will never happen, but it might as well be a sensible result. // This will never happen, but it might as well be a sensible result.
return tiers[tiers.length-1]; return tiers[tiers.length - 1];
} }
} }
@@ -10,50 +10,48 @@ import net.minecraft.item.ItemStack;
// into the damage increase for melee weapons, meaning I don't have to use events - always handy! // into the damage increase for melee weapons, meaning I don't have to use events - always handy!
public class EnchantmentMagicSword extends EnchantmentDamage implements Imbuement { public class EnchantmentMagicSword extends EnchantmentDamage implements Imbuement {
public EnchantmentMagicSword() { public EnchantmentMagicSword(){
super(Enchantment.Rarity.COMMON, 0, EntityEquipmentSlot.MAINHAND); super(Enchantment.Rarity.COMMON, 0, EntityEquipmentSlot.MAINHAND);
// Setting this to null stops the book appearing in the creative inventory // Setting this to null stops the book appearing in the creative inventory
this.type = null; this.type = null;
} }
@Override @Override
public boolean canApply(ItemStack p_92089_1_){ public boolean canApply(ItemStack p_92089_1_){
return false; return false;
} }
/** /**
* Returns the maximum level that the enchantment can have. * Returns the maximum level that the enchantment can have.
*/ */
// Here, enchantment level is the damage multiplier of the spell used to apply the enchantment, i.e. with an // Here, enchantment level is the damage multiplier of the spell used to apply the enchantment, i.e. with an
// non-sorcerer wand it is level 1, a basic sorcerer wand is level 2, and so on. Note that basic sorcerer wands can't // non-sorcerer wand it is level 1, a basic sorcerer wand is level 2, and so on. Note that basic sorcerer wands
// can't
// cast the imbue weapon spell, so level 2 is actually for apprentice wands. // cast the imbue weapon spell, so level 2 is actually for apprentice wands.
@Override @Override
public int getMaxLevel() public int getMaxLevel(){
{ return 4;
return 4; }
}
// Returns the number by which the damage should be increased (or something) // Returns the number by which the damage should be increased (or something)
@Override @Override
public float calcDamageByCreature(int p_152376_1_, EnumCreatureAttribute p_152376_2_) public float calcDamageByCreature(int p_152376_1_, EnumCreatureAttribute p_152376_2_){
{ return (float)p_152376_1_ * 1.25F;
return (float)p_152376_1_ * 1.25F; }
}
@Override
public String getName(){
return "enchantment." + this.getRegistryName();
}
@Override
public boolean isAllowedOnBooks(){
return false;
}
@Override
public boolean canApplyAtEnchantingTable(ItemStack stack){
return false;
}
@Override
public String getName()
{
return "enchantment." + this.getRegistryName();
}
@Override
public boolean isAllowedOnBooks(){
return false;
}
@Override
public boolean canApplyAtEnchantingTable(ItemStack stack) {
return false;
}
} }
@@ -6,43 +6,42 @@ import net.minecraft.item.ItemStack;
// This one is for everything other than imbued swords. // This one is for everything other than imbued swords.
public class EnchantmentTimed extends Enchantment implements Imbuement { public class EnchantmentTimed extends Enchantment implements Imbuement {
public EnchantmentTimed() { public EnchantmentTimed(){
// Setting enchantment type to null stops the book appearing in the creative inventory // Setting enchantment type to null stops the book appearing in the creative inventory
super(Enchantment.Rarity.COMMON, null, new EntityEquipmentSlot[]{EntityEquipmentSlot.MAINHAND}); super(Enchantment.Rarity.COMMON, null, new EntityEquipmentSlot[]{EntityEquipmentSlot.MAINHAND});
} }
@Override @Override
public boolean canApply(ItemStack p_92089_1_){ public boolean canApply(ItemStack p_92089_1_){
return false; return false;
} }
@Override
public String getName()
{
return "enchantment." + this.getRegistryName();
}
/** @Override
* Returns the maximum level that the enchantment can have. public String getName(){
*/ return "enchantment." + this.getRegistryName();
}
/**
* Returns the maximum level that the enchantment can have.
*/
// Here, enchantment level is the damage multiplier of the spell used to apply the enchantment, i.e. with an // Here, enchantment level is the damage multiplier of the spell used to apply the enchantment, i.e. with an
// non-sorcerer wand it is level 1, an apprentice sorcerer wand is level 2, and so on. Note that basic sorcerer wands can't // non-sorcerer wand it is level 1, an apprentice sorcerer wand is level 2, and so on. Note that basic sorcerer
// wands can't
// cast the imbue weapon spell, so level 2 is actually for apprentice wands. // cast the imbue weapon spell, so level 2 is actually for apprentice wands.
@Override @Override
public int getMaxLevel() public int getMaxLevel(){
{ return 4;
return 4; }
}
@Override
@Override public boolean isAllowedOnBooks(){
public boolean isAllowedOnBooks(){ return false;
return false; }
}
@Override
@Override public boolean canApplyAtEnchantingTable(ItemStack stack){
public boolean canApplyAtEnchantingTable(ItemStack stack) { return false;
return false; }
}
} }
@@ -22,12 +22,15 @@ import net.minecraftforge.event.entity.player.PlayerContainerEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
/** Interface for temporary enchantments that last for a certain duration ('imbuements'). This interface allows /**
* {@link EnchantmentMagicSword} and {@link EnchantmentTimed} to both be treated as instances of a * Interface for temporary enchantments that last for a certain duration ('imbuements'). This interface allows
* single type, rather than having to deal with each of them separately, * {@link EnchantmentMagicSword} and {@link EnchantmentTimed} to both be treated as instances of a single type, rather
* which would be inefficient and cumbersome (the former of those classes cannot extend the latter because they both * than having to deal with each of them separately, which would be inefficient and cumbersome (the former of those
* need to extend different subclasses of {@link net.minecraft.enchantment.Enchantment}). * classes cannot extend the latter because they both need to extend different subclasses of
* @since Wizardry 1.2 */ * {@link net.minecraft.enchantment.Enchantment}).
*
* @since Wizardry 1.2
*/
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
public interface Imbuement { public interface Imbuement {
@@ -37,20 +40,21 @@ public interface Imbuement {
public static void onLivingDropsEvent(LivingDropsEvent event){ public static void onLivingDropsEvent(LivingDropsEvent event){
// Instantly disenchants an imbued weapon if it is dropped when the player dies. // Instantly disenchants an imbued weapon if it is dropped when the player dies.
for(EntityItem item : event.getDrops()){ for(EntityItem item : event.getDrops()){
removeImbuements(item.getEntityItem()); removeImbuements(item.getItem());
} }
} }
@SubscribeEvent @SubscribeEvent
public static void onItemTossEvent(ItemTossEvent event){ public static void onItemTossEvent(ItemTossEvent event){
// Instantly disenchants an imbued weapon if it is thrown on the ground. // Instantly disenchants an imbued weapon if it is thrown on the ground.
removeImbuements(event.getEntityItem().getEntityItem()); removeImbuements(event.getEntityItem().getItem());
} }
/** Removes all imbuements from the given itemstack. */ /** Removes all imbuements from the given itemstack. */
static void removeImbuements(ItemStack stack){ static void removeImbuements(ItemStack stack){
if(stack.isItemEnchanted()){ if(stack.isItemEnchanted()){
// No need to check what enchantments the item has, since remove() does nothing if the element does not exist. // No need to check what enchantments the item has, since remove() does nothing if the element does not
// exist.
Map<Enchantment, Integer> enchantments = EnchantmentHelper.getEnchantments(stack); Map<Enchantment, Integer> enchantments = EnchantmentHelper.getEnchantments(stack);
// Removes the magic weapon enchantments from the enchantment map // Removes the magic weapon enchantments from the enchantment map
enchantments.entrySet().removeIf(entry -> entry.getKey() instanceof Imbuement); enchantments.entrySet().removeIf(entry -> entry.getKey() instanceof Imbuement);
@@ -58,7 +62,7 @@ public interface Imbuement {
EnchantmentHelper.setEnchantments(enchantments, stack); EnchantmentHelper.setEnchantments(enchantments, stack);
} }
} }
@SubscribeEvent @SubscribeEvent
public static void onPlayerOpenContainerEvent(PlayerContainerEvent event){ public static void onPlayerOpenContainerEvent(PlayerContainerEvent event){
// Brute-force fix to stop enchanted books in dungeon chests from having imbuements on them. // Brute-force fix to stop enchanted books in dungeon chests from having imbuements on them.
@@ -66,7 +70,7 @@ public interface Imbuement {
// Still not sure if it's better to set stacks in slots or modify the itemstack list directly, but I would // Still not sure if it's better to set stacks in slots or modify the itemstack list directly, but I would
// imagine it's the former. // imagine it's the former.
for(Slot slot : event.getContainer().inventorySlots){ for(Slot slot : event.getContainer().inventorySlots){
if(slot.getStack() != null && slot.getStack().getItem() instanceof ItemEnchantedBook){ if(slot.getStack().getItem() instanceof ItemEnchantedBook){
// We don't care about the level of the enchantments // We don't care about the level of the enchantments
Map<Enchantment, Integer> enchantments = EnchantmentHelper.getEnchantments(slot.getStack()); Map<Enchantment, Integer> enchantments = EnchantmentHelper.getEnchantments(slot.getStack());
// Removes all imbuements // Removes all imbuements
@@ -74,7 +78,7 @@ public interface Imbuement {
// If any imbuements were removed, replaces the enchantments on the book with the new ones, or // If any imbuements were removed, replaces the enchantments on the book with the new ones, or
// deletes the book entirely if there are none left. // deletes the book entirely if there are none left.
if(enchantments.isEmpty()){ if(enchantments.isEmpty()){
slot.putStack(null); // NOTE: Will need changing in 1.11 slot.putStack(ItemStack.EMPTY); // NOTE: Will need changing in 1.11
Wizardry.logger.info("Deleted enchanted book with illegal enchantments"); Wizardry.logger.info("Deleted enchanted book with illegal enchantments");
}else{ }else{
EnchantmentHelper.setEnchantments(enchantments, slot.getStack()); EnchantmentHelper.setEnchantments(enchantments, slot.getStack());
@@ -90,7 +94,7 @@ public interface Imbuement {
public static void onEntityJoinWorld(EntityJoinWorldEvent event){ public static void onEntityJoinWorld(EntityJoinWorldEvent event){
// Rather long-winded (but necessary) way of getting an arrow just after it has been fired, checking if the bow // Rather long-winded (but necessary) way of getting an arrow just after it has been fired, checking if the bow
// that fired it has the imbuement enchantment, and applying extra damage accordingly. // that fired it has the imbuement enchantment, and applying extra damage accordingly.
if(!event.getEntity().worldObj.isRemote && event.getEntity() instanceof EntityArrow){ if(!event.getEntity().world.isRemote && event.getEntity() instanceof EntityArrow){
EntityArrow arrow = (EntityArrow)event.getEntity(); EntityArrow arrow = (EntityArrow)event.getEntity();
@@ -100,9 +104,9 @@ public interface Imbuement {
ItemStack bow = archer.getHeldItemMainhand(); ItemStack bow = archer.getHeldItemMainhand();
if(bow == null || !(bow.getItem() instanceof ItemBow)){ if(!(bow.getItem() instanceof ItemBow)){
bow = archer.getHeldItemOffhand(); bow = archer.getHeldItemOffhand();
if(bow == null || !(bow.getItem() instanceof ItemBow)) return; if(!(bow.getItem() instanceof ItemBow)) return;
} }
// Taken directly from ItemBow, so it works exactly the same as the power enchantment. // Taken directly from ItemBow, so it works exactly the same as the power enchantment.
@@ -7,19 +7,19 @@ import net.minecraft.world.World;
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData; import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
public class EntityArc extends Entity implements IEntityAdditionalSpawnData { public class EntityArc extends Entity implements IEntityAdditionalSpawnData {
public int textureIndex = 0; public int textureIndex = 0;
public double x1, y1, z1, x2, y2, z2; public double x1, y1, z1, x2, y2, z2;
// The number of ticks the arc lasts for before disappearing // The number of ticks the arc lasts for before disappearing
public int lifetime = 3; public int lifetime = 3;
public double offsetX, offsetZ; public double offsetX, offsetZ;
public EntityArc(World par1World) { public EntityArc(World par1World){
super(par1World); super(par1World);
textureIndex = this.rand.nextInt(16); textureIndex = this.rand.nextInt(16);
this.ignoreFrustumCheck = true; this.ignoreFrustumCheck = true;
} }
public void setEndpointCoords(double x1, double y1, double z1, double x2, double y2, double z2){ public void setEndpointCoords(double x1, double y1, double z1, double x2, double y2, double z2){
this.x1 = x1; this.x1 = x1;
this.y1 = y1; this.y1 = y1;
@@ -27,7 +27,7 @@ public class EntityArc extends Entity implements IEntityAdditionalSpawnData {
this.x2 = x2; this.x2 = x2;
this.y2 = y2; this.y2 = y2;
this.z2 = z2; this.z2 = z2;
this.setPosition(x2, y2, z2); this.setPosition(x2, y2, z2);
} }
@Override @Override
@@ -36,38 +36,38 @@ public class EntityArc extends Entity implements IEntityAdditionalSpawnData {
this.setDead(); this.setDead();
} }
} }
protected void entityInit()
{
}
@Override protected void entityInit(){
protected void readEntityFromNBT(NBTTagCompound nbttagcompound) {
} }
@Override @Override
protected void writeEntityToNBT(NBTTagCompound nbttagcompound) { protected void readEntityFromNBT(NBTTagCompound nbttagcompound){
// Nothing needed here; arc is merely a graphic effect that only exists for a few ticks; as such there is no need to save it.
} }
@Override @Override
public boolean isInRangeToRenderDist(double distance) { protected void writeEntityToNBT(NBTTagCompound nbttagcompound){
// Nothing needed here; arc is merely a graphic effect that only exists for a few ticks; as such there is no
// need to save it.
}
@Override
public boolean isInRangeToRenderDist(double distance){
return true; return true;
} }
@Override @Override
public void writeSpawnData(ByteBuf data) { public void writeSpawnData(ByteBuf data){
data.writeDouble(this.x1); data.writeDouble(this.x1);
data.writeDouble(this.y1); data.writeDouble(this.y1);
data.writeDouble(this.z1); data.writeDouble(this.z1);
} }
@Override @Override
public void readSpawnData(ByteBuf data) { public void readSpawnData(ByteBuf data){
this.x1 = data.readDouble(); this.x1 = data.readDouble();
this.y1 = data.readDouble(); this.y1 = data.readDouble();
this.z1 = data.readDouble(); this.z1 = data.readDouble();
} }
} }

Some files were not shown because too many files have changed in this diff Show More