Compare commits

..

187 Commits

Author SHA1 Message Date
Electroblob77 f9f6b34549 Update version number 2019-01-05 18:28:06 +00:00
Electroblob77 bee7e51d06 Change key handler to static event handler and remove initialisation from main mod class, fixes #104 2019-01-05 16:42:21 +00:00
Electroblob77 51a2ff0976 Update version number 2019-01-04 22:12:37 +00:00
Electroblob77 1b298ff18b Update credits (all locations) 2019-01-04 22:12:06 +00:00
Electroblob77 86d13d3a6e Swap canSnowAt for canPlaceBlockAt, so it actually works... 2019-01-04 21:58:45 +00:00
Electroblob77 5421372754 Unike input events, tick events fire before the player is initialised, so add a check to stop it crashing with an NPE. 2019-01-04 21:53:39 +00:00
Electroblob77 53b29939f1 Change key handler to listen for ClientTickEvent instead of KeyInputEvent, swap isPressed() to isKeyDown() and restructure code; fixes 'lag'/inconsistent behaviour with mouse button keybinds. (See also #79, not sure if this fixes it since I can't reproduce the problem.) 2019-01-04 21:48:35 +00:00
Electroblob77 7bda8db86f Add check for wand before sending control packets, prevents unnecessary packets being sent 2019-01-04 21:04:06 +00:00
Electroblob77 a7a48cd32b Add a less than max timer check so that magic light does not keep growing indefinitely if the block fails to disappear. Helps reduce the effects of #101 but does not fix it. 2019-01-04 20:53:01 +00:00
Electroblob77 b8e0836a6d Add test for fake players in retaliatory ice shroud effect, fixes #93 2019-01-04 20:48:03 +00:00
Electroblob77 a7e6b2892c Add check to prevent ArrayIndexOutOfBoundsException in WandHelper, fixes #90 (and duplicate issues #80, #91, #97 and #98) 2019-01-04 20:07:02 +00:00
Electroblob77 f886ebfd75 Prevent ice age from placing snow layers at invalid locations, fixes #64 2019-01-04 20:05:09 +00:00
Electroblob77 98b334e6d7 Add condition to only write magic projectile thrower to spawn data if the thrower exists and tweak overrides so it is always written/read last, fixes #71 2019-01-04 20:04:43 +00:00
Electroblob77 83edb8007e Replace direct translation in /allies command with text component, fixes #70 2019-01-04 20:02:57 +00:00
Electroblob77 67dda448f3 Add background tint to arcane workbench GUI, fixes #96 2019-01-04 19:58:31 +00:00
Electroblob77 09953c0299 Add bottom of world check to wizard tower foundation worldgen, fixes #73 2019-01-04 19:57:33 +00:00
Electroblob77 38b0fa65bc Comment out scroll translation console message, fixes #56 2019-01-04 19:56:39 +00:00
Electroblob 7200182c82 Merge pull request #102 from dragon-evol/1.12.2
[zh_cn_handbook update]minor, minor, minor fixes (sorry for disturbing...)
2019-01-03 23:08:10 +00:00
dragon-evol e73e998de2 minor fixes 2019-01-03 13:19:53 +08:00
Electroblob a69da2eb2a Merge pull request #94 from dragon-evol/1.12.2
Update zh_cn.lang and translate the handbook
2018-12-18 00:23:36 +00:00
dragon-evol a00c594d83 Add files via upload 2018-12-17 14:23:23 +08:00
dragon-evol 3df99552e1 Merge pull request #1 from dragon-evol/dragon-evol-patch-1
Update zh_cn.lang
2018-12-17 14:22:20 +08:00
dragon-evol e2bc2824f6 Add files via upload 2018-12-17 14:11:18 +08:00
Electroblob 36f4728f3a Merge pull request #88 from Avatair/feature/mapping-update
Updated MCP Mapping to stable39
2018-11-24 18:20:08 +00:00
alesto 6ca72e7965 Undid adding wizardry dependency. 2018-11-24 09:56:35 +01:00
alesto 151dcc06da Updated mappings 2018-11-22 16:02:40 +01:00
Electroblob 5737109dec Merge pull request #82 from HellFirePvP/1.12.2
Switch enchantment-writing related code to a more direct data-driven approach
2018-11-10 00:48:16 +00:00
HellFirePvP 4bd3a46f32 Switch enchantment-writing related code to a more direct data-driven approach 2018-11-01 13:19:46 +01:00
Electroblob 73e2d64fcd Update guide_for_contributing.md 2018-08-17 23:06:46 +01:00
Electroblob 1f008b405d Update ISSUE_TEMPLATE.md 2018-08-01 23:13:43 +01:00
Electroblob 00e1e2602f Update guide_for_contributing.md 2018-08-01 23:11:27 +01:00
Electroblob 98445da971 Update ISSUE_TEMPLATE.md 2018-08-01 22:59:42 +01:00
Electroblob dbc1490e10 Merge pull request #53 from ZHENGLOC/1.12.2
Update zh_cn.lang
2018-06-17 11:21:23 +01:00
ZLOCK_1911 f33a0aceb2 Update zh_cn.lang 2018-06-09 12:02:45 +08:00
Electroblob 7141ae9544 Update CREDITS.md 2018-06-07 17:34:36 +01:00
Electroblob af638ab2f7 Merge pull request #51 from ZHENGLOC/1.12.2
Create zh_cn.lang
2018-06-07 17:32:32 +01:00
ZLOCK_1911 a75a6c6114 Create zh_cn.lang 2018-06-07 18:31:37 +08:00
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
1045 changed files with 38536 additions and 38258 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
run
misc
libs
Thumbs.db
+10 -2
View File
@@ -1,8 +1,8 @@
# Credits
Electroblob's Wizardry
Version 2.1.0
For Minecraft 1.10.2
Version 4.1.4
For Minecraft 1.12.2
Designed, coded and textured by Electroblob
@@ -12,9 +12,17 @@ Thanks also to the Minecraft modding community, which always has an answer to my
In addition, I'd like to thank the following individuals for their contributions to the mod:
#### Code
- Corail31
- 12foo
- Shadows-of-Fire
- HellFirePvP
#### Translations
- Russian: VilagVil
- Spanish and Mexican Spanish: MadWrist
- Chinese: ZHENGLOC and dragon-evol
Lightning ray sound effect from OhhWowProductions
+4 -2
View File
@@ -1,5 +1,7 @@
Minecraft version: 1.10.2 [change as necessary]
Wizardry version: 2.1.0 [change as necessary]
Please read the [guide for contributing](https://github.com/Electroblob77/Wizardry/blob/1.12.2/guide_for_contributing.md) before posting.
Minecraft version: 1.12.2 [change as necessary]
Wizardry version: 4.1.4 [change as necessary]
Environment: Singleplayer/LAN game/Server [delete as necessary]
Issue details: [describe what you were doing when the issue occurred, what went wrong, what you expected to happen, etc.]
+2 -2
View File
@@ -1,7 +1,7 @@
# License
This repository is copyright © Electroblob 2018. The following license is provided to allow you to creatively contribute to and improve the repository.
This license applies only to the source code and assets present in this repository. The compiled mod (available at https://minecraft.curseforge.com/projects/electroblobs-wizardry) comes under its own separate license, see the aforementioned webpage for details.
This license applies only to the source code, assets and wiki pages present in this repository. The compiled mod (available at https://minecraft.curseforge.com/projects/electroblobs-wizardry) comes under its own separate license, see the aforementioned webpage for details.
TL;DR: Do what you want with this repo on Github, but ask me first if you want to put it anywhere else or publish your version. Don't try and make money off the repo or anything in it. I'm not responsible if the code breaks things, and if you help me out by submitting a PR, I can use and modify the contents of that PR as long as I give you credit. (This brief summary is non-binding and does not override or replace the full license below.)
@@ -17,7 +17,7 @@ TL;DR: Do what you want with this repo on Github, but ask me first if you want t
'Electroblob's Wizardry', 'Wizardry', 'the mod' - The Minecraft modification Electroblob's Wizardry
'Repository' - This repository on Github, containing this license, other informational files, configurations, code and assets which are part of Electroblob's Wizardry
'Repository' - This repository on Github, containing this license, the wiki, other informational files, configurations, code and assets which are part of Electroblob's Wizardry
'Curseforge' - The webpage https://minecraft.curseforge.com/projects/electroblobs-wizardry
+46 -43
View File
@@ -1,57 +1,60 @@
buildscript {
repositories {
mavenCentral()
maven {
name = "forge"
url = "https://maven.minecraftforge.net/"
}
maven {
name = "sonatype"
url = "https://oss.sonatype.org/content/repositories/snapshots/"
}
jcenter()
maven { url = "http://files.minecraftforge.net/maven" }
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT'
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
}
}
apply plugin: 'net.minecraftforge.gradle.forge'
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'java'
apply plugin: 'idea'
apply plugin: 'forge'
version = " 1.1.5 - MC 1.7.10"
group = "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
version = " 4.1.4 - MC 1.12.2"
group= "electroblob.wizardry"// http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "Electroblob's Wizardry "
sourceCompatibility = targetCompatibility = "1.8" // Need this here so eclipse task generates correctly.
compileJava {
sourceCompatibility = targetCompatibility = "1.8"
}
minecraft {
version = "1.7.10-10.13.4.1614-1.7.10"
runDir = "eclipse"
}
task deobfJar(type: Jar) { // Generate deobfuscated
from sourceSets.main.output
classifier = 'deobf'
}
task sourceJar(type: Jar) { // Generate sources
from sourceSets.main.allSource
classifier = 'sources'
}
tasks.build.dependsOn('sourceJar', 'deobfJar')
artifacts {
archives deobfJar
archives sourceJar
archives jar
}
repositories {
maven {
name 'ChickenBones maven'
url 'https://chickenbones.net/maven/'
}
version = "1.12.2-14.23.2.2611"
runDir = "run"
// the mappings can be changed at any time, and must be in the following format.
// snapshot_YYYYMMDD snapshot are built nightly.
// stable_# stables are built at the discretion of the MCP team.
// Use non-default mappings at your own risk. they may not always work.
// simply re-run your setup task after changing the mappings to update your workspace.
mappings = "stable_39"
// makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable.
}
dependencies {
compileOnly 'codechicken:NotEnoughItems:1.7.10-1.0.5.120:dev'
// you may put jars on which you depend on in ./libs
// or you may define them like so..
//compile "some.group:artifact:version:classifier"
//compile "some.group:artifact:version"
// real examples
//compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env
//compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env
// the 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime.
//provided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// the deobf configurations: 'deobfCompile' and 'deobfProvided' are the same as the normal compile and provided,
// except that these dependencies get remapped to your current MCP mappings
//deobfCompile 'com.mod-buildcraft:buildcraft:6.0.8:dev'
//deobfProvided 'com.mod-buildcraft:buildcraft:6.0.8:dev'
// for more info...
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
// http://www.gradle.org/docs/current/userguide/dependency_management.html
}
processResources {
@@ -62,12 +65,12 @@ processResources {
// replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
// replace version and mcversion
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) {
exclude 'mcmod.info'
}
+3
View File
@@ -0,0 +1,3 @@
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
# This is required to provide enough memory for the Minecraft decompilation process.
org.gradle.jvmargs=-Xmx3G
Binary file not shown.
+2 -1
View File
@@ -1,5 +1,6 @@
#Mon Sep 14 12:28:28 PDT 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip
Vendored
+51 -59
View File
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
#!/usr/bin/env bash
##############################################################################
##
@@ -6,6 +6,47 @@
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -20,49 +61,9 @@ while [ -h "$PRG" ] ; do
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -89,7 +90,7 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
@@ -113,7 +114,6 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
@@ -154,19 +154,11 @@ if $cygwin ; then
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
APP_ARGS=$(save "$@")
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
Vendored
+10 -4
View File
@@ -8,14 +8,14 @@
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@@ -46,9 +46,10 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
@@ -59,6 +60,11 @@ set _SKIP=2
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
+14 -1
View File
@@ -2,7 +2,20 @@
## Submitting an issue
When submitting an issue, please stick to the issue template. Please give me as much information about the issue as you can, but keep it relevant. "This is really annoying me and my friend" does not help me fix the problem! Most importantly, use gist or pastebin to post crash reports.
When submitting an issue, I would be grateful if you could follow these few guidelines:
- First and foremost, please check your issue hasn't already been posted. The issue tracker is searchable, so try typing in a few keywords and see if anything comes up.
- Please stick to the issue template, it's there to help you provide the right information so I can fix the problem more easily. If you're not sure what to put for anything, that's ok, just leave it as it is.
- Please give me as much information about the issue as you can, but keep it relevant. "This is really annoying me and my friend" does not help me fix the problem!
- There's no need to put 'tags' in square brackets in the issue title, I'll put proper github issue tags on it which will also help organise it. You can use them to search for issues too!
- Don't close an issue unless it has actually been fixed or is no longer relevant - otherwise I might not end up fixing it at all! Usually I'll take care of closing issues anyway, so you don't have to worry about it.
- Most importantly, use gist or pastebin to post crash reports. Do not paste the entire crash report inline, not even in a code block!
> If you've got a git account (which you do, if you're posting an issue) you can access gist, and pastebin doesn't require an account at all, so there's no excuse!
## Submitting a PR
Binary file not shown.
Binary file not shown.
@@ -1,203 +1,213 @@
package electroblob.wizardry;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
import cpw.mods.fml.common.FMLCommonHandler;
import electroblob.wizardry.item.ItemSpectralBow;
import electroblob.wizardry.packet.PacketCastContinuousSpell;
import electroblob.wizardry.packet.PacketCastSpell;
import electroblob.wizardry.packet.PacketClairvoyance;
import electroblob.wizardry.packet.PacketGlyphData;
import electroblob.wizardry.packet.PacketNPCCastSpell.Message;
import electroblob.wizardry.packet.PacketPlayerSync;
import electroblob.wizardry.packet.PacketTransportation;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.spell.Spell;
import net.minecraft.block.Block;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.model.ModelBiped;
import electroblob.wizardry.util.WizardryParticleType;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.StatCollector;
import net.minecraft.util.Vec3;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.translation.I18n;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
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
* differently on the client and the server. A lot of the methods here appear to do absolutely nothing; this is
* because they do client-only things which are only handled in the client proxy.
* @see {@link electroblob.wizardry.client.ClientProxy} */
/**
* 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 because
* they do client-only things which are only handled in the client proxy.
*
* @see {@link electroblob.wizardry.client.ClientProxy}
* @author Electroblob
* @since Wizardry 1.0
*/
@SuppressWarnings("deprecation")
public class CommonProxy {
/** Used to store IExtendedEntityProperties data temporarily between player death and respawn */
private static final Map<String, NBTTagCompound> extendedEntityData = new HashMap<String, NBTTagCompound>();
public void registerRenderers(){}
public void registerKeyBindings(){}
// SECTION Registry
// ===============================================================================================================
public void registerRenderers(){
}
public void initialiseLayers(){
}
public void registerKeyBindings(){
}
public void registerSpellHUD(){}
public ModelBiped getWizardArmourModel(){
public net.minecraft.client.model.ModelBiped getWizardArmourModel(){
return null;
}
/**
* Adds an entity's custom data to the map for temporary storage
* @param compound An NBT Tag Compound that stores the IExtendedEntityProperties data only
*/
public static void storeEntityData(String name, NBTTagCompound compound){
extendedEntityData.put(name, compound);
}
/**
* Removes the compound from the map and returns the NBT tag stored for name or null if none exists
*/
public static NBTTagCompound getEntityData(String name){
return extendedEntityData.remove(name);
}
public double getPlayerEyesPos(EntityPlayer player){
return player.posY + player.eyeHeight;
}
/** Gets the absolute coordinates of the tip of the wand belonging to the given entity. If this is a client in
* first person view, the coordinates will instead be the entity's position + 1.2. */
public Vec3 getWandTipPosition(EntityLivingBase entity){
// 0.7 forwards, 0.4 to the right, and 1.35 upwards.
double x = entity.posX - 0.7*Math.sin(Math.toRadians(entity.renderYawOffset)) - 0.4*Math.cos(Math.toRadians(entity.renderYawOffset));
double y = entity.boundingBox.minY + 1.35;
double z = entity.posZ + 0.7*Math.cos(Math.toRadians(entity.renderYawOffset)) - 0.4*Math.sin(Math.toRadians(entity.renderYawOffset));
return Vec3.createVectorHelper(x, y, z);
}
/**
* Spawns a custom particle of the specified type.
*
* @param type EnumParticleType of the particle
* @param world Reference to the World object
* @param x Particle x position
* @param y Particle y position
* @param z Particle z position
* @param velX Particle x velocity
* @param velY Particle y velocity
* @param velZ Particle z velocity
* @param maxAge Lifetime of the particle in ticks
* @param r Red component of particle colour
* @param g Red component of particle colour
* @param b Red component of particle colour
* @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
*/
public void spawnParticle(EnumParticleType 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){
// 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.
*
* @param type EnumParticleType of the particle
* @param world Reference to the World object
* @param x Particle x position
* @param y Particle y position
* @param z Particle z position
* @param velX Particle x velocity
* @param velY Particle y velocity
* @param velZ Particle z velocity
* @param maxAge Lifetime of the particle in ticks
* @param r Red component of particle colour (unless this is a MAGIC_FIRE particle, in which case this is the scale)
* @param g Red component of particle colour
* @param b Red component of particle colour
*/
public void spawnParticle(EnumParticleType type, World world, double x, double y, double z, double velX, double velY, double velZ, int maxAge, float r, float g, float b){
this.spawnParticle(type, world, x, y, z, velX, velY, velZ, maxAge, r, g, b, false, 0);
}
/** Spawns a custom particle of the specified type. Colour defaults to white, 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 x Particle x position
* @param y Particle y position
* @param z Particle z position
* @param velX Particle x velocity
* @param velY Particle y velocity
* @param velZ Particle z velocity
* @param maxAge Lifetime of the particle in ticks
*/
public void spawnParticle(EnumParticleType 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 spawnDigParticle(World world, double x, double y, double z, double velX, double velY, double velZ, Block block){}
public void initGuiBits(){}
public void spawnTornadoParticle(World world, double x, double y, double z, double velX, double velZ, double radius, int maxAge, Block block, int metadata){}
/** Plays a sound which moves with the given entity.
*
* @param entity The source of the sound
* @param soundName String resource path of the sound
* @param volume Volume relative to 1
* @param pitch Pitch relative to 1
* @param repeat Whether to repeat the sound for as long as the entity is alive (or until stopped manually)
*/
public void playMovingSound(Entity entity, String soundName, float volume, float pitch, boolean repeat){}
public void handleCastSpellPacket(PacketCastSpell.Message message){}
public double getWandDisplayDamage(ItemStack stack){
return 1.0d;
}
public int getConjuredItemDisplayDamage(ItemStack stack){
return 0;
// SECTION Particles
// ===============================================================================================================
/**
* Spawns a custom particle of the specified type.
*
* @param type EnumParticleType of the particle
* @param world Reference to the World object
* @param x Particle x position
* @param y Particle y position
* @param z Particle z position
* @param velX Particle x velocity
* @param velY Particle y velocity
* @param velZ Particle z velocity
* @param maxAge Lifetime of the particle in ticks
* @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 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 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){
// Does nothing since particles are client-side only
}
public void registerEventHandlers(){
MinecraftForge.EVENT_BUS.register(new WizardryEventHandler());
/**
* 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 x Particle x position
* @param y Particle y position
* @param z Particle z position
* @param velX Particle x velocity
* @param velY Particle y velocity
* @param velZ Particle z velocity
* @param maxAge Lifetime of the particle in ticks
* @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 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
*/
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){
this.spawnParticle(type, world, x, y, z, velX, velY, velZ, maxAge, r, g, b, false, 0);
}
public void handleTransportationPacket(PacketTransportation.Message message){}
/**
* Spawns a custom particle of the specified type. Colour defaults to white, 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 x Particle x position
* @param y Particle y position
* @param z Particle z position
* @param velX Particle x velocity
* @param velY Particle y velocity
* @param velZ Particle z velocity
* @param maxAge Lifetime of the particle in ticks
*/
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 FontRenderer getFontRenderer(ItemStack stack) {
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
// ===============================================================================================================
public net.minecraft.client.gui.FontRenderer getFontRenderer(ItemStack stack){
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
* 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){
// 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.
// Commented because it's just really annoying.
//Wizardry.logger.info("A mod has called ItemScroll#getItemStackDisplayName from the server side. Using the"
// + "deprecated server-side translation methods as a fallback.");
// Displays [Empty slot] if spell is continuous.
Spell spell = Spell.get(scroll.getItemDamage());
if(spell.isContinuous) spell = WizardryRegistry.none;
return StatCollector.translateToLocalFormatted("item.scroll.name", StatCollector.translateToLocal("spell." + spell.getUnlocalisedName())).trim();
if(spell.isContinuous) spell = Spells.none;
return I18n.translateToLocalFormatted("item." + Wizardry.MODID + ":scroll.name",
I18n.translateToLocal("spell." + spell.getUnlocalisedName())).trim();
}
public void handlePlayerSyncPacket(PacketPlayerSync.Message message){}
public double getConjuredBowDurability(ItemStack stack){
return ((ItemSpectralBow)WizardryItems.spectral_bow).getDefaultDurabilityForDisplay(stack);
}
public void handleGlyphDataPacket(PacketGlyphData.Message message){}
// SECTION Packet Handlers
// ===============================================================================================================
public void handleCastContinuousSpellPacket(PacketCastContinuousSpell.Message message){}
public void handlePlayerSyncPacket(PacketPlayerSync.Message message){
}
public void setToNumberSliderEntry(Property property){}
public void handleGlyphDataPacket(PacketGlyphData.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
// ===============================================================================================================
public void setToNumberSliderEntry(Property property){
}
// public void setToEntityNameEntry(Property property){}
/**
* Plays a sound which moves with the given entity.
*
* @param entity The source of the sound
* @param sound The SoundEvent to play
* @param volume Volume relative to 1
* @param pitch Pitch relative to 1
* @param repeat Whether to repeat the sound for as long as the entity is alive (or until stopped manually)
*/
public void playMovingSound(Entity entity, SoundEvent sound, float volume, float pitch, boolean repeat){
}
/**
* 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;
}
}
@@ -1,39 +0,0 @@
package electroblob.wizardry;
import net.minecraft.util.StatCollector;
public enum EnumElement {
MAGIC("\u00A77", "simple"),
FIRE("\u00A74", "fire"),
ICE("\u00A7b", "ice"),
LIGHTNING("\u00A73", "lightning"),
NECROMANCY("\u00A75", "necromancy"),
EARTH("\u00A72", "earth"),
SORCERY("\u00A7a", "sorcery"),
HEALING("\u00A7e", "healing");
/** Display colour for this element */
public final String colour;
/** Unlocalised name for this element */
public final String unlocalisedName;
private EnumElement(String colour, String name){
this.colour = colour;
this.unlocalisedName = name;
}
public EnumElement get(int id){
return this.values()[id];
}
/** Returns the translated display name of this element, without formatting. */
public String getDisplayName() {
return StatCollector.translateToLocal("element." + unlocalisedName);
}
/** Returns the translated display name for wizards of this element, shown in the trading GUI */
public String getWizardName() {
return StatCollector.translateToLocal("element." + unlocalisedName + ".wizard");
}
}
@@ -1,16 +0,0 @@
package electroblob.wizardry;
public enum EnumParticleType {
BLIZZARD,
BRIGHT_DUST,
DARK_MAGIC,
DUST,
ICE,
LEAF,
MAGIC_BUBBLE,
MAGIC_FIRE,
PATH,
SNOW,
SPARK,
SPARKLE
}
@@ -1,21 +0,0 @@
package electroblob.wizardry;
import net.minecraft.util.StatCollector;
public enum EnumSpellType {
ATTACK("attack"),
DEFENCE("defence"),
UTILITY("utility"),
MINION("minion");
private final String unlocalisedName;
EnumSpellType(String name){
this.unlocalisedName = name;
}
public String getDisplayName() {
return StatCollector.translateToLocal("spelltype." + unlocalisedName);
}
}
@@ -1,38 +0,0 @@
package electroblob.wizardry;
import net.minecraft.util.StatCollector;
public enum EnumTier {
BASIC(700, 3, "\u00A7f", "basic"),
APPRENTICE(1000, 4, "\u00A7b", "apprentice"),
ADVANCED(1500, 5, "\u00A71", "advanced"),
MASTER(2500, 6, "\u00A75", "master");
/** Maximum mana a wand of this tier can store. */
public final int maxCharge;
/** Just an ordinal. Shouldn't really be needed but no point changing it now. */
public final int level;
/** The maximum number of upgrades that can be applied to a wand of this tier. */
public final int upgradeLimit;
/** The colour of text associated with this tier */
public final String colour;
private final String unlocalisedName;
private EnumTier(int maxCharge, int upgradeLimit, String colour, String name){
this.maxCharge = maxCharge;
this.level = ordinal();
this.upgradeLimit = upgradeLimit;
this.colour = colour;
this.unlocalisedName = name;
}
public String getDisplayName() {
return StatCollector.translateToLocal("tier." + unlocalisedName);
}
public String getDisplayNameWithFormatting() {
return this.colour + StatCollector.translateToLocal("tier." + unlocalisedName);
}
}
@@ -1,485 +0,0 @@
package electroblob.wizardry;
import java.lang.ref.WeakReference;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
import java.util.UUID;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import electroblob.wizardry.MagicDamage.DamageType;
import electroblob.wizardry.entity.EntityShield;
import electroblob.wizardry.entity.living.EntitySummonedCreature;
import electroblob.wizardry.packet.PacketCastContinuousSpell;
import electroblob.wizardry.packet.PacketPlayerSync;
import electroblob.wizardry.packet.PacketTransportation;
import electroblob.wizardry.packet.WizardryPacketHandler;
import electroblob.wizardry.spell.None;
import electroblob.wizardry.spell.Spell;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.world.World;
import net.minecraftforge.common.IExtendedEntityProperties;
import net.minecraftforge.common.util.Constants.NBT;
/** IExtendedEntityProperties for players. Everything player-data-related that is needed by wizardry is handled here,
* including the ADS, soulbinding, conjured items, summoned wolves and horses, transportation and clairvoyance. */
public class ExtendedPlayer implements IExtendedEntityProperties {
public final static String name = "WizardryExtendedPlayer";
private final EntityPlayer player;
public int damageToApply;
// These were originally done using the item damage directly, but this caused the annoying re-equip animation
// to keep happening so they were moved to here instead.
public int conjuredSwordDuration;
public int conjuredPickaxeDuration;
public int conjuredBowDuration;
public int conjuredArmourDuration;
public int flamingAxeDuration;
public int frostAxeDuration;
public int magicWeaponDuration;
public int flamingWeaponDuration;
public int freezingWeaponDuration;
public boolean hasSpiritWolf;
public boolean hasSpiritHorse;
/** Whether this player is currently casting a continuous spell via commands. Not saved over world reload
* and reset on player death. */
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. */
private int castingTick;
/** The damage multiplier for the current continuous spell cast via commands. Not saved over world reload and
* reset on player death. */
private float spellDamageMultiplier;
/** The range multiplier for the current continuous spell cast via commands. Not saved over world reload and
* reset on player death. */
private float spellRangeMultiplier;
/** The duration multiplier for the current continuous spell cast via commands. Not saved over world reload and
* reset on player death. */
private float spellDurationMultiplier;
/** The blast multiplier for the current continuous spell cast via commands. Not saved over world reload and
* reset on player death. */
private float spellBlastMultiplier;
/** Coordinate for the saved transportation stone location. Will be -1 if no location is saved. */
public int transportX, transportY, transportZ;
/** Dimension id which the saved stone circle is in. */
public int transportDimension;
/** Time left until the player teleports under the effect of transportation */
public int tpTimer;
/** Coordinate for the saved clairvoyance location. Will be -1 if no location is saved. */
public int clairvoyanceX, clairvoyanceY, clairvoyanceZ;
/** Dimension id which the saved clairvoyance point is in. */
public int clairvoyanceDimension;
public EntityShield shield;
public WeakReference<EntitySummonedCreature> selectedMinion;
public HashSet<Spell> spellsDiscovered;
private HashSet<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.
* <b> Do not use this for any other purpose than displaying the names! */
public HashSet<String> allyNames;
private HashSet<UUID> soulboundCreatures;
public ExtendedPlayer(EntityPlayer player){
this.player = player;
this.damageToApply = 0;
this.conjuredSwordDuration = 0;
this.conjuredPickaxeDuration = 0;
this.conjuredBowDuration = 0;
this.conjuredArmourDuration = 0;
this.flamingAxeDuration = 0;
this.frostAxeDuration = 0;
this.magicWeaponDuration = 0;
this.flamingWeaponDuration = 0;
this.freezingWeaponDuration = 0;
this.spellsDiscovered = new HashSet<Spell>();
// All players can recognise magic missile. This is not done using discoverSpell because that seems to cause
// a crash on load occasionally (probably something to do with achievements being initalised)
this.spellsDiscovered.add(WizardryRegistry.magicMissile);
this.hasSpiritWolf = false;
this.hasSpiritHorse = false;
this.currentlyCasting = WizardryRegistry.none;
this.spellDamageMultiplier = 1;
this.spellRangeMultiplier = 1;
this.spellDurationMultiplier = 1;
this.spellBlastMultiplier = 1;
this.castingTick = 0;
this.transportX = -1;
this.transportY = -1;
this.transportZ = -1;
this.transportDimension = 0;
this.clairvoyanceX = -1;
this.clairvoyanceY = -1;
this.clairvoyanceZ = -1;
this.clairvoyanceDimension = 0;
this.tpTimer = 0;
this.allies = new HashSet<UUID>();
this.allyNames = new HashSet<String>();
this.soulboundCreatures = new HashSet<UUID>();
}
public boolean hasSpellBeenDiscovered(Spell spell){
return spellsDiscovered.contains(spell) || spell instanceof None;
}
/**
* Adds the spell to the list of discovered spells for this player. Automatically takes into account
* whether the spell has been discovered. Use this method rather than adding directly to the list
* because it handles the mage of all trades achievement.
* @param spell
*/
public void discoverSpell(Spell spell){
if(spellsDiscovered == null){
spellsDiscovered = new HashSet<Spell>();
}
if(!(spell instanceof None)){
spellsDiscovered.add(spell);
}
if(spellsDiscovered.containsAll(Spell.getSpells(Spell.enabledSpells))){
this.player.triggerAchievement(Wizardry.allSpells);
}
for(EnumElement element : EnumElement.values()){
if(element != EnumElement.MAGIC && spellsDiscovered.containsAll(Spell.getSpells(new Spell.TierElementFilter(null, element)))){
this.player.triggerAchievement(Wizardry.elementMaster);
}
}
}
/** Sets the player's saved transportation stone location. */
public void setStoneLocation(int x, int y, int z, int dimensionID){
this.transportX = x;
this.transportY = y;
this.transportZ = z;
this.transportDimension = dimensionID;
}
/** Sets the player's saved clairvoyance location. */
public void setClairvoyancePoint(int x, int y, int z, int dimensionID){
this.clairvoyanceX = x;
this.clairvoyanceY = y;
this.clairvoyanceZ = z;
this.clairvoyanceDimension = dimensionID;
}
/** 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){
if(this.isPlayerAlly(player)){
this.allies.remove(player.getUniqueID());
// The remove method uses .equals() rather than == so this will work fine.
this.allyNames.remove(player.getCommandSenderName());
return false;
}else{
this.allies.add(player.getUniqueID());
this.allyNames.add(player.getCommandSenderName());
return true;
}
}
/** Returns whether the given player is in this player's list of allies, or is on the same team as this player. */
public boolean isPlayerAlly(EntityPlayer player){
return this.allies.contains(player.getUniqueID()) || this.player.isOnSameTeam(player);
}
/** Adds the given entity to this player's list of soulbound creatures, and returns whether it succeeded. */
public boolean soulbind(EntityLivingBase target){
return this.soulboundCreatures.add(target.getUniqueID());
}
/** Returns whether the given entity has been soulbound to this player. */
public boolean isCreatureSoulbound(EntityPlayer target){
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. */
public void damageAllSoulboundCreatures(float damage){
for(Iterator<UUID> iterator = this.soulboundCreatures.iterator(); iterator.hasNext();){
Entity entity = WizardryUtilities.getEntityByUUID(this.player.worldObj, iterator.next());
if(entity == null) iterator.remove();
if(entity instanceof EntityLivingBase){
if(entity.attackEntityFrom(MagicDamage.causeDirectMagicDamage(this.player, DamageType.MAGIC), damage)){
// Sound only plays if the damage succeeds
player.worldObj.playSoundAtEntity(entity, "mob.wither.hurt", 1.0F, player.worldObj.rand.nextFloat() * 0.2F + 1.0F);
}
}
}
}
/** Starts casting the given spell with the given modifiers. */
public void startCastingContinuousSpell(Spell spell, float damageMultiplier, float rangeMultiplier, float durationMultiplier, float blastMultiplier){
this.currentlyCasting = spell;
this.spellDamageMultiplier = damageMultiplier;
this.spellRangeMultiplier = rangeMultiplier;
this.spellDurationMultiplier = durationMultiplier;
this.spellBlastMultiplier = blastMultiplier;
if(!this.player.worldObj.isRemote){
PacketCastContinuousSpell.Message message = new PacketCastContinuousSpell.Message(this.player.getEntityId(), spell.id(), damageMultiplier, rangeMultiplier, blastMultiplier);
WizardryPacketHandler.net.sendToDimension(message, this.player.worldObj.provider.dimensionId);
}
}
/** Stops casting the current spell. */
public void stopCastingContinuousSpell(){
this.currentlyCasting = WizardryRegistry.none;
this.castingTick = 0;
this.spellDamageMultiplier = 1;
this.spellRangeMultiplier = 1;
this.spellDurationMultiplier = 1;
this.spellBlastMultiplier = 1;
if(!this.player.worldObj.isRemote){
PacketCastContinuousSpell.Message message = new PacketCastContinuousSpell.Message(this.player.getEntityId(), WizardryRegistry.none.id(), 1, 1, 1);
WizardryPacketHandler.net.sendToDimension(message, this.player.worldObj.provider.dimensionId);
}
}
/** Returns whether this player is currently casting a continuous spell via commands. */
public boolean isCasting(){
return this.currentlyCasting != null && this.currentlyCasting != WizardryRegistry.none;
}
/** Returns the continuous spell this player is currently casting via commands, or the 'none' spell if they aren't
* casting anything. */
public Spell currentlyCasting(){
return currentlyCasting;
}
/** Called from the event handler each time the associated player is updated. */
public void update(EntityPlayer entityplayer){
if(this.selectedMinion != null && this.selectedMinion.get() == null) this.selectedMinion = null;
Random random = entityplayer.worldObj.rand;
// Annoyingly, it seems that the armour inventory is dealt with completely separately.
if(entityplayer.inventory.hasItem(Wizardry.spectralHelmet)
|| entityplayer.inventory.hasItem(Wizardry.spectralChestplate)
|| entityplayer.inventory.hasItem(Wizardry.spectralLeggings)
|| entityplayer.inventory.hasItem(Wizardry.spectralBoots)
|| (entityplayer.inventory.armorInventory[3] != null && entityplayer.inventory.armorInventory[3].getItem() == Wizardry.spectralHelmet)
|| (entityplayer.inventory.armorInventory[2] != null && entityplayer.inventory.armorInventory[2].getItem() == Wizardry.spectralChestplate)
|| (entityplayer.inventory.armorInventory[1] != null && entityplayer.inventory.armorInventory[1].getItem() == Wizardry.spectralLeggings)
|| (entityplayer.inventory.armorInventory[0] != null && entityplayer.inventory.armorInventory[0].getItem() == Wizardry.spectralBoots)){
this.conjuredArmourDuration++;
}else{
this.conjuredArmourDuration = 0;
}
if(!entityplayer.worldObj.isRemote){
if(tpTimer == 1){
entityplayer.setPositionAndUpdate(this.transportX + 0.5, this.transportY, this.transportZ + 0.5);
entityplayer.worldObj.playSoundAtEntity(entityplayer, "portal.travel", 1.0f, 1.0f);
entityplayer.addPotionEffect(new PotionEffect(Potion.blindness.id, 50, 0));
IMessage msg = new PacketTransportation.Message(entityplayer.getEntityId());
WizardryPacketHandler.net.sendToDimension(msg, entityplayer.worldObj.provider.dimensionId);
}
if(tpTimer > 0){
tpTimer--;
}
}
if(this.currentlyCasting != null && this.currentlyCasting.isContinuous){
this.currentlyCasting.cast(player.worldObj, player, castingTick++, spellDamageMultiplier, spellRangeMultiplier, spellDurationMultiplier, spellBlastMultiplier);
}else{
this.castingTick = 0;
}
}
/** Called from the event handler each time the associated player dies. Used to reset any variables that shouldn't
* persist over player death. */
public void onPlayerDeath(){
this.conjuredSwordDuration = 0;
this.conjuredPickaxeDuration = 0;
this.conjuredBowDuration = 0;
this.conjuredArmourDuration = 0;
this.flamingAxeDuration = 0;
this.frostAxeDuration = 0;
this.magicWeaponDuration = 0;
this.flamingWeaponDuration = 0;
this.freezingWeaponDuration = 0;
// Death cancels transportation spell.
this.tpTimer = 0;
this.soulboundCreatures = new HashSet<UUID>();
this.currentlyCasting = WizardryRegistry.none;
this.castingTick = 0;
this.spellDamageMultiplier = 1;
this.spellRangeMultiplier = 1;
this.spellDurationMultiplier = 1;
this.spellBlastMultiplier = 1;
}
/**
* Returns the string key to be used when saving and loading the extended player data on respawn.
*/
public static String getSaveKey(EntityPlayer player) {
return player.getUniqueID().toString() + ":" + name;
}
/**
* Used to register these extended properties for the player during EntityConstructing event
* This method is for convenience only; it will make your code look nicer
*/
public static final void register(EntityPlayer player){
player.registerExtendedProperties(ExtendedPlayer.name, new ExtendedPlayer(player));
}
/**
* Returns the ExtendedPlayer properties for the specified player.
*/
public static final ExtendedPlayer get(EntityPlayer player){
return (ExtendedPlayer) player.getExtendedProperties(name);
}
/** Sends a packet to this player's client to synchronise necessary information. Only called server side. */
public void sync(){
if(this.player instanceof EntityPlayerMP){
int id = -1;
if(this.selectedMinion != null && this.selectedMinion.get() != null) id = this.selectedMinion.get().getEntityId();
IMessage msg = new PacketPlayerSync.Message(this.spellsDiscovered, id);
WizardryPacketHandler.net.sendTo(msg, (EntityPlayerMP)this.player);
}
}
@Override
public void saveNBTData(NBTTagCompound compound) {
// NBTTagCompound is for Maps, NBTTagList is for Lists/Sets
NBTTagCompound properties = new NBTTagCompound();
properties.setInteger("conjuredSwordDuration", this.conjuredSwordDuration);
properties.setInteger("conjuredPickaxeDuration", this.conjuredPickaxeDuration);
properties.setInteger("conjuredBowDuration", this.conjuredBowDuration);
properties.setInteger("conjuredArmourDuration", this.conjuredArmourDuration);
properties.setInteger("flamingAxeDuration", this.flamingAxeDuration);
properties.setInteger("frostAxeDuration", this.frostAxeDuration);
properties.setInteger("magicWeaponDuration", this.magicWeaponDuration);
properties.setInteger("flamingWeaponDuration", this.flamingWeaponDuration);
properties.setInteger("freezingWeaponDuration", this.freezingWeaponDuration);
properties.setBoolean("hasSpiritWolf", this.hasSpiritWolf);
properties.setBoolean("hasSpiritHorse", this.hasSpiritHorse);
properties.setInteger("x", this.transportX);
properties.setInteger("y", this.transportY);
properties.setInteger("z", this.transportZ);
properties.setInteger("dimension", this.transportDimension);
properties.setInteger("x2", this.clairvoyanceX);
properties.setInteger("y2", this.clairvoyanceY);
properties.setInteger("z2", this.clairvoyanceZ);
properties.setInteger("dimension2", this.clairvoyanceDimension);
properties.setInteger("tpTimer", this.tpTimer);
NBTTagList tagList = new NBTTagList();
for(UUID id : this.allies){
tagList.appendTag(new NBTTagString(id.toString()));
}
properties.setTag("allies", tagList);
NBTTagList tagList2 = new NBTTagList();
for(String name : this.allyNames){
tagList2.appendTag(new NBTTagString(name));
}
properties.setTag("allyNames", tagList2);
NBTTagList tagList3 = new NBTTagList();
for(UUID id : this.soulboundCreatures){
tagList3.appendTag(new NBTTagString(id.toString()));
}
properties.setTag("soulboundCreatures", tagList3);
int[] spells = new int[this.spellsDiscovered.size()];
int i=0;
for(Spell spell : this.spellsDiscovered){
spells[i] = spell.id();
i++;
}
properties.setIntArray("discoveredSpells", spells);
compound.setTag(name, properties);
}
@Override
public void loadNBTData(NBTTagCompound compound) {
NBTTagCompound properties = (NBTTagCompound) compound.getTag(name);
if(properties != null){
this.conjuredSwordDuration = properties.getInteger("conjuredSwordDuration");
this.conjuredPickaxeDuration = properties.getInteger("conjuredPickaxeDuration");
this.conjuredBowDuration = properties.getInteger("conjuredBowDuration");
this.conjuredArmourDuration = properties.getInteger("conjuredArmourDuration");
this.flamingAxeDuration = properties.getInteger("flamingAxeDuration");
this.frostAxeDuration = properties.getInteger("frostAxeDuration");
this.magicWeaponDuration = properties.getInteger("magicWeaponDuration");
this.flamingWeaponDuration = properties.getInteger("flamingWeaponDuration");
this.freezingWeaponDuration = properties.getInteger("freezingWeaponDuration");
this.hasSpiritWolf = properties.getBoolean("hasSpiritWolf");
this.hasSpiritHorse = properties.getBoolean("hasSpiritHorse");
this.transportX = properties.getInteger("x");
this.transportY = properties.getInteger("y");
this.transportZ = properties.getInteger("z");
this.transportDimension = properties.getInteger("dimension");
this.clairvoyanceX = properties.getInteger("x2");
this.clairvoyanceY = properties.getInteger("y2");
this.clairvoyanceZ = properties.getInteger("z2");
this.clairvoyanceDimension = properties.getInteger("dimension2");
this.tpTimer = properties.getInteger("tpTimer");
this.allies = new HashSet<UUID>();
NBTTagList tagList = properties.getTagList("allies", NBT.TAG_STRING);
for(int i=0; i<tagList.tagCount(); i++){
allies.add(UUID.fromString(tagList.getStringTagAt(i)));
}
this.allyNames = new HashSet<String>();
NBTTagList tagList2 = properties.getTagList("allyNames", NBT.TAG_STRING);
for(int i=0; i<tagList2.tagCount(); i++){
allyNames.add(tagList2.getStringTagAt(i));
}
this.soulboundCreatures = new HashSet<UUID>();
NBTTagList tagList3 = properties.getTagList("soulboundCreatures", NBT.TAG_STRING);
for(int i=0; i<tagList3.tagCount(); i++){
soulboundCreatures.add(UUID.fromString(tagList3.getStringTagAt(i)));
}
this.spellsDiscovered = new HashSet<Spell>();
for(int id : properties.getIntArray("discoveredSpells")){
spellsDiscovered.add(Spell.get(id));
}
}
}
@Override
public void init(Entity entity, World world) {
// For reference, apparently there is a strange error that causes 'this' to be null here.
}
}
@@ -1,16 +0,0 @@
package electroblob.wizardry;
import electroblob.wizardry.MagicDamage.DamageType;
import net.minecraft.entity.Entity;
import scala.actors.threadpool.Arrays;
/** This interface allows {@link MagicDamage} and {@link IndirectMagicDamage} to both be treated as instances of a
* single type so that the damage type field can be accessed, rather than having to deal with each of them separately,
* which would be inefficient and cumbersome (the latter of those classes cannot extend the former because they both
* need to extend different subclasses of {@link net.minecraft.util.DamageSource DamageSource}).
* @since Wizardry 1.1 */
public interface IElementalDamage {
DamageType getType();
}
@@ -0,0 +1,591 @@
package electroblob.wizardry;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import electroblob.wizardry.packet.PacketSyncSettings;
import electroblob.wizardry.packet.WizardryPacketHandler;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.translation.I18n;
import net.minecraftforge.common.config.ConfigCategory;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
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
* {@link Wizardry#settings}. Also stores a few string constants for easy access.
* <p>
* As part of the 1.2 update and code overhaul, the way the config settings work in multiplayer has been tightened up.
* Importantly, there are <b>three</b> different types of config options:
* <p>
* <li>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. Examples
* include worldgen, mob drops and commands.
* <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 only has an effect if the
* local game is the host, i.e. a dedicated server, a LAN host or a singleplayer world. Examples include discovery mode
* and crafting recipes. <i> Note that as far as users are concerned, there is no difference in behaviour between
* 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 its
* own values for these, and changing them on a dedicated server will have no effect. These are usually only display and
* controls settings.</li>
* <p>
* Each of the settings fields in this class is marked with one of the above categories to indicate which it belongs to.
* This in turn dictates which logical side it should be called from: client, server or both. <b> Do not access a config
* setting from the wrong side, because it may cause unexpected or strange behaviour.</b>
*
* @since Wizardry 1.2
* @author Electroblob
*/
// TODO: New plan: convert to the @Config system BUT separate the spells config out so it doesn't break stuff. (Maybe even
// make it a JSON instead? Either way, there's scope for then adding more options for adjusting the base attributes etc.)
// @Config(modid = Wizardry.MODID)
@SuppressWarnings("deprecation") // Used server I18n deliberately; we want to write the comments in english.
public final class Settings {
// Category names
/** The unlocalised name of the spells config category. */
public static final String SPELLS_CATEGORY = "spells";
/** The unlocalised name of the resistances config category. */
public static final String RESISTANCES_CATEGORY = "resistances";
/** The unlocalised name of the client config category. */
public static final String CLIENT_CATEGORY = "client";
/** The unlocalised name of the commands config category. */
public static final String COMMANDS_CATEGORY = "commands";
/** The unlocalised name of the worldgen config category. */
public static final String WORLDGEN_CATEGORY = "worldgen";
/** The unlocalised name of the gameplay config category. */
public static final String GAMEPLAY_CATEGORY = "gameplay";
/** The wizardry config file. */
private Configuration config;
// 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.
// Worldgen
/** <b>[Server-only]</b> The rarity of wizard towers, used by the world generator. Larger numbers are rarer. */
public int towerRarity = 8;
/** <b>[Server-only]</b> List of dimension ids in which to generate crystal ore. */
public int[] oreDimensions = {0};
/** <b>[Server-only]</b> List of dimension ids in which to generate crystal ore. */
public int[] flowerDimensions = {0};
/** <b>[Server-only]</b> List of dimension ids in which to generate crystal ore. */
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.
*/
public boolean generateLoot = true;
// Entities' drops, targeting, damage, etc.
/** <b>[Server-only]</b> Chance (out of 200) for mobs to drop spell books. */
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.
*/
public boolean teleportThroughUnbreakableBlocks = false;
/** <b>[Server-only]</b> Whether to allow players to damage their designated allies using magic. */
public boolean friendlyFire = true;
/** <b>[Server-only]</b> Whether to allow players to disarm other players using the telekinesis spell. */
public boolean telekineticDisarmament = true;
/** <b>[Server-only]</b> Whether summoned creatures can revenge attack their caster if their caster attacks them. */
public boolean minionRevengeTargeting = true;
/**
* <b>[Server-only]</b> List of registry names of entities which summoned creatures are allowed to attack, in addition
* to the defaults.
*/
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. */
public double playerDamageScale = 1.0f;
/** <b>[Server-only]</b> Global damage scaling factor for all npc magic damage. */
public double npcDamageScale = 1.0f;
/** <b>[Server-only]</b> List of dimension ids in which evil wizards can spawn. */
public int[] evilWizardDimensions = {0};
// Commands (these don't need synchronising since typing a command always queries the server).
/**
* <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;
/** <b>[Server-only]</b> The name of the /cast command. */
public String castCommandName = "cast";
/** <b>[Server-only]</b> The name of the /discoverspell command. */
public String discoverspellCommandName = "discoverspell";
/** <b>[Server-only]</b> The name of the /ally command. */
public String allyCommandName = "ally";
/** <b>[Server-only]</b> The name of the /allies command. */
public String alliesCommandName = "allies";
// 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.
// 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.
*/
public boolean discoveryMode = true;
// 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.
// Controls
/**
* <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;
// Display
/** <b>[Client-only]</b> Whether to show summoned creatures' names and owners above their heads. */
public boolean showSummonedCreatureNames = true;
/** <b>[Client-only]</b> The position of the spell HUD. */
public GuiPosition spellHUDPosition = GuiPosition.BOTTOM_LEFT;
/** Set of constants for each of the four positions that the spell HUD can be in. */
public enum GuiPosition {
BOTTOM_LEFT("Bottom left"), 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. */
public static final String[] names;
static{
names = new String[values().length];
for(GuiPosition position : values()){
names[position.ordinal()] = position.name;
}
}
/** The readable name for this GUI position that will be displayed on the button in the config GUI. */
public final String name;
GuiPosition(String 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.
*/
public static GuiPosition fromName(String name){
for(GuiPosition position : values()){
if(position.name.equalsIgnoreCase(name)) return position;
}
Wizardry.logger.info("Invalid string for the spell HUD position. Using default (bottom left) instead.");
return BOTTOM_LEFT;
}
}
// 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
// options for different languages.
// 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
* conventional) so that the various registries can change what they do accordingly. The spell part of the config
* 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){
config = new Configuration(event.getSuggestedConfigurationFile());
config.load();
Wizardry.logger.info("Setting up main config");
setupGeneralConfig();
setupWorldgenConfig();
setupClientConfig();
setupCommandsConfig();
config.save();
}
/**
* Called from init to initialise the parts of the config file that 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. */
void saveConfigChanges(){
Wizardry.logger.info("Saving in-game config changes");
setupGeneralConfig();
setupWorldgenConfig();
setupClientConfig();
setupCommandsConfig();
setupSpellsConfig();
setupResistancesConfig();
config.save();
}
/** Sends a packet to the specified player's client containing all the <b>synchronised</b> settings. */
public void sync(EntityPlayerMP player){
Wizardry.logger.info("Synchronising config settings for " + player.getName());
IMessage message = new PacketSyncSettings.Message(this);
WizardryPacketHandler.net.sendTo(message, player);
}
public ConfigCategory getConfigCategory(String name){
return config.getCategory(name);
}
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.");
Property property;
for(Spell spell : Spell.getSpells(Spell.allSpells)){
property = config.get(SPELLS_CATEGORY, spell.getRegistryName().toString(), true,
I18n.translateToLocal("spell." + spell.getUnlocalisedName() + ".desc"));
// Uses the same config key as the spell name, because - well, that's what it's called!
property.setLanguageKey("spell." + spell.getUnlocalisedName());
spell.setEnabled(property.getBoolean());
}
}
private void setupGeneralConfig(){
// 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(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(GAMEPLAY_CATEGORY, "discoveryMode", true,
"For those who like a sense of mystery! When set to true, spells you haven't cast yet will be unreadable until you cast them (on a per-world basis). Has no effect when in creative mode. Spells of identification will be unobtainable in survival mode if this is false.");
property.setLanguageKey("config." + Wizardry.MODID + ".discovery_mode");
property.setRequiresWorldRestart(true);
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);
Wizardry.proxy.setToNumberSliderEntry(property);
towerRarity = property.getInt();
propOrder.add(property.getName());
property = config.get(WORLDGEN_CATEGORY, "towerDimensions", new int[]{0}, "List of dimension ids in which wizard towers will generate.");
property.setLanguageKey("config." + Wizardry.MODID + ".tower_dimensions");
property.setRequiresWorldRestart(true);
towerDimensions = property.getIntList();
propOrder.add(property.getName());
property = config.get(WORLDGEN_CATEGORY, "oreDimensions", new int[]{0}, "List of dimension ids in which crystal ore will generate. Note that removing the overworld (id 0) from this list will make the mod VERY difficult to play!");
property.setLanguageKey("config." + Wizardry.MODID + ".ore_dimensions");
property.setRequiresWorldRestart(true);
oreDimensions = property.getIntList();
propOrder.add(property.getName());
property = config.get(WORLDGEN_CATEGORY, "flowerDimensions", new int[]{0}, "List of dimension ids in which crystal flowers will generate.");
property.setLanguageKey("config." + Wizardry.MODID + ".flower_dimensions");
property.setRequiresWorldRestart(true);
flowerDimensions = property.getIntList();
propOrder.add(property.getName());
property = config.get(WORLDGEN_CATEGORY, "generateLoot", true, "Whether to inject wizardry loot (as specified in loot_tables/chests/dungeon_additions.json) into the loot tables for vanilla dungeon chests.");
property.setLanguageKey("config." + Wizardry.MODID + ".generate_loot");
property.setRequiresWorldRestart(true);
generateLoot = property.getBoolean();
propOrder.add(property.getName());
config.setCategoryPropertyOrder(WORLDGEN_CATEGORY, propOrder);
}
private void setupClientConfig(){
// This trick is borrowed from forge; it sorts the config options into the order you want them.
List<String> propOrder = new ArrayList<String>();
Property property;
config.addCustomCategoryComment(CLIENT_CATEGORY, "Client-side settings that only affect the local minecraft game. If this file is on a dedicated server, these settings will have no effect; in multiplayer, each player obeys their own settings.");
property = config.get(CLIENT_CATEGORY, "enableShiftScrolling", true,
"Whether you can switch between spells on a wand by scrolling with the mouse wheel while sneaking. Note that this will only affect you; other players connected to the same server obey their own settings.");
property.setLanguageKey("config." + Wizardry.MODID + ".enable_shift_scrolling");
property.setRequiresWorldRestart(false);
enableShiftScrolling = property.getBoolean();
propOrder.add(property.getName());
property = config.get(CLIENT_CATEGORY, "spellHUDPosition", GuiPosition.BOTTOM_LEFT.name, "The position of the spell HUD.", GuiPosition.names);
property.setLanguageKey("config." + Wizardry.MODID + ".spell_hud_position");
spellHUDPosition = GuiPosition.fromName(property.getString());
propOrder.add(property.getName());
property = config.get(CLIENT_CATEGORY, "showSummonedCreatureNames", true, "Whether to show summoned creatures' names and owners above their heads.");
property.setLanguageKey("config." + Wizardry.MODID + ".show_summoned_creature_names");
showSummonedCreatureNames = property.getBoolean();
propOrder.add(property.getName());
config.setCategoryPropertyOrder(CLIENT_CATEGORY, propOrder);
}
private void setupCommandsConfig(){
// This trick is borrowed from forge; it sorts the config options into the order you want them.
List<String> propOrder = new ArrayList<String>();
Property property;
config.addCustomCategoryComment(COMMANDS_CATEGORY, "Settings for the commands added by Wizardry. In multiplayer, the server/LAN host settings will apply.");
// This one isn't a slider either because people are likely to want exact values ("it must be at most 50.3" is a
// bit strange!).
property = config.get(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);
castCommandName = property.getString();
propOrder.add(property.getName());
property = config.get(COMMANDS_CATEGORY, "discoverspellCommandName", "discoverspell",
"The name of the /discoverspell command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /discoverspell you would type /magic instead.");
property.setLanguageKey("config." + Wizardry.MODID + ".discoverspell_command_name");
property.setRequiresWorldRestart(true);
discoverspellCommandName = property.getString();
propOrder.add(property.getName());
property = config.get(COMMANDS_CATEGORY, "allyCommandName", "ally",
"The name of the /ally command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /ally you would type /magic instead.");
property.setLanguageKey("config." + Wizardry.MODID + ".ally_command_name");
property.setRequiresWorldRestart(true);
allyCommandName = property.getString();
propOrder.add(property.getName());
property = config.get(COMMANDS_CATEGORY, "alliesCommandName", "allies",
"The name of the /allies command. This is what you type directly after the /; for example if this was set to 'magic' then instead of typing /allies you would type /magic instead.");
property.setLanguageKey("config." + Wizardry.MODID + ".allies_command_name");
property.setRequiresWorldRestart(true);
alliesCommandName = property.getString();
propOrder.add(property.getName());
config.setCategoryPropertyOrder(COMMANDS_CATEGORY, propOrder);
}
private void setupResistancesConfig(){
Property property;
List<String> propOrder = new ArrayList<String>();
config.addCustomCategoryComment(RESISTANCES_CATEGORY,
"Settings which allow entities to be made immune to certain types of magic. In multiplayer, the server/LAN host settings will apply.");
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToFire", new String[]{},
"List of names of entities that are immune to fire, in addition to the defaults. Add mod creatures to this list if you want them to be immune to fire magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_fire");
property.setRequiresMcRestart(true);
// Wizardry.proxy.setToEntityNameEntry(property);
// 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++){
property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim();
MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
DamageType.FIRE);
}
propOrder.add(property.getName());
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToIce", new String[]{},
"List of names of entities that are immune to ice, in addition to the defaults. Add mod creatures to this list if you want them to be immune to ice magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_ice");
property.setRequiresMcRestart(true);
// Wizardry.proxy.setToEntityNameEntry(property);
// 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++){
property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim();
MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
DamageType.FROST);
}
propOrder.add(property.getName());
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToLightning", new String[]{},
"List of names of entities that are immune to lightning, in addition to the defaults. Add mod creatures to this list if you want them to be immune to lightning magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_lightning");
property.setRequiresMcRestart(true);
// Wizardry.proxy.setToEntityNameEntry(property);
// 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++){
property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim();
MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
DamageType.SHOCK);
}
propOrder.add(property.getName());
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToWither", new String[]{},
"List of names of entities that are immune to wither effects, in addition to the defaults. Add mod creatures to this list if you want them to be immune to withering magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_wither");
property.setRequiresMcRestart(true);
// Wizardry.proxy.setToEntityNameEntry(property);
// 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++){
property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim();
MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
DamageType.WITHER);
}
propOrder.add(property.getName());
property = config.get(RESISTANCES_CATEGORY, "mobsImmuneToPoison", new String[]{},
"List of names of entities that are immune to poison, in addition to the defaults. Add mod creatures to this list if you want them to be immune to poison magic and they aren't already. Entity names are not case sensitive. For mod entities, prefix with the mod ID (e.g. " + Wizardry.MODID + ":wizard).");
property.setLanguageKey("config." + Wizardry.MODID + ".mobs_immune_to_poison");
property.setRequiresMcRestart(true);
// Wizardry.proxy.setToEntityNameEntry(property);
// 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++){
property.getStringList()[i] = property.getStringList()[i].toLowerCase(Locale.ROOT).trim();
MagicDamage.addEntityImmunity(EntityList.getClass(new ResourceLocation(property.getStringList()[i])),
DamageType.POISON);
}
propOrder.add(property.getName());
config.setCategoryPropertyOrder(RESISTANCES_CATEGORY, propOrder);
}
}
@@ -15,110 +15,127 @@ import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
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.event.world.WorldEvent;
import net.minecraftforge.fml.common.Mod;
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.
* @since Wizardry 1.1 */
*
* @since Wizardry 1.1
*/
@Mod.EventBusSubscriber
public class SpellGlyphData extends WorldSavedData {
private 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> randomDescriptions = new HashMap<Spell, String>(Spell.getTotalSpellCount());
// Required constructors
public SpellGlyphData() {
public SpellGlyphData(){
this(NAME);
}
public SpellGlyphData(String name){
super(name);
}
/** Generates random names and descriptions for any spells which don't already have them. */
public void generateGlyphNames(World world){
for(Spell spell : Spell.getSpells(Spell.allSpells)){
if(!randomNames.containsKey(spell)) randomNames.put(spell, generateRandomName(world.rand));
}
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();
}
private String generateRandomName(Random random){
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") + " ";
}
return name.trim();
}
private String generateRandomDescription(Random random){
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") + " ";
}
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. */
public static SpellGlyphData get(World world) {
/**
* 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.
*/
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){
instance = new SpellGlyphData();
}
// 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.
// 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.
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);
world.setItemData(NAME, instance);
world.setData(NAME, instance);
}
return instance;
}
/** Sends the random spell names for this world to the specified player's client. */
public void sync(EntityPlayerMP player){
List<String> names = new ArrayList<String>();
List<String> descriptions = new ArrayList<String>();
for(Spell spell : Spell.getSpells(Spell.allSpells)){
names.add(this.randomNames.get(spell));
descriptions.add(this.randomDescriptions.get(spell));
}
PacketGlyphData.Message msg = new PacketGlyphData.Message(names, descriptions);
WizardryPacketHandler.net.sendTo(msg, player);
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. */
public static String getGlyphName(Spell spell, World world){
Map<Spell, String> names = SpellGlyphData.get(world).randomNames;
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){
Map<Spell, String> descriptions = SpellGlyphData.get(world).randomDescriptions;
return descriptions == null ? "" : descriptions.get(spell);
@@ -126,13 +143,13 @@ public class SpellGlyphData extends WorldSavedData {
@Override
public void readFromNBT(NBTTagCompound nbt){
this.randomNames = new HashMap<Spell, String>();
this.randomDescriptions = new HashMap<Spell, String>();
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);
randomNames.put(Spell.get(tag.getInteger("spell")), tag.getString("name"));
randomDescriptions.put(Spell.get(tag.getInteger("spell")), tag.getString("description"));
@@ -140,10 +157,10 @@ public class SpellGlyphData extends WorldSavedData {
}
@Override
public void writeToNBT(NBTTagCompound nbt){
public NBTTagCompound writeToNBT(NBTTagCompound nbt){
NBTTagList tagList = new NBTTagList();
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
// The description is now also included; there's no point in making a second compound tag!
@@ -153,7 +170,18 @@ public class SpellGlyphData extends WorldSavedData {
tag.setString("description", this.randomDescriptions.get(spell));
tagList.appendTag(tag);
}
nbt.setTag("spellGlyphData", tagList);
return nbt;
}
@SubscribeEvent
public static void onWorldLoadEvent(WorldEvent.Load event){
if(!event.getWorld().isRemote && event.getWorld().provider.getDimension() == 0){
// Called to initialise the spell glyph data when a world loads, if it isn't already.
// NOTE: Do we actually need this, or can we just let it initialise the first time it is needed? (see below)
SpellGlyphData.get(event.getWorld());
}
}
}
@@ -1,64 +0,0 @@
package electroblob.wizardry;
import java.util.Random;
import electroblob.wizardry.item.ItemScroll;
import electroblob.wizardry.item.ItemSpellBook;
import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.item.ItemWizardArmour;
import electroblob.wizardry.spell.Spell;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.WeightedRandomChestContent;
import net.minecraftforge.common.ChestGenHooks;
public class WeightedRandomSpellBook extends WeightedRandomChestContent{
public WeightedRandomSpellBook(ItemStack par1ItemStack, int par2, int par3,
int par4) {
super(par1ItemStack, par2, par3, par4);
}
/* A brief comment about dungeon loot:
* Tiers are weighted as per usual. Elements all have equal chance, INCLUDING simple stuff. The main reason for
* this is that dungeon loot is not that common anyway, so making elemental gear even rarer would be too much.
*/
protected ItemStack[] generateChestContent(Random random, IInventory newInventory){
if(theItemId.getItem() instanceof ItemSpellBook){
theItemId = new ItemStack(theItemId.getItem(), 1, WizardryUtilities.getStandardWeightedRandomSpellId(random));
}else if(theItemId.getItem() instanceof ItemWand){
theItemId = new ItemStack(WizardryUtilities.getWand(EnumTier.BASIC, EnumElement.values()[random.nextInt(EnumElement.values().length)]));
}else if(theItemId.getItem() instanceof ItemWizardArmour){
theItemId = new ItemStack(WizardryUtilities.getArmour(EnumElement.values()[random.nextInt(EnumElement.values().length)], random.nextInt(3)));
}else if(theItemId.getItem() instanceof ItemScroll){
int spellId = WizardryUtilities.getStandardWeightedRandomSpellId(random, true);
theItemId = new ItemStack(theItemId.getItem(), 1, spellId);
}else if(theItemId.getItem() == Wizardry.condenserUpgrade){
switch(random.nextInt(8)){
case 0: theItemId = new ItemStack(Wizardry.condenserUpgrade); break;
case 1: theItemId = new ItemStack(Wizardry.siphonUpgrade); break;
case 2: theItemId = new ItemStack(Wizardry.rangeUpgrade); break;
case 3: theItemId = new ItemStack(Wizardry.cooldownUpgrade); break;
case 4: theItemId = new ItemStack(Wizardry.durationUpgrade); break;
case 5: theItemId = new ItemStack(Wizardry.storageUpgrade); break;
case 6: theItemId = new ItemStack(Wizardry.blastUpgrade); break;
case 7: theItemId = new ItemStack(Wizardry.attunementUpgrade); break;
}
}
return ChestGenHooks.generateStacks(random, theItemId, theMinimumChanceToGenerateItem, theMaximumChanceToGenerateItem);
}
}
@@ -0,0 +1,715 @@
package electroblob.wizardry;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.enchantment.Imbuement;
import electroblob.wizardry.entity.EntityShield;
import electroblob.wizardry.entity.living.ISummonedCreature;
import electroblob.wizardry.event.SpellCastEvent;
import electroblob.wizardry.event.SpellCastEvent.Source;
import electroblob.wizardry.packet.PacketCastContinuousSpell;
import electroblob.wizardry.packet.PacketPlayerSync;
import electroblob.wizardry.packet.PacketTransportation;
import electroblob.wizardry.packet.WizardryPacketHandler;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardryAdvancementTriggers;
import electroblob.wizardry.spell.None;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.SpellModifiers;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Items;
import net.minecraft.init.MobEffects;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemEnchantedBook;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.*;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
import net.minecraftforge.event.entity.player.PlayerEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
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 and
* an IEEP is a couple of redundant classes and a different way of registering it.
* <p>
* Forge seems to have separate classes to hold the Capability<...> instance ('key') and methods for getting the
* capability, but in my opinion there are already too many classes to deal with, so I'm not adding any more than are
* necessary, meaning those constants and values are kept here instead.
*
* @since Wizardry 2.1
* @author Electroblob
*/
// On the plus side, having to rethink this class allowed me to clean it up a lot.
@Mod.EventBusSubscriber
public class WizardData implements INBTSerializable<NBTTagCompound> {
/** Static instance of what I like to refer to as the capability key. Private because, well, it's internal! */
// This annotation does some crazy Forge magic behind the scenes and assigns this field a value.
@CapabilityInject(WizardData.class)
private static final Capability<WizardData> WIZARD_DATA_CAPABILITY = null;
/** The player this WizardData instance belongs to. */
private final EntityPlayer player;
// This one is still necessary, because I can't override the equip animation for items that aren't from Wizardry.
private Map<Imbuement, Integer> imbuementDurations;
public boolean hasSpiritWolf;
public boolean hasSpiritHorse;
/**
* Whether this player is currently casting a continuous spell via commands. Not saved over world reload and reset
* on player death.
*/
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.
*/
private int castingTick;
/**
* SpellModifiers object for the current continuous spell cast via commands. Not saved over world reload and reset
* on player death.
*/
private SpellModifiers spellModifiers;
/** Coordinates for the saved transportation stone circle location. Will be null if no location is saved. */
private BlockPos stoneCircleLocation;
/** Dimension id which the saved stone circle is in. */
private int stoneCircleDimension;
/** Time left until the player teleports under the effect of transportation */
private int tpCountdown;
/** Coordinates for the saved clairvoyance location. Will be null if no location is saved. */
private BlockPos clairvoyanceLocation;
/** Dimension id which the saved clairvoyance point is in. */
private int clairvoyanceDimension;
public EntityShield shield;
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.
*/
public Set<Spell> spellsDiscovered;
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. <b> Do not use this for any other
* purpose than displaying the names!
*/
public Set<String> allyNames;
private Set<UUID> soulboundCreatures;
public WizardData(){
this(null); // Nullary constructor for the registration method factory parameter
}
public WizardData(EntityPlayer player){
this.player = player;
this.imbuementDurations = new HashMap<Imbuement, Integer>();
this.spellsDiscovered = new HashSet<Spell>();
// All players can recognise magic missile. This is not done using discoverSpell because that seems to cause
// a crash on load occasionally (probably something to do with achievements being initalised)
this.spellsDiscovered.add(Spells.magic_missile);
this.hasSpiritWolf = false;
this.hasSpiritHorse = false;
this.currentlyCasting = Spells.none;
this.spellModifiers = new SpellModifiers();
this.castingTick = 0;
this.stoneCircleDimension = 0;
this.clairvoyanceDimension = 0;
this.setTpCountdown(0);
this.allies = new HashSet<UUID>();
this.allyNames = new HashSet<String>();
this.soulboundCreatures = new HashSet<UUID>();
}
public boolean hasSpellBeenDiscovered(Spell spell){
return spellsDiscovered.contains(spell) || spell instanceof None;
}
/**
* Adds the given spell to the list of discovered spells for this player. Automatically takes into account whether
* the spell has been discovered. Use this method rather than adding directly to the list because it handles
* achievements.
*
* @param spell The spell to be discovered
* @return True if the spell had not already been discovered; false otherwise.
*/
public boolean discoverSpell(Spell spell){
if(spellsDiscovered == null){
spellsDiscovered = new HashSet<Spell>();
}
// The 'none' spell cannot be discovered
if(spell instanceof None) return false;
// Tries to add the spell to the list of discovered spells, and returns false if it was already present
if(!spellsDiscovered.add(spell)) return false;
// If the spell had not already been discovered, achievements can be triggered and the method returns true
if(spellsDiscovered.containsAll(Spell.getSpells(Spell::isEnabled))){
WizardryAdvancementTriggers.all_spells.triggerFor(this.player);
}
for(Element element : Element.values()){
if(element != Element.MAGIC
&& spellsDiscovered.containsAll(Spell.getSpells(new Spell.TierElementFilter(null, element)))){
WizardryAdvancementTriggers.element_master.triggerFor(this.player);
}
}
return true;
}
/** Sets the player's saved transportation stone location and dimension. */
public void setStoneCircleLocation(BlockPos pos, int dimensionID){
this.stoneCircleLocation = pos;
this.stoneCircleDimension = dimensionID;
}
/** Returns the coordinates of the associated player's saved transportation stone circle. */
public BlockPos getStoneCircleLocation(){
return stoneCircleLocation;
}
/** Returns the dimension ID of the associated player's saved transportation stone circle. */
public int getStoneCircleDimension(){
return stoneCircleDimension;
}
public int getTpCountdown(){
return tpCountdown;
}
public void setTpCountdown(int tpCountdown){
this.tpCountdown = tpCountdown;
}
/** Sets the player's saved clairvoyance location. */
public void setClairvoyancePoint(BlockPos pos, int dimensionID){
this.clairvoyanceLocation = pos;
this.clairvoyanceDimension = dimensionID;
}
/** Returns the coordinates for the saved clairvoyance location. Will be null if no location is saved. */
public BlockPos getClairvoyanceLocation(){
return clairvoyanceLocation;
}
/** Returns the dimension ID for the saved clairvoyance location. Will be null if no location is saved. */
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.
*
* @throws IllegalArgumentException if the given {@link Enchantment} is not an {@link Imbuement}.
*/
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
// were ignored) or cause a ClassCastException later (if non-imbuements were allowed to be added).
if(enchantment instanceof Imbuement){
this.imbuementDurations.put((Imbuement)enchantment, duration);
}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.)");
}
}
/**
* Returns the imbuement duration associated with the given imbuement for this player, or 0 if it does not exist.
*/
@SuppressWarnings("unlikely-arg-type")
public int getImbuementDuration(Enchantment enchantment){
// 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.
Integer i = this.imbuementDurations.get(enchantment);
// If i is null, returns 0; otherwise returns i, auto-unboxed to an int.
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.
*/
private void updateImbuedItems(){
Set<Imbuement> activeImbuements = new HashSet<Imbuement>();
// For each item in the player's inventory
for(ItemStack stack : player.inventory.mainInventory){
if(stack.isItemEnchanted()){
NBTTagList enchantmentList = stack.getItem() == Items.ENCHANTED_BOOK ?
ItemEnchantedBook.getEnchantments(stack) : stack.getEnchantmentTagList();
Iterator<NBTBase> iterator =enchantmentList.iterator();
// For each of the item's enchantments
while(iterator.hasNext()){
NBTTagCompound enchantmentTag = (NBTTagCompound) iterator.next();
Enchantment enchantment = Enchantment.getEnchantmentByID(enchantmentTag.getShort("id"));
// Ignores the enchantment unless it is an imbuement
if(enchantment instanceof Imbuement){
int duration = this.getImbuementDuration(enchantment);
// If the imbuement is still active:
if(duration > 0){
// Decrements the timer
this.imbuementDurations.put((Imbuement)enchantment, duration - 1);
// Adds this imbuement to the set of imbuements that need to be kept
activeImbuements.add((Imbuement)enchantment);
// Otherwise:
}else{
// Removes the enchantment from the item
iterator.remove();
}
}
}
}
}
// Removes all imbuements from the map that are no longer active
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.
*/
public boolean toggleAlly(EntityPlayer player){
if(this.isPlayerAlly(player)){
this.allies.remove(player.getUniqueID());
// The remove method uses .equals() rather than == so this will work fine.
this.allyNames.remove(player.getName());
return false;
}else{
this.allies.add(player.getUniqueID());
this.allyNames.add(player.getName());
return true;
}
}
/** Returns whether the given player is in this player's list of allies, or is on the same team as this player. */
public boolean isPlayerAlly(EntityPlayer player){
return this.allies.contains(player.getUniqueID()) || this.player.isOnSameTeam(player);
}
/** Adds the given entity to this player's list of soulbound creatures, and returns whether it succeeded. */
public boolean soulbind(EntityLivingBase target){
return this.soulboundCreatures.add(target.getUniqueID());
}
/** Returns whether the given entity has been soulbound to this player. */
public boolean isCreatureSoulbound(EntityPlayer target){
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.
*/
public void damageAllSoulboundCreatures(float damage){
for(Iterator<UUID> iterator = this.soulboundCreatures.iterator(); iterator.hasNext();){
Entity entity = WizardryUtilities.getEntityByUUID(this.player.world, iterator.next());
if(entity == null) iterator.remove();
if(entity instanceof EntityLivingBase){
// Retaliatory effect
if(entity.attackEntityFrom(MagicDamage.causeDirectMagicDamage(this.player, DamageType.MAGIC, true),
damage)){
// Sound only plays if the damage succeeds
player.playSound(SoundEvents.ENTITY_WITHER_HURT, 1.0F, player.world.rand.nextFloat() * 0.2F + 1.0F);
}
}
}
}
/** Starts casting the given spell with the given modifiers. */
public void startCastingContinuousSpell(Spell spell, SpellModifiers modifiers){
this.currentlyCasting = spell;
this.spellModifiers = modifiers;
if(!this.player.world.isRemote){
PacketCastContinuousSpell.Message message = new PacketCastContinuousSpell.Message(this.player.getEntityId(),
spell.id(), this.spellModifiers);
WizardryPacketHandler.net.sendToDimension(message, this.player.world.provider.getDimension());
}
}
/** Stops casting the current spell. */
public void stopCastingContinuousSpell(){
this.currentlyCasting = Spells.none;
this.castingTick = 0;
this.spellModifiers.reset();
if(!this.player.world.isRemote){
PacketCastContinuousSpell.Message message = new PacketCastContinuousSpell.Message(this.player.getEntityId(),
Spells.none.id(), this.spellModifiers);
WizardryPacketHandler.net.sendToDimension(message, this.player.world.provider.getDimension());
}
}
/** Casts the current continuous spell, fires relevant events and updates the castingTick field. */
public void updateContinuousSpellCasting(){
if(this.currentlyCasting != null && this.currentlyCasting.isContinuous){
if(MinecraftForge.EVENT_BUS.post(
new SpellCastEvent.Tick(player, currentlyCasting, spellModifiers, Source.COMMAND, castingTick))){
this.stopCastingContinuousSpell();
return;
}
if(this.currentlyCasting.cast(player.world, player, EnumHand.MAIN_HAND, castingTick, this.spellModifiers)
&& this.castingTick == 0){
// 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));
}
castingTick++;
}else{
// Why is this here? Surely castingTick will always be 0 if currentlyCasting is null?
this.castingTick = 0;
}
}
/** Returns whether this player is currently casting a continuous spell via commands. */
public boolean isCasting(){
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.
*/
public Spell currentlyCasting(){
return currentlyCasting;
}
/** Called each time the associated player is updated. */
private void update(){
if(this.selectedMinion != null && this.selectedMinion.get() == null) this.selectedMinion = null;
// This new system removes a lot of repetitive event handler code and inflexible variables which had duplicate
// functions, just for different enchantments.
updateImbuedItems();
if(!player.world.isRemote){
if(getTpCountdown() == 1){
player.setPositionAndUpdate(this.stoneCircleLocation.getX() + 0.5, this.stoneCircleLocation.getY(),
this.stoneCircleLocation.getZ() + 0.5);
player.addPotionEffect(new PotionEffect(MobEffects.BLINDNESS, 50, 0));
IMessage msg = new PacketTransportation.Message(player.getEntityId());
WizardryPacketHandler.net.sendToDimension(msg, player.world.provider.getDimension());
}
if(getTpCountdown() > 0){
setTpCountdown(getTpCountdown() - 1);
}
}
updateContinuousSpellCasting();
}
/**
* Returns the WizardData instance for the specified player.
*/
public static final WizardData get(EntityPlayer player){
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. 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 respawn True if the player died and is respawning, false if they are just travelling between dimensions.
*/
public void copyFrom(WizardData data, boolean respawn){
// TODO: What happens with spirit wolf and spirit horse?
this.hasSpiritHorse = data.hasSpiritHorse;
this.hasSpiritWolf = data.hasSpiritWolf;
this.allies = data.allies;
this.allyNames = data.allyNames;
this.clairvoyanceDimension = data.clairvoyanceDimension;
this.clairvoyanceLocation = data.clairvoyanceLocation;
this.selectedMinion = data.selectedMinion;
// Curse of soulbinding is lifted when the caster dies, but not when they switch dimensions.
if(!respawn) this.soulboundCreatures = data.soulboundCreatures;
this.spellsDiscovered = data.spellsDiscovered;
this.stoneCircleDimension = data.stoneCircleDimension;
this.stoneCircleLocation = data.stoneCircleLocation;
// Imbuements are lost on death so their durations do not persist.
// Command spell casting is reset on death so the associated variables do not persist.
// tpCountdown is reset both when the player dies and when they switch dimensions.
}
/** Sends a packet to this player's client to synchronise necessary information. Only called server side. */
public void sync(){
if(this.player instanceof EntityPlayerMP){
int id = -1;
if(this.selectedMinion != null && this.selectedMinion.get() instanceof Entity)
id = ((Entity)this.selectedMinion.get()).getEntityId();
IMessage msg = new PacketPlayerSync.Message(this.spellsDiscovered, id);
WizardryPacketHandler.net.sendTo(msg, (EntityPlayerMP)this.player);
}
}
@Override
public NBTTagCompound serializeNBT(){
NBTTagCompound properties = new NBTTagCompound();
// ...so Java 8 allows you to do stuff like this:
properties.setTag("imbuements", WizardryUtilities.mapToNBT(this.imbuementDurations,
imbuement -> new NBTTagInt(Enchantment.getEnchantmentID((Enchantment)imbuement)), NBTTagInt::new));
properties.setBoolean("hasSpiritWolf", this.hasSpiritWolf);
properties.setBoolean("hasSpiritHorse", this.hasSpiritHorse);
if(this.stoneCircleLocation != null)
properties.setLong("stoneCircleLocation", this.stoneCircleLocation.toLong());
properties.setInteger("stoneCircleDimension", this.stoneCircleDimension);
properties.setInteger("tpCountdown", this.tpCountdown);
if(this.clairvoyanceLocation != null)
properties.setLong("clairvoyanceLocation", this.clairvoyanceLocation.toLong());
properties.setInteger("clairvoyanceDimension", this.getClairvoyanceDimension());
// 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("allyNames", WizardryUtilities.listToNBT(this.allyNames, NBTTagString::new));
properties.setTag("soulboundCreatures",
WizardryUtilities.listToNBT(this.soulboundCreatures, WizardryUtilities::UUIDtoTagCompound));
// Might be worth converting this over to WizardryUtilities.listToNBT.
int[] spells = new int[this.spellsDiscovered.size()];
int i = 0;
for(Spell spell : this.spellsDiscovered){
spells[i] = spell.id();
i++;
}
properties.setIntArray("discoveredSpells", spells);
return properties;
}
@Override
public void deserializeNBT(NBTTagCompound nbt){
if(nbt != null){
this.imbuementDurations = WizardryUtilities.NBTToMap(nbt.getTagList("imbuements", NBT.TAG_COMPOUND),
(NBTTagInt tag) -> (Imbuement)Enchantment.getEnchantmentByID(tag.getInt()), NBTTagInt::getInt);
this.hasSpiritWolf = nbt.getBoolean("hasSpiritWolf");
this.hasSpiritHorse = nbt.getBoolean("hasSpiritHorse");
this.stoneCircleLocation = BlockPos.fromLong(nbt.getLong("stoneCircleLocation"));
this.stoneCircleDimension = nbt.getInteger("stoneCircleDimension");
this.tpCountdown = nbt.getInteger("tpCountdown");
this.clairvoyanceLocation = BlockPos.fromLong(nbt.getLong("clairvoyanceLocation"));
this.clairvoyanceDimension = nbt.getInteger("clairvoyanceDimension");
this.allies = new HashSet<UUID>(WizardryUtilities.NBTToList(nbt.getTagList("allies", NBT.TAG_COMPOUND),
WizardryUtilities::tagCompoundToUUID));
this.allyNames = new HashSet<String>(
WizardryUtilities.NBTToList(nbt.getTagList("allyNames", NBT.TAG_STRING), NBTTagString::getString));
this.soulboundCreatures = new HashSet<UUID>(WizardryUtilities.NBTToList(
nbt.getTagList("soulboundCreatures", NBT.TAG_COMPOUND), WizardryUtilities::tagCompoundToUUID));
this.spellsDiscovered = new HashSet<Spell>();
for(int id : nbt.getIntArray("discoveredSpells")){
spellsDiscovered.add(Spell.get(id));
}
}
}
// Event handlers
@SubscribeEvent
// The type parameter here has to be Entity, not EntityPlayer, or the event won't get fired.
public static void onCapabilityLoad(AttachCapabilitiesEvent<Entity> event){
if(event.getObject() instanceof EntityPlayer)
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
// a player into a CapabilityDispatcher, which is in turn stored in that very same player, which makes no sense
// at all!
// event.addCapability(new ResourceLocation(Wizardry.MODID, "WizardData"), event.getObject());
}
@SubscribeEvent
public static void onPlayerCloneEvent(PlayerEvent.Clone event){
WizardData newData = WizardData.get(event.getEntityPlayer());
WizardData oldData = WizardData.get(event.getOriginal());
newData.copyFrom(oldData, event.isWasDeath());
}
@SubscribeEvent
public static void onEntityJoinWorld(EntityJoinWorldEvent event){
if(!event.getEntity().world.isRemote && event.getEntity() instanceof EntityPlayerMP){
// Synchronises wizard data after loading.
WizardData data = WizardData.get((EntityPlayer)event.getEntity());
if(data != null) data.sync();
}
}
@SubscribeEvent
public static void onLivingUpdateEvent(LivingUpdateEvent event){
if(event.getEntityLiving() instanceof EntityPlayer){
EntityPlayer player = (EntityPlayer)event.getEntityLiving();
if(WizardData.get(player) != null){
WizardData.get(player).update();
}
}
}
/**
* 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
* me to access WIZARD_DATA_CAPABILITY while keeping it private.
*/
public static class Provider implements ICapabilitySerializable<NBTTagCompound> {
private final WizardData data;
public Provider(EntityPlayer player){
data = new WizardData(player);
}
@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing){
return capability == WIZARD_DATA_CAPABILITY;
}
@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing){
if(capability == WIZARD_DATA_CAPABILITY){
return WIZARD_DATA_CAPABILITY.cast(data);
}
return null;
}
@Override
public NBTTagCompound serializeNBT(){
return data.serializeNBT();
}
@Override
public void deserializeNBT(NBTTagCompound nbt){
data.deserializeNBT(nbt);
}
}
// Ended up deleting IWizardData because it was unnecessary. This is the comment that was at the start of it:
/* I'm not going to lie, I will never find the capabilities system even remotely intuitive so this is a bare-minimum
* approach just to get things working (four classes where one would have done?!) At one point I considered simply
* wrapping my old IEEP inside a single-field capability, but I eventually decided I would at least *try* to do it
* properly.
*
* "...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?
*
* Other things I find annoying: - IStorage. It's completely redundant in the majority of cases, and I don't
* understand why we need yet another separate class. - Making an interface, only to implement it once and once
* only. This completely defeats the point of interfaces. - 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
* 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: - You make an interface which defines the
* things your capability can do (this class). I will call this the TEMPLATE. - You implement that interface with
* your default implementation (WizardData). This is the closest analog to your old IEEP implementation class. THIS
* CLASS STORES ALL THE VARIABLES, and hence has one instance for each instance of whatever it is attached to. I
* will call this the DATA. - The DATA class implements INBTSerializable (assuming you want it to be saved, which is
* nearly always the case) - Despite its name, Capability<T> does NOT represent a capability itself. Instead, it
* acts as a sort of identifier/key, the idea being that you can access a particular instance of your DATA given the
* key (which tells forge that you want a capability of type TEMPLATE) and the object you want the DATA for. This is
* 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 capabilities are actually hooked into vanilla: - Anything that implements ICapabilityProvider will have a
* private CapabilityDispatcher field. This holds other ICapabilityProviders. (I know. This inheritance pattern DOES
* NOT MAKE SENSE, because these could, in theory, be OTHER ENTITIES!) - This field is assigned a value through
* Forge's event factory, which, as we are all familiar with, calls all the methods marked with @SubscribeEvent.
* These methods add individual ICapabilityProviders to a Map stored in the event, which the event factory then
* wraps in a CapabilityDispatcher (which is itself an ICapabilityProvider) for the object that called it. - In your
* event handler, you return a custom ICapabilityProvider which is effectively bolted on to the player, and
* duplicates the ICapabilityProvider methods so you can hook into them and return an instance of your DATA class. -
* Where before there was a simple collection of IEEPs stored in the player, there is now a tree of
* ICapabilityProviders:
*
* - Entity/TileEntity/ItemStack - Vanilla ICapabilityProviders, mostly IItemHandlers, stored as fields. -
* CapabilityDispatcher, stored as a field. - Custom ICapabilityProviders - Custom CapabilityDispatchers - ...
*
* Most importantly, EACH PLAYER HOLDS THEIR OWN INSTANCE OF THIS TREE.
*
* When a capability is retrieved, the following process happens: 1. For the Entity/TileEntity/ItemStack instance,
* ICapabilityProvider.getCapability(...) is called. 2. The request propogates through the tree and finds the
* requested capability. */
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -2,34 +2,29 @@ package electroblob.wizardry;
import java.util.Set;
import cpw.mods.fml.client.IModGuiFactory;
import electroblob.wizardry.client.GuiConfigWizardry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraftforge.fml.client.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;
}
@Override
public RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement element)
{
return null;
}
@Override
public void initialize(Minecraft minecraftInstance){
}
@Override
public Set<RuntimeOptionCategoryElement> runtimeGuiCategories(){
return null;
}
@Override
public boolean hasConfigGui(){
return true;
}
@Override
public GuiScreen createConfigGui(GuiScreen parentScreen){
return new GuiConfigWizardry(parentScreen);
}
}
@@ -1,10 +1,5 @@
package electroblob.wizardry;
import cpw.mods.fml.common.network.IGuiHandler;
import electroblob.wizardry.client.GuiArcaneWorkbench;
import electroblob.wizardry.client.GuiPortableCrafting;
import electroblob.wizardry.client.GuiSpellBook;
import electroblob.wizardry.client.GuiWizardHandbook;
import electroblob.wizardry.item.ItemSpellBook;
import electroblob.wizardry.item.ItemWizardHandbook;
import electroblob.wizardry.spell.Spell;
@@ -13,50 +8,52 @@ import electroblob.wizardry.tileentity.ContainerPortableWorkbench;
import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.IGuiHandler;
public class WizardryGuiHandler implements IGuiHandler {
/** Incrementable index for the gui ID */
private static int nextGuiId = 0;
public static final int SPELL_BOOK = nextGuiId++;
public static final int ARCANE_WORKBENCH = nextGuiId++;
public static final int WIZARD_HANDBOOK = nextGuiId++;
public static final int PORTABLE_CRAFTING = nextGuiId++;
@Override
public Object getServerGuiElement(int id, EntityPlayer player, World world,
int x, int y, int z) {
public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z){
if(id == ARCANE_WORKBENCH){
TileEntity tileEntity = world.getTileEntity(x, y, z);
TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z));
if(tileEntity instanceof TileEntityArcaneWorkbench){
return new ContainerArcaneWorkbench(player.inventory, (TileEntityArcaneWorkbench) tileEntity);
return new ContainerArcaneWorkbench(player.inventory, (TileEntityArcaneWorkbench)tileEntity);
}
}
else if(id == PORTABLE_CRAFTING){
return new ContainerPortableWorkbench(player.inventory, world, x, y, z);
}else if(id == PORTABLE_CRAFTING){
return new ContainerPortableWorkbench(player.inventory, world, new BlockPos(x, y, z));
}
return null;
}
@Override
public Object getClientGuiElement(int id, EntityPlayer player, World world,
int x, int y, int z) {
public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z){
if(id == ARCANE_WORKBENCH){
TileEntity tileEntity = world.getTileEntity(x, y, z);
TileEntity tileEntity = world.getTileEntity(new BlockPos(x, y, z));
if(tileEntity instanceof TileEntityArcaneWorkbench){
return new GuiArcaneWorkbench(player.inventory, (TileEntityArcaneWorkbench) tileEntity);
return new electroblob.wizardry.client.GuiArcaneWorkbench(player.inventory,
(TileEntityArcaneWorkbench)tileEntity);
}
}
else if(id == WIZARD_HANDBOOK && player.getHeldItem().getItem() instanceof ItemWizardHandbook){
return new GuiWizardHandbook();
}
else if(id == SPELL_BOOK && player.getHeldItem().getItem() instanceof ItemSpellBook){
return new GuiSpellBook(Spell.get(player.getHeldItem().getItemDamage()));
}
else if(id == PORTABLE_CRAFTING){
return new GuiPortableCrafting(player.inventory, world, x, y, z);
}else if(id == WIZARD_HANDBOOK && (player.getHeldItemMainhand().getItem() instanceof ItemWizardHandbook
|| player.getHeldItemOffhand().getItem() instanceof ItemWizardHandbook)){
return new electroblob.wizardry.client.GuiWizardHandbook();
}else if(id == SPELL_BOOK){
if(player.getHeldItemMainhand().getItem() instanceof ItemSpellBook){
return new electroblob.wizardry.client.GuiSpellBook(Spell.get(player.getHeldItemMainhand().getItemDamage()));
}else if(player.getHeldItemOffhand().getItem() instanceof ItemSpellBook){
return new electroblob.wizardry.client.GuiSpellBook(Spell.get(player.getHeldItemOffhand().getItemDamage()));
}
}else if(id == PORTABLE_CRAFTING){
return new electroblob.wizardry.client.GuiPortableCrafting(player.inventory, world, new BlockPos(x, y, z));
}
return null;
}
@@ -1,69 +0,0 @@
package electroblob.wizardry;
import org.lwjgl.input.Keyboard;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.InputEvent;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import electroblob.wizardry.client.ClientProxy;
import electroblob.wizardry.packet.PacketControlInput;
import electroblob.wizardry.packet.WizardryPacketHandler;
import net.minecraft.client.Minecraft;
public class WizardryKeyHandler {
boolean NkeyPressed = false;
boolean BkeyPressed = false;
boolean NkeyAlreadyPressed = false;
boolean BkeyAlreadyPressed = false;
@SubscribeEvent
public void onKeyInput(InputEvent.KeyInputEvent event) {
// Key pressed
if(Keyboard.getEventKeyState()){
if(Wizardry.proxy instanceof ClientProxy){
ClientProxy proxy = (ClientProxy)Wizardry.proxy;
if(proxy.nextSpell.isPressed() && Minecraft.getMinecraft().inGameHasFocus){
if(!NkeyPressed){
NkeyPressed = true;
}else{
NkeyAlreadyPressed = true;
}
if(!NkeyAlreadyPressed){
// Packet building
IMessage msg = new PacketControlInput.Message(1);
WizardryPacketHandler.net.sendToServer(msg);
}
}
if(proxy.previousSpell.isPressed() && Minecraft.getMinecraft().inGameHasFocus){
if(!BkeyPressed){
BkeyPressed = true;
}else{
BkeyAlreadyPressed = true;
}
if(!BkeyAlreadyPressed){
// Packet building
IMessage msg = new PacketControlInput.Message(2);
WizardryPacketHandler.net.sendToServer(msg);
}
}
}
}
// Key released
else{
if(NkeyPressed){
NkeyPressed = false;
NkeyAlreadyPressed = false;
}else if(BkeyPressed){
BkeyPressed = false;
BkeyAlreadyPressed = false;
}
}
}
}
@@ -1,631 +0,0 @@
package electroblob.wizardry;
import java.util.ArrayList;
import java.util.List;
import cpw.mods.fml.common.registry.EntityRegistry;
import cpw.mods.fml.common.registry.GameRegistry;
import electroblob.wizardry.entity.EntityArc;
import electroblob.wizardry.entity.EntityFallingGrass;
import electroblob.wizardry.entity.EntityMagicSlime;
import electroblob.wizardry.entity.EntityMeteor;
import electroblob.wizardry.entity.EntityShield;
import electroblob.wizardry.entity.construct.EntityArrowRain;
import electroblob.wizardry.entity.construct.EntityBlackHole;
import electroblob.wizardry.entity.construct.EntityBlizzard;
import electroblob.wizardry.entity.construct.EntityBubble;
import electroblob.wizardry.entity.construct.EntityDecay;
import electroblob.wizardry.entity.construct.EntityEarthquake;
import electroblob.wizardry.entity.construct.EntityFireRing;
import electroblob.wizardry.entity.construct.EntityFireSigil;
import electroblob.wizardry.entity.construct.EntityForcefield;
import electroblob.wizardry.entity.construct.EntityFrostSigil;
import electroblob.wizardry.entity.construct.EntityHailstorm;
import electroblob.wizardry.entity.construct.EntityHammer;
import electroblob.wizardry.entity.construct.EntityHealAura;
import electroblob.wizardry.entity.construct.EntityIceSpike;
import electroblob.wizardry.entity.construct.EntityLightningPulse;
import electroblob.wizardry.entity.construct.EntityLightningSigil;
import electroblob.wizardry.entity.construct.EntityTornado;
import electroblob.wizardry.entity.living.EntityBlazeMinion;
import electroblob.wizardry.entity.living.EntityDecoy;
import electroblob.wizardry.entity.living.EntityEvilWizard;
import electroblob.wizardry.entity.living.EntityIceGiant;
import electroblob.wizardry.entity.living.EntityIceWraith;
import electroblob.wizardry.entity.living.EntityLightningWraith;
import electroblob.wizardry.entity.living.EntityPhoenix;
import electroblob.wizardry.entity.living.EntityShadowWraith;
import electroblob.wizardry.entity.living.EntitySilverfishMinion;
import electroblob.wizardry.entity.living.EntitySkeletonMinion;
import electroblob.wizardry.entity.living.EntitySpiderMinion;
import electroblob.wizardry.entity.living.EntitySpiritHorse;
import electroblob.wizardry.entity.living.EntitySpiritWolf;
import electroblob.wizardry.entity.living.EntityStormElemental;
import electroblob.wizardry.entity.living.EntityWizard;
import electroblob.wizardry.entity.living.EntityZombieMinion;
import electroblob.wizardry.entity.projectile.EntityDarknessOrb;
import electroblob.wizardry.entity.projectile.EntityDart;
import electroblob.wizardry.entity.projectile.EntityFirebolt;
import electroblob.wizardry.entity.projectile.EntityFirebomb;
import electroblob.wizardry.entity.projectile.EntityForceArrow;
import electroblob.wizardry.entity.projectile.EntityForceOrb;
import electroblob.wizardry.entity.projectile.EntityIceCharge;
import electroblob.wizardry.entity.projectile.EntityIceLance;
import electroblob.wizardry.entity.projectile.EntityIceShard;
import electroblob.wizardry.entity.projectile.EntityLightningArrow;
import electroblob.wizardry.entity.projectile.EntityLightningDisc;
import electroblob.wizardry.entity.projectile.EntityMagicMissile;
import electroblob.wizardry.entity.projectile.EntityPoisonBomb;
import electroblob.wizardry.entity.projectile.EntitySmokeBomb;
import electroblob.wizardry.entity.projectile.EntitySpark;
import electroblob.wizardry.entity.projectile.EntitySparkBomb;
import electroblob.wizardry.entity.projectile.EntityThunderbolt;
import electroblob.wizardry.spell.*;
import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench;
import electroblob.wizardry.tileentity.TileEntityMagicLight;
import electroblob.wizardry.tileentity.TileEntityPlayerSave;
import electroblob.wizardry.tileentity.TileEntityStatue;
import electroblob.wizardry.tileentity.TileEntityTimer;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.util.WeightedRandomChestContent;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraftforge.common.ChestGenHooks;
import net.minecraftforge.oredict.OreDictionary;
public final class WizardryRegistry {
// Usage note on ChestGenHooks: First number is minimum, second is maximum. Third is rarity, lower numbers are more rare [bread = 100].
// i starts at 1 here so that 'none' does not spawn.
// Earlier problem solved using clever forge hook - extend WeightedRandomChestContent and override generateChestContent.
// Apparently this seems to be incompatible with roguelike dungeons (any others?), in that it generates the same spell book in
// all of the chests that have a spell book in the same dungeon (usually, though it has been known to do different ones on
// different floors). It also appears to be able to generate the 'none' book, which should be impossible... never mind.
// I don't think that's my fault, or I would have seen a 'none' book in a vanilla dungeon by now.
// Another curious observation: Recurrent complex's generators also seem to always generate the same book/wand/armour
// until you restart the game and can generate the 'none' book as well.
// My best guess as to what's happening is that some mods hook into the dungeon loot differently to others, in that
// they take all the WeightedRandomChestContent objects once and pick from them each time rather than making new ones
// for each chest - which is, in theory, a more efficient way of doing things and will speed up world gen a bit, but
// does of course result in custom chest content implementations behaving strangely. The 'none' book thing remains a
// mystery, however.
/** Called from the preInit method in the main mod class to register the custom dungeon loot. */
public static void registerLoot(){
// The generate loot option only applies to vanilla chests, not wizard tower chests.
if(Wizardry.generateLoot){
String[] chestTypes = {
ChestGenHooks.DUNGEON_CHEST,
ChestGenHooks.PYRAMID_JUNGLE_CHEST,
ChestGenHooks.PYRAMID_DESERT_CHEST,
ChestGenHooks.MINESHAFT_CORRIDOR,
ChestGenHooks.STRONGHOLD_CORRIDOR,
ChestGenHooks.STRONGHOLD_CROSSING,
ChestGenHooks.STRONGHOLD_LIBRARY
};
for(String chest : chestTypes){
ChestGenHooks.addItem(chest, new WeightedRandomSpellBook(new ItemStack(Wizardry.spellBook), 1, 1, Wizardry.SPELL_BOOK_FREQUENCY));
ChestGenHooks.addItem(chest, new WeightedRandomSpellBook(new ItemStack(Wizardry.magicWand), 1, 1, Wizardry.WAND_FREQUENCY));
ChestGenHooks.addItem(chest, new WeightedRandomSpellBook(new ItemStack(Wizardry.wizardHat), 1, 1, Wizardry.ARMOUR_FREQUENCY));
ChestGenHooks.addItem(chest, new WeightedRandomSpellBook(new ItemStack(Wizardry.scroll), 1, 1, Wizardry.SCROLL_FREQUENCY));
ChestGenHooks.addItem(chest, new WeightedRandomSpellBook(new ItemStack(Wizardry.condenserUpgrade), 1, 1, Wizardry.WAND_UPGRADE_FREQUENCY));
ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.magicCrystal), 1, 4, Wizardry.CRYSTAL_FREQUENCY));
ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.arcaneTome, 1, 1), 1, 1, Wizardry.APPRENTICE_TOME_FREQUENCY));
ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.arcaneTome, 1, 2), 1, 1, Wizardry.ADVANCED_TOME_FREQUENCY));
ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.arcaneTome, 1, 3), 1, 1, Wizardry.MASTER_TOME_FREQUENCY));
ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.armourUpgrade), 1, 1, Wizardry.ARMOUR_UPGRADE_FREQUENCY));
ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.firebomb), 1, 5, Wizardry.FIREBOMB_FREQUENCY));
ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.poisonBomb), 1, 5, Wizardry.POISON_BOMB_FREQUENCY));
ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.smokeBomb), 1, 5, Wizardry.SMOKE_BOMB_FREQUENCY));
if(Wizardry.discoveryMode) ChestGenHooks.addItem(chest, new WeightedRandomChestContent(new ItemStack(Wizardry.identificationScroll), 1, 1, Wizardry.IDENTIFICATION_SCROLL_FREQUENCY));
}
}
// Creates a new ChestGenHooks for wizard towers.
ChestGenHooks chestGen = ChestGenHooks.getInfo(WizardryWorldGenerator.WIZARD_TOWER);
chestGen.setMax(7);
chestGen.setMin(3);
// Wizard tower chests use exactly the same things, minus the firebombs, poison bombs and smoke bombs
ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomSpellBook(new ItemStack(Wizardry.spellBook), 1, 1, Wizardry.SPELL_BOOK_FREQUENCY));
ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomSpellBook(new ItemStack(Wizardry.magicWand), 1, 1, Wizardry.WAND_FREQUENCY));
ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomSpellBook(new ItemStack(Wizardry.wizardHat), 1, 1, Wizardry.ARMOUR_FREQUENCY));
ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomSpellBook(new ItemStack(Wizardry.scroll), 1, 1, Wizardry.SCROLL_FREQUENCY));
ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomSpellBook(new ItemStack(Wizardry.condenserUpgrade), 1, 1, Wizardry.WAND_UPGRADE_FREQUENCY));
ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomChestContent(new ItemStack(Wizardry.magicCrystal), 1, 4, Wizardry.CRYSTAL_FREQUENCY));
ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomChestContent(new ItemStack(Wizardry.arcaneTome, 1, 1), 1, 1, Wizardry.APPRENTICE_TOME_FREQUENCY));
ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomChestContent(new ItemStack(Wizardry.arcaneTome, 1, 2), 1, 1, Wizardry.ADVANCED_TOME_FREQUENCY));
ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomChestContent(new ItemStack(Wizardry.arcaneTome, 1, 3), 1, 1, Wizardry.MASTER_TOME_FREQUENCY));
ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomChestContent(new ItemStack(Wizardry.armourUpgrade), 1, 1, Wizardry.ARMOUR_UPGRADE_FREQUENCY));
if(Wizardry.discoveryMode) ChestGenHooks.addItem(WizardryWorldGenerator.WIZARD_TOWER, new WeightedRandomChestContent(new ItemStack(Wizardry.identificationScroll), 1, 1, Wizardry.IDENTIFICATION_SCROLL_FREQUENCY));
}
/* The name defined here in the regitry is the one Minecraft uses in game for commands like /give, as
* opposed to the one defined earlier with setBlockName() or setUnlocalizedName() which is the one used by
* the lang files. Ideally these should both be the same, but I've written the lang file now, so... */
/** Called from the preInit method in the main mod class to register all the blocks. */
public static void registerBlocks(){
GameRegistry.registerBlock(Wizardry.arcaneWorkbench, "arcane_workbench");
GameRegistry.registerBlock(Wizardry.crystalOre, "crystal_ore");
GameRegistry.registerBlock(Wizardry.petrifiedStone, "petrified_stone");
GameRegistry.registerBlock(Wizardry.iceStatue, "ice_statue");
GameRegistry.registerBlock(Wizardry.magicLight, "magic_light");
GameRegistry.registerBlock(Wizardry.crystalFlower, "crystal_flower");
GameRegistry.registerBlock(Wizardry.snare, "snare");
GameRegistry.registerBlock(Wizardry.transportationStone, "transportation_stone");
GameRegistry.registerBlock(Wizardry.spectralBlock, "spectral_block");
GameRegistry.registerBlock(Wizardry.crystalBlock, "crystal_block");
GameRegistry.registerBlock(Wizardry.meteor, "meteor");
GameRegistry.registerBlock(Wizardry.vanishingCobweb, "vanishing_cobweb");
}
/** Called from the preInit method in the main mod class to register all the items. */
public static void registerItems(){
GameRegistry.registerItem(Wizardry.magicCrystal, "magic_crystal");
GameRegistry.registerItem(Wizardry.magicWand, "magic_wand");
GameRegistry.registerItem(Wizardry.apprenticeWand, "apprentice_wand");
GameRegistry.registerItem(Wizardry.advancedWand, "advanced_wand");
GameRegistry.registerItem(Wizardry.masterWand, "master_wand");
GameRegistry.registerItem(Wizardry.spellBook, "spell_book");
GameRegistry.registerItem(Wizardry.arcaneTome, "arcane_tome");
GameRegistry.registerItem(Wizardry.wizardHandbook, "wizard_handbook");
GameRegistry.registerItem(Wizardry.basicFireWand, "basic_fire_wand");
GameRegistry.registerItem(Wizardry.basicIceWand, "basic_ice_wand");
GameRegistry.registerItem(Wizardry.basicLightningWand, "basic_lightning_wand");
GameRegistry.registerItem(Wizardry.basicNecromancyWand, "basic_necromancy_wand");
GameRegistry.registerItem(Wizardry.basicEarthWand, "basic_earth_wand");
GameRegistry.registerItem(Wizardry.basicSorceryWand, "basic_sorcery_wand");
GameRegistry.registerItem(Wizardry.basicHealingWand, "basic_healing_wand");
GameRegistry.registerItem(Wizardry.apprenticeFireWand, "apprentice_fire_wand");
GameRegistry.registerItem(Wizardry.apprenticeIceWand, "apprentice_ice_wand");
GameRegistry.registerItem(Wizardry.apprenticeLightningWand, "apprentice_lightning_wand");
GameRegistry.registerItem(Wizardry.apprenticeNecromancyWand, "apprentice_necromancy_wand");
GameRegistry.registerItem(Wizardry.apprenticeEarthWand, "apprentice_earth_wand");
GameRegistry.registerItem(Wizardry.apprenticeSorceryWand, "apprentice_sorcery_wand");
GameRegistry.registerItem(Wizardry.apprenticeHealingWand, "apprentice_healing_wand");
GameRegistry.registerItem(Wizardry.advancedFireWand, "advanced_fire_wand");
GameRegistry.registerItem(Wizardry.advancedIceWand, "advanced_ice_wand");
GameRegistry.registerItem(Wizardry.advancedLightningWand, "advanced_lightning_wand");
GameRegistry.registerItem(Wizardry.advancedNecromancyWand, "advanced_necromancy_wand");
GameRegistry.registerItem(Wizardry.advancedEarthWand, "advanced_earth_wand");
GameRegistry.registerItem(Wizardry.advancedSorceryWand, "advanced_sorcery_wand");
GameRegistry.registerItem(Wizardry.advancedHealingWand, "advanced_healing_wand");
GameRegistry.registerItem(Wizardry.masterFireWand, "master_fire_wand");
GameRegistry.registerItem(Wizardry.masterIceWand, "master_ice_wand");
GameRegistry.registerItem(Wizardry.masterLightningWand, "master_lightning_wand");
GameRegistry.registerItem(Wizardry.masterNecromancyWand, "master_necromancy_wand");
GameRegistry.registerItem(Wizardry.masterEarthWand, "master_earth_wand");
GameRegistry.registerItem(Wizardry.masterSorceryWand, "master_sorcery_wand");
GameRegistry.registerItem(Wizardry.masterHealingWand, "master_healing_wand");
GameRegistry.registerItem(Wizardry.spectralSword, "spectral_sword");
GameRegistry.registerItem(Wizardry.spectralPickaxe, "spectral_pickaxe");
GameRegistry.registerItem(Wizardry.spectralBow, "spectral_bow");
GameRegistry.registerItem(Wizardry.manaFlask, "mana_flask");
GameRegistry.registerItem(Wizardry.storageUpgrade, "storage_upgrade");
GameRegistry.registerItem(Wizardry.siphonUpgrade, "siphon_upgrade");
GameRegistry.registerItem(Wizardry.condenserUpgrade, "condenser_upgrade");
GameRegistry.registerItem(Wizardry.rangeUpgrade, "range_upgrade");
GameRegistry.registerItem(Wizardry.durationUpgrade, "duration_upgrade");
GameRegistry.registerItem(Wizardry.cooldownUpgrade, "cooldown_upgrade");
GameRegistry.registerItem(Wizardry.blastUpgrade, "blast_upgrade");
GameRegistry.registerItem(Wizardry.attunementUpgrade, "attunement_upgrade");
GameRegistry.registerItem(Wizardry.flamingAxe, "flaming_axe");
GameRegistry.registerItem(Wizardry.frostAxe, "frost_axe");
GameRegistry.registerItem(Wizardry.firebomb, "firebomb");
GameRegistry.registerItem(Wizardry.poisonBomb, "poison_bomb");
GameRegistry.registerItem(Wizardry.blankScroll, "blank_scroll");
GameRegistry.registerItem(Wizardry.scroll, "scroll");
GameRegistry.registerItem(Wizardry.armourUpgrade, "armour_upgrade");
GameRegistry.registerItem(Wizardry.magicSilk, "magic_silk");
GameRegistry.registerItem(Wizardry.wizardHat, "wizard_hat");
GameRegistry.registerItem(Wizardry.wizardRobe, "wizard_robe");
GameRegistry.registerItem(Wizardry.wizardLeggings, "wizard_leggings");
GameRegistry.registerItem(Wizardry.wizardBoots, "wizard_boots");
GameRegistry.registerItem(Wizardry.wizardHatFire, "wizard_hat_fire");
GameRegistry.registerItem(Wizardry.wizardRobeFire, "wizard_robe_fire");
GameRegistry.registerItem(Wizardry.wizardLeggingsFire, "wizard_leggings_fire");
GameRegistry.registerItem(Wizardry.wizardBootsFire, "wizard_boots_fire");
GameRegistry.registerItem(Wizardry.wizardHatIce, "wizard_hat_ice");
GameRegistry.registerItem(Wizardry.wizardRobeIce, "wizard_robe_ice");
GameRegistry.registerItem(Wizardry.wizardLeggingsIce, "wizard_leggings_ice");
GameRegistry.registerItem(Wizardry.wizardBootsIce, "wizard_boots_ice");
GameRegistry.registerItem(Wizardry.wizardHatLightning, "wizard_hat_lightning");
GameRegistry.registerItem(Wizardry.wizardRobeLightning, "wizard_robe_lightning");
GameRegistry.registerItem(Wizardry.wizardLeggingsLightning, "wizard_leggings_lightning");
GameRegistry.registerItem(Wizardry.wizardBootsLightning, "wizard_boots_lightning");
GameRegistry.registerItem(Wizardry.wizardHatNecromancy, "wizard_hat_necromancy");
GameRegistry.registerItem(Wizardry.wizardRobeNecromancy, "wizard_robe_necromancy");
GameRegistry.registerItem(Wizardry.wizardLeggingsNecromancy, "wizard_leggings_necromancy");
GameRegistry.registerItem(Wizardry.wizardBootsNecromancy, "wizard_boots_necromancy");
GameRegistry.registerItem(Wizardry.wizardHatEarth, "wizard_hat_earth");
GameRegistry.registerItem(Wizardry.wizardRobeEarth, "wizard_robe_earth");
GameRegistry.registerItem(Wizardry.wizardLeggingsEarth, "wizard_leggings_earth");
GameRegistry.registerItem(Wizardry.wizardBootsEarth, "wizard_boots_earth");
GameRegistry.registerItem(Wizardry.wizardHatSorcery, "wizard_hat_sorcery");
GameRegistry.registerItem(Wizardry.wizardRobeSorcery, "wizard_robe_sorcery");
GameRegistry.registerItem(Wizardry.wizardLeggingsSorcery, "wizard_leggings_sorcery");
GameRegistry.registerItem(Wizardry.wizardBootsSorcery, "wizard_boots_sorcery");
GameRegistry.registerItem(Wizardry.wizardHatHealing, "wizard_hat_healing");
GameRegistry.registerItem(Wizardry.wizardRobeHealing, "wizard_robe_healing");
GameRegistry.registerItem(Wizardry.wizardLeggingsHealing, "wizard_leggings_healing");
GameRegistry.registerItem(Wizardry.wizardBootsHealing, "wizard_boots_healing");
GameRegistry.registerItem(Wizardry.spawnWizard, "spawn_wizard");
GameRegistry.registerItem(Wizardry.spectralHelmet, "spectral_helmet");
GameRegistry.registerItem(Wizardry.spectralChestplate, "spectral_chestplate");
GameRegistry.registerItem(Wizardry.spectralLeggings, "spectral_leggings");
GameRegistry.registerItem(Wizardry.spectralBoots, "spectral_boots");
GameRegistry.registerItem(Wizardry.smokeBomb, "smoke_bomb");
GameRegistry.registerItem(Wizardry.identificationScroll, "identification_scroll");
}
/** Called from the preInit method in the main mod class to register all the tileentities. */
public static void registerTileEntities(){
GameRegistry.registerTileEntity(TileEntityArcaneWorkbench.class, Wizardry.MODID + "ArcaneWorkbenchTileEntity");
GameRegistry.registerTileEntity(TileEntityStatue.class, Wizardry.MODID + "PetrifiedStoneTileEntity");
GameRegistry.registerTileEntity(TileEntityMagicLight.class, Wizardry.MODID + "MagicLightTileEntity");
GameRegistry.registerTileEntity(TileEntityTimer.class, Wizardry.MODID + "TimerTileEntity");
GameRegistry.registerTileEntity(TileEntityPlayerSave.class, Wizardry.MODID + "TileEntityPlayerSave");
}
/** Called from the preInit method in the main mod class to register all the entities. */
public static void registerEntities(Wizardry wizardry){
int id = 0; // Incrementable index for the mod specific entity id.
EntityRegistry.registerModEntity(EntityZombieMinion.class, "Zombie Minion", id++, wizardry, 128, 3, true);
EntityRegistry.registerModEntity(EntityMagicMissile.class, "Magic Missile", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityArc.class, "Arc", id++, wizardry, 128, 10, false);
EntityRegistry.registerModEntity(EntitySkeletonMinion.class, "Skeleton Minion", id++, wizardry, 128, 3, true);
EntityRegistry.registerModEntity(EntitySparkBomb.class, "Spark Bomb", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntitySpiritWolf.class, "Spirit Wolf", id++, wizardry, 128, 3, true);
EntityRegistry.registerModEntity(EntityIceShard.class, "Ice Shard", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityBlazeMinion.class, "Blaze Minion", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityIceWraith.class, "Ice Wraith", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityLightningWraith.class, "Lightning Wraith", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityBlackHole.class, "Black Hole", id++, wizardry, 128, 10, false);
EntityRegistry.registerModEntity(EntityShield.class, "Shield", id++, wizardry, 128, 1, true);
EntityRegistry.registerModEntity(EntityMeteor.class, "Meteor", id++, wizardry, 128, 5, true);
EntityRegistry.registerModEntity(EntityBlizzard.class, "Blizzard", id++, wizardry, 128, 10, false);
EntityRegistry.registerModEntity(EntityWizard.class, "Wizard", id++, wizardry, 128, 3, true);
EntityRegistry.registerModEntity(EntityBubble.class, "Bubble", id++, wizardry, 128, 3, false);
EntityRegistry.registerModEntity(EntityTornado.class, "Tornado", id++, wizardry, 128, 1, false);
EntityRegistry.registerModEntity(EntityHammer.class, "Lightning Hammer", id++, wizardry, 128, 1, true);
EntityRegistry.registerModEntity(EntityFirebomb.class, "Firebomb", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityForceOrb.class, "Force Orb", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityArrowRain.class, "Arrow Rain", id++, wizardry, 128, 10, false);
EntityRegistry.registerModEntity(EntitySpark.class, "Spark", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityShadowWraith.class, "Shadow Wraith", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityDarknessOrb.class, "Darkness Orb", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntitySpiderMinion.class, "Spider Minion", id++, wizardry, 128, 3, true);
EntityRegistry.registerModEntity(EntityHealAura.class, "Healing Aura", id++, wizardry, 128, 10, false);
EntityRegistry.registerModEntity(EntityFireSigil.class, "Fire Sigil", id++, wizardry, 128, 10, false);
EntityRegistry.registerModEntity(EntityFrostSigil.class, "Frost Sigil", id++, wizardry, 128, 10, false);
EntityRegistry.registerModEntity(EntityLightningSigil.class, "Lightning Sigil", id++, wizardry, 128, 10, false);
EntityRegistry.registerModEntity(EntityLightningArrow.class, "Lightning Arrow", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityFirebolt.class, "Firebolt", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityPoisonBomb.class, "Poison Bomb", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityIceCharge.class, "Ice Charge", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityForceArrow.class, "Force Arrow", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityDart.class, "Dart", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityMagicSlime.class, "Magic Slime", id++, wizardry, 128, 3, true);
EntityRegistry.registerModEntity(EntityForcefield.class, "Forcefield", id++, wizardry, 128, 10, false);
EntityRegistry.registerModEntity(EntityFireRing.class, "Ring of Fire", id++, wizardry, 128, 10, false);
EntityRegistry.registerModEntity(EntityLightningDisc.class, "Lightning Disc", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityThunderbolt.class, "Thunderbolt", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityIceGiant.class, "Ice Giant", id++, wizardry, 128, 3, true);
EntityRegistry.registerModEntity(EntitySpiritHorse.class, "Spirit Horse", id++, wizardry, 128, 3, true);
EntityRegistry.registerModEntity(EntityPhoenix.class, "Phoenix", id++, wizardry, 128, 3, true);
EntityRegistry.registerModEntity(EntitySilverfishMinion.class, "Silverfish Minion", id++, wizardry, 128, 3, true);
EntityRegistry.registerModEntity(EntityDecay.class, "Decay", id++, wizardry, 128, 10, false);
EntityRegistry.registerModEntity(EntityStormElemental.class, "Storm Elemental", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityEarthquake.class, "Earthquake", id++, wizardry, 128, 10, false);
EntityRegistry.registerModEntity(EntityFallingGrass.class, "Falling Grass", id++, wizardry, 128, 5, true);
EntityRegistry.registerModEntity(EntityIceLance.class, "Ice Lance", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityHailstorm.class, "Hailstorm", id++, wizardry, 128, 10, false);
EntityRegistry.registerModEntity(EntitySmokeBomb.class, "Smoke Bomb", id++, wizardry, 128, 10, true);
EntityRegistry.registerModEntity(EntityEvilWizard.class, "Evil Wizard", id++, wizardry, 128, 3, true);
EntityRegistry.registerModEntity(EntityDecoy.class, "Decoy", id++, wizardry, 128, 3, true);
EntityRegistry.registerModEntity(EntityIceSpike.class, "Ice Spike", id++, wizardry, 128, 1, true);
EntityRegistry.registerModEntity(EntityLightningPulse.class, "Lightning Pulse", id++, wizardry, 128, 10, false);
List<BiomeGenBase> biomes = new ArrayList<BiomeGenBase>();
for(BiomeGenBase biome : BiomeGenBase.getBiomeGenArray()){
if(biome != null){
biomes.add(biome);
}
}
// For reference: 5, 1, 1 are the parameters for the witch in vanilla.
EntityRegistry.addSpawn(EntityEvilWizard.class, 3, 1, 1, EnumCreatureType.monster, biomes.toArray(new BiomeGenBase[biomes.size()]));
}
/** Static instance of the none spell, used for various purposes. */
public static Spell none;
/** Static instance of the magic missile spell, used for crafting spell books and by wizards. */
public static Spell magicMissile;
/** Static instance of the transportation spell, used for chat messages. */
public static Spell transportation;
/** Static instance of the clairvoyance spell, used for chat messages. */
public static Spell clairvoyance;
/** Called from the preInit method in the main mod class to register all the spells in wizardry. */
public static void registerSpells(){
// Wizardry 1.0 spells
Spell.register(none = new None());
Spell.register(magicMissile = new MagicMissile());
Spell.register(new Ignite());
Spell.register(new Freeze());
Spell.register(new Snowball());
Spell.register(new Arc());
Spell.register(new Thunderbolt());
Spell.register(new SummonZombie());
Spell.register(new Snare());
Spell.register(new Dart());
Spell.register(new Light());
Spell.register(new Telekinesis());
Spell.register(new Heal());
Spell.register(new Fireball());
Spell.register(new FlameRay());
Spell.register(new Firebomb());
Spell.register(new FireSigil());
Spell.register(new Firebolt());
Spell.register(new FrostRay());
Spell.register(new SummonSnowGolem());
Spell.register(new IceShard());
Spell.register(new IceStatue());
Spell.register(new FrostSigil());
Spell.register(new LightningRay());
Spell.register(new SparkBomb());
Spell.register(new HomingSpark());
Spell.register(new LightningSigil());
Spell.register(new LightningArrow());
Spell.register(new LifeDrain());
Spell.register(new SummonSkeleton());
Spell.register(new Metamorphosis());
Spell.register(new Wither());
Spell.register(new Poison());
Spell.register(new GrowthAura());
Spell.register(new Bubble());
Spell.register(new Whirlwind());
Spell.register(new PoisonBomb());
Spell.register(new SummonSpiritWolf());
Spell.register(new Blink());
Spell.register(new Agility());
Spell.register(new ConjureSword());
Spell.register(new ConjurePickaxe());
Spell.register(new ConjureBow());
Spell.register(new ForceArrow());
Spell.register(new Shield());
Spell.register(new ReplenishHunger());
Spell.register(new CureEffects());
Spell.register(new HealAlly());
Spell.register(new SummonBlaze());
Spell.register(new RingOfFire());
Spell.register(new Detonate());
Spell.register(new FireResistance());
Spell.register(new Fireskin());
Spell.register(new FlamingAxe());
Spell.register(new Blizzard());
Spell.register(new SummonIceWraith());
Spell.register(new IceShroud());
Spell.register(new IceCharge());
Spell.register(new FrostAxe());
Spell.register(new InvokeWeather());
Spell.register(new ChainLightning());
Spell.register(new LightningBolt());
Spell.register(new SummonLightningWraith());
Spell.register(new StaticAura());
Spell.register(new LightningDisc());
Spell.register(new MindControl());
Spell.register(new SummonWitherSkeleton());
Spell.register(new Entrapment());
Spell.register(new WitherSkull());
Spell.register(new DarknessOrb());
Spell.register(new ShadowWard());
Spell.register(new Decay());
Spell.register(new WaterBreathing());
Spell.register(new Tornado());
Spell.register(new Glide());
Spell.register(new SummonSpiritHorse());
Spell.register(new SpiderSwarm());
Spell.register(new Slime());
Spell.register(new Petrify());
Spell.register(new Invisibility());
Spell.register(new Levitation());
Spell.register(new ForceOrb());
Spell.register(transportation = new Transportation());
Spell.register(new SpectralPathway());
Spell.register(new PhaseStep());
Spell.register(new VanishingBox());
Spell.register(new GreaterHeal());
Spell.register(new HealingAura());
Spell.register(new Forcefield());
Spell.register(new Ironflesh());
Spell.register(new Transience());
Spell.register(new Meteor());
Spell.register(new Firestorm());
Spell.register(new SummonPhoenix());
Spell.register(new IceAge());
Spell.register(new WallOfFrost());
Spell.register(new SummonIceGiant());
Spell.register(new Thunderstorm());
Spell.register(new LightningHammer());
Spell.register(new PlagueOfDarkness());
Spell.register(new SummonSkeletonLegion());
Spell.register(new SummonShadowWraith());
Spell.register(new ForestsCurse());
Spell.register(new Flight());
Spell.register(new SilverfishSwarm());
Spell.register(new BlackHole());
Spell.register(new Shockwave());
Spell.register(new SummonIronGolem());
Spell.register(new ArrowRain());
Spell.register(new Diamondflesh());
Spell.register(new FontOfVitality());
// Wizardry 1.1 spells
Spell.register(new SmokeBomb());
Spell.register(new MindTrick());
Spell.register(new Leap());
Spell.register(new PocketFurnace());
Spell.register(new Intimidate());
Spell.register(new Banish());
Spell.register(new SixthSense());
Spell.register(new Darkvision());
Spell.register(clairvoyance = new Clairvoyance());
Spell.register(new PocketWorkbench());
Spell.register(new ImbueWeapon());
Spell.register(new InvigoratingPresence());
Spell.register(new Oakflesh());
Spell.register(new GreaterFireball());
Spell.register(new FlamingWeapon());
Spell.register(new IceLance());
Spell.register(new FreezingWeapon());
Spell.register(new IceSpikes());
Spell.register(new LightningPulse());
Spell.register(new CurseOfSoulbinding());
Spell.register(new Cobwebs());
Spell.register(new Decoy());
Spell.register(new ArcaneJammer());
Spell.register(new ConjureArmour());
Spell.register(new GroupHeal());
Spell.register(new Hailstorm());
Spell.register(new LightningWeb());
Spell.register(new SummonStormElemental());
Spell.register(new Earthquake());
Spell.register(new FontOfMana());
}
/** Called from the init method in the main mod class to register all the recipes. */
public static void registerRecipes(){
ItemStack ironIngotStack = new ItemStack(Items.iron_ingot);
ItemStack magicCrystalStack = new ItemStack(Wizardry.magicCrystal);
ItemStack magicWandStack = new ItemStack(Wizardry.magicWand, 1, EnumTier.BASIC.maxCharge);
ItemStack goldNuggetStack = new ItemStack(Items.gold_nugget);
ItemStack stickStack = new ItemStack(Items.stick);
ItemStack bookStack = new ItemStack(Items.book);
ItemStack stringStack = new ItemStack(Items.string);
ItemStack spellBookStack = new ItemStack(Wizardry.spellBook, 1, WizardryRegistry.magicMissile.id());
ItemStack arcaneWorkbenchStack = new ItemStack(Wizardry.arcaneWorkbench);
ItemStack stoneStack = new ItemStack(Blocks.stone);
ItemStack lapisBlockStack = new ItemStack(Blocks.lapis_block);
ItemStack purpleCarpetStack = new ItemStack(Blocks.carpet, 1, 10);
ItemStack wizardHandbookStack = new ItemStack(Wizardry.wizardHandbook);
ItemStack crystalFlowerStack = new ItemStack(Wizardry.crystalFlower);
ItemStack magicCrystalStack1 = new ItemStack(Wizardry.magicCrystal, 2);
ItemStack magicCrystalStack2 = new ItemStack(Wizardry.magicCrystal, 9);
ItemStack crystalBlockStack = new ItemStack(Wizardry.crystalBlock);
ItemStack manaFlaskStack = new ItemStack(Wizardry.manaFlask);
ItemStack bottleStack = new ItemStack(Items.glass_bottle);
ItemStack gunpowderStack = new ItemStack(Items.gunpowder);
ItemStack blazePowderStack = new ItemStack(Items.blaze_powder);
ItemStack spiderEyeStack = new ItemStack(Items.spider_eye);
// Coal or charcoal is equally fine, hence the wildcard value
ItemStack coalStack = new ItemStack(Items.coal, 1, OreDictionary.WILDCARD_VALUE);
ItemStack firebombStack = new ItemStack(Wizardry.firebomb, 3);
ItemStack poisonBombStack = new ItemStack(Wizardry.poisonBomb, 3);
ItemStack smokeBombStack = new ItemStack(Wizardry.smokeBomb, 3);
ItemStack transportationStoneStack = new ItemStack(Wizardry.transportationStone, 2);
ItemStack silkStack = new ItemStack(Wizardry.magicSilk);
ItemStack silkStack1 = new ItemStack(Wizardry.magicSilk, 2);
ItemStack hatStack = new ItemStack(Wizardry.wizardHat);
ItemStack robeStack = new ItemStack(Wizardry.wizardRobe);
ItemStack leggingsStack = new ItemStack(Wizardry.wizardLeggings);
ItemStack bootsStack = new ItemStack(Wizardry.wizardBoots);
ItemStack scrollStack = new ItemStack(Wizardry.blankScroll);
ItemStack paperStack = new ItemStack(Items.paper);
GameRegistry.addRecipe(magicWandStack, " x", " y ", "z ", 'x', magicCrystalStack, 'y', stickStack, 'z', goldNuggetStack);
GameRegistry.addRecipe(spellBookStack, " x ", "xyx", " x ", 'x', magicCrystalStack, 'y', bookStack);
GameRegistry.addRecipe(arcaneWorkbenchStack, "vwv", "xyx", "zzz", 'v', goldNuggetStack, 'w', purpleCarpetStack, 'x', magicCrystalStack, 'y', lapisBlockStack, 'z', stoneStack);
GameRegistry.addRecipe(manaFlaskStack, "yyy", "yxy", "yyy", 'x', bottleStack, 'y', magicCrystalStack);
GameRegistry.addRecipe(transportationStoneStack, " x ", "xyx", " x ", 'x', stoneStack, 'y', magicCrystalStack);
GameRegistry.addRecipe(hatStack, "yyy", "y y", 'y', silkStack);
GameRegistry.addRecipe(robeStack, "y y", "yyy", "yyy", 'y', silkStack);
GameRegistry.addRecipe(leggingsStack, "yyy", "y y", "y y", 'y', silkStack);
GameRegistry.addRecipe(bootsStack, "y y", "y y", 'y', silkStack);
GameRegistry.addRecipe(silkStack1, " x ", "xyx", " x ", 'x', stringStack, 'y', magicCrystalStack);
GameRegistry.addRecipe(crystalBlockStack, "zzz", "zzz", "zzz", 'z', magicCrystalStack);
GameRegistry.addShapelessRecipe(wizardHandbookStack, bookStack, magicCrystalStack);
GameRegistry.addShapelessRecipe(magicCrystalStack1, crystalFlowerStack);
GameRegistry.addShapelessRecipe(magicCrystalStack2, crystalBlockStack);
if(Wizardry.firebombIsCraftable) GameRegistry.addShapelessRecipe(firebombStack, bottleStack, gunpowderStack, blazePowderStack, blazePowderStack);
if(Wizardry.poisonBombIsCraftable) GameRegistry.addShapelessRecipe(poisonBombStack, bottleStack, gunpowderStack, spiderEyeStack, spiderEyeStack);
if(Wizardry.smokeBombIsCraftable) GameRegistry.addShapelessRecipe(smokeBombStack, bottleStack, gunpowderStack, coalStack, coalStack);
if(Wizardry.useAlternateScrollRecipe){
GameRegistry.addShapelessRecipe(scrollStack, paperStack, stringStack, magicCrystalStack);
}else{
GameRegistry.addShapelessRecipe(scrollStack, paperStack, stringStack);
}
// Mana flask recipes
ItemStack miscWandStack;
for(int i=0; i<EnumElement.values().length; i++){
for(int j=0; j<EnumTier.values().length; j++){
miscWandStack = new ItemStack(WizardryUtilities.getWand(EnumTier.values()[j], EnumElement.values()[i]), 1, OreDictionary.WILDCARD_VALUE);
GameRegistry.addShapelessRecipe(miscWandStack, miscWandStack, manaFlaskStack);
}
}
ItemStack miscArmourStack;
for(int i=0; i<EnumElement.values().length; i++){
for(int j=0; j<4; j++){
miscArmourStack = new ItemStack(WizardryUtilities.getArmour(EnumElement.values()[i], j), 1, OreDictionary.WILDCARD_VALUE);
GameRegistry.addShapelessRecipe(miscArmourStack, miscArmourStack, manaFlaskStack);
}
}
}
}
@@ -1,881 +0,0 @@
package electroblob.wizardry;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import cpw.mods.fml.common.registry.EntityRegistry;
import electroblob.wizardry.entity.living.EntitySummonedCreature;
import electroblob.wizardry.entity.living.EntityWizard;
import electroblob.wizardry.spell.MindControl;
import electroblob.wizardry.spell.Spell;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.command.IEntitySelector;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityList.EntityEggInfo;
import net.minecraft.entity.monster.IMob;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.Potion;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
/** This class contains some useful static methods for use anywhere - items, entities, spells, events, blocks, etc.
* @see CommonProxy
* @see WandHelper
* @since Wizardry 1.0 */
public final class WizardryUtilities {
/**
* Finds the nearest floor level to the given y coord within the range specified at the given x and z coords.
* Liquids and other blocks that cannot be built on top of do not count, but stuff like signs does.
* (Technically any block is allowed to be the floor according to the code, but seeing as it searches upwards and
* non-solid blocks usually need a supporting block, the floor is likely to always be solid).
* @param world
* @param x The x coordinate to search in
* @param y The y coordinate to search from
* @param z The z coordinate to search in
* @param range The maximum distance from the given y coordinate to search.
* @return The y coordinate of the closest floor level, or -1 if there is none. Returns the actual level of the floor
* as would be seen in the debug screen when the player is standing on it.
* @see WizardryUtilities#getNearestFloorLevelB(World, int, int, int, int)
*/
public static int getNearestFloorLevel(World world, int x, int y, int z, int range){
int yCoord = -2;
for(int i=y-range;i<=y+range;i++){
// The last bit determines whether the block found to be a suitable floor is closer than the previous one found.
// Edit: Changed the first condition from blockExists() since that method includes air blocks!
if(world.doesBlockHaveSolidTopSurface(world, x, i, z) && (world.isAirBlock(x, i+1, z) || !world.doesBlockHaveSolidTopSurface(world, x, i+1, z))
&& (i-y < yCoord-y || yCoord == -2)){
yCoord = i;
}
}
return yCoord + 1;
}
/**
* Returns whether the block at the given coordinates can be replaced by another one (works as if a block is being placed by a player).
* True for air, liquids, vines, tall grass and snow layers but not for flowers, signs etc.
* This is a shortcut for world.getBlock(x, y, z).isReplaceable(world, x, y, z);
* Not much of a shortcut any more, since block ids have been phased out.
* @see WizardryUtilities#canBlockBeReplacedB(World, int, int, int)
*/
public static boolean canBlockBeReplaced(World world, int x, int y, int z){
// Why does isReplaceable have those arguments? I don't know. They aren't used. It's probably for overriding
// stuff in case these arguments affect whether it is replaceable or not. It is a forge method, after all.
return world.isAirBlock(x, y, z) || world.getBlock(x, y, z).isReplaceable(world, x, y, z);
}
/**
* Returns whether the block at the given coordinates can be replaced by another one (works as if a block is being placed by a player)
* and is not a liquid.
* True for air, vines, tall grass and snow layers but not for flowers, signs etc. or any liquids.
* @see WizardryUtilities#canBlockBeReplaced(World, int, int, int)
*/
public static boolean canBlockBeReplacedB(World world, int x, int y, int z){
return (world.isAirBlock(x, y, z) || world.getBlock(x, y, z).isReplaceable(world, x, y, z)) && !world.getBlock(x, y, z).getMaterial().isLiquid();
}
/**
* Returns whether the block at the given coordinates is unbreakable in survival mode. In vanilla this is true for
* bedrock and end portal frame, for example.
* This is a shortcut for world.getBlockId(x, y, z).getBlockHardness == -1.0f;
* Not much of a shortcut any more, since block ids have been phased out.
*/
public static boolean isBlockUnbreakable(World world, int x, int y, int z){
return world.isAirBlock(x, y, z) ? false : world.getBlock(x, y, z).getBlockHardness(world, x, y, z) == -1.0f;
}
/**
* Finds the nearest floor level to the given y coord within the range specified at the given x and z coords.
* Only works if the block above the floor is actually air and the floor is solid or a liquid.
* @param world
* @param x The x coordinate to search in
* @param y The y coordinate to search from
* @param z The z coordinate to search in
* @param range The maximum distance from the given y coordinate to search.
* @return The y coordinate of the closest floor level, or -1 if there is none. Returns the actual level of the floor
* as would be seen in the debug screen when the player is standing on it.
* @see WizardryUtilities#getNearestFloorLevel(World, int, int, int, int)
*/
public static int getNearestFloorLevelB(World world, int x, int y, int z, int range){
int yCoord = -2;
for(int i=y-range;i<=y+range;i++){
if(world.isAirBlock(x, i+1, z) && (world.getBlock(x, i, z).getMaterial().isLiquid() || world.doesBlockHaveSolidTopSurface(world, x, i, z))
&& (i-y < yCoord-y || yCoord == -2)){
// The last bit determines whether the block found to be a suitable floor is closer than the previous one found.
yCoord = i;
}
}
return yCoord + 1;
}
/**
* Finds the nearest floor level to the given y coord within the range specified at the given x and z coords.
* Everything that is not air is treated as floor, even stuff that can't be walked on.
* @param world
* @param x The x coordinate to search in
* @param y The y coordinate to search from
* @param z The z coordinate to search in
* @param range The maximum distance from the given y coordinate to search.
* @return The y coordinate of the closest floor level, or -1 if there is none. Returns the actual level of the floor
* as would be seen in the debug screen when the player is standing on it.
* @see WizardryUtilities#getNearestFloorLevel(World, int, int, int, int)
*/
public static int getNearestFloorLevelC(World world, int x, int y, int z, int range){
int yCoord = -2;
for(int i=y-range;i<=y+range;i++){
if(world.isAirBlock(x, i+1, z) && (i-y < yCoord-y || yCoord == -2)){
// The last bit determines whether the block found to be a suitable floor is closer than the previous one found.
yCoord = i;
}
}
return yCoord + 1;
}
/**
* Gets the block the specified entity is standing on. Uses {@link MathHelper#floor_double(double)} because casting to int will not
* return the correct coordinate when x or z is negative.
*/
public static Block getBlockEntityIsStandingOn(Entity entity){
return entity.worldObj.getBlock(MathHelper.floor_double(entity.posX), (int)WizardryUtilities.getEntityFeetPos(entity)-1, MathHelper.floor_double(entity.posZ));
}
/**
* Shorthand for {@link WizardryUtilities#getEntitiesWithinRadius(double, double, double, double, World, Class)}
* with EntityLivingBase as the entity type. This is by far the most common use for that method, which is why this
* shorthand exists.
* @param radius The search radius
* @param x The x coordinate to search around
* @param y The y coordinate to search around
* @param z The z coordinate to search around
* @param world The world to search in
*/
public static List<EntityLivingBase> getEntitiesWithinRadius(double radius, double x, double y, double z, World world){
return getEntitiesWithinRadius(radius, x, y, z, world, EntityLivingBase.class);
}
/**
* Returns all entities of the specified type within the specified radius of the given coordinates. This is different to using
* a raw AABB because a raw AABB will search in a cube volume rather than a sphere.
* Note that this does not exclude any entities; if any specific entities are to be excluded this must be
* checked when iterating through the list.
* @see {@link WizardryUtilities#getEntitiesWithinRadius(double, double, double, double, World)}
* @param radius The search radius
* @param x The x coordinate to search around
* @param y The y coordinate to search around
* @param z The z coordinate to search around
* @param world The world to search in
* @param entityType The class of entity to search for; pass in Entity.class for all entities
*/
public static <T extends Entity> List<T> getEntitiesWithinRadius(double radius, double x, double y, double z, World world, Class<T> entityType){
AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(x - radius, y - radius, z - radius, x + radius, y + radius, z + radius);
List entityList = world.getEntitiesWithinAABB(entityType, aabb);
for(int i=0;i<entityList.size();i++){
if(((Entity)entityList.get(i)).getDistance(x, y, z) > radius){
entityList.remove(i);
}
}
return entityList;
}
// ^ Handy syntax using type parameters here!
// I *think* that eclipse, for whatever reason, was not showing an 'unchecked' warning here. If you think about it,
// if this method returns a generic list type I could, in theory, put strings or something in it and then when
// invoking the method store its result as a List<EntityLivingBase>, which would cause a ClassCastException. Using
// this handy syntax prevents that from happening. TL;DR: Always use type parameters when available, they're there
// for a reason. Minecraft is bad in this respect because it doesn't use them in places like World.
/**
* Gets an entity from its UUID. Note that you should check this isn't null.
* @param world The world the entity is in
* @param id The entity's UUID
* @return The Entity that has the given UUID, or null if no such entity exists in the specified world.
*/
public static Entity getEntityByUUID(World world, UUID id){
for(Object object : world.loadedEntityList){
if(object instanceof Entity){
Entity entity = (Entity)object;
// This is a perfect example of where you need to use .equals() and not ==. For most applications,
// this was unnoticeable until world reload because the UUID instance or entity instance is stored.
// Fixed now though. Of course, you could alternatively compare the string representations.
if(entity.getUniqueID().equals(id)){
return entity;
}
}
}
return null;
}
/**
* Does a block ray trace (NOT entities) from an entity's eyes (i.e. properly...)
*/
public static MovingObjectPosition rayTrace(double range, World world, EntityLivingBase entity, boolean hitLiquids)
{
Vec3 vec3 = Vec3.createVectorHelper(entity.posX, entity.posY + entity.getEyeHeight(), entity.posZ);
Vec3 vec31 = entity.getLookVec();
Vec3 vec32 = vec3.addVector(vec31.xCoord * range, vec31.yCoord * range, vec31.zCoord * range);
return world.rayTraceBlocks(vec3, vec32, hitLiquids);
}
/**
* Helper method which does a rayTrace for entities from an entity's eye level in the direction they are looking
* with a specified range, using the tracePath method. Tidies up the code a bit. Border size defaults to 1.
*
* @param world
* @param entity
* @param range
* @return
*/
public static MovingObjectPosition standardEntityRayTrace(World world, EntityLivingBase entity, double range){
double dx = entity.getLookVec().xCoord * range;
double dy = entity.getLookVec().yCoord * range;
double dz = entity.getLookVec().zCoord * range;
HashSet hashset = new HashSet(1);
hashset.add(entity);
return WizardryUtilities.tracePath(world, (float)entity.posX, (float)(entity.posY + entity.getEyeHeight()), (float)entity.posZ, (float)(entity.posX + dx), (float)(entity.posY + entity.getEyeHeight() + dy), (float)(entity.posZ + dz), 1.0f, hashset, false);
}
/**
* Helper method which does a rayTrace for entities from a entity's eye level in the direction they are looking
* with a specified range and radius, using the tracePath method. Tidies up the code a bit.
*
* @param world
* @param entity
* @param range
* @param borderSize
* @return
*/
public static MovingObjectPosition standardEntityRayTrace(World world, EntityLivingBase entity, double range, float borderSize){
double dx = entity.getLookVec().xCoord * range;
double dy = entity.getLookVec().yCoord * range;
double dz = entity.getLookVec().zCoord * range;
HashSet hashset = new HashSet(1);
hashset.add(entity);
return WizardryUtilities.tracePath(world, (float)entity.posX, (float)(entity.posY + entity.getEyeHeight()), (float)entity.posZ, (float)(entity.posX + dx), (float)(entity.posY + entity.getEyeHeight() + dy), (float)(entity.posZ + dz), borderSize, hashset, false);
}
/**
* Method for ray tracing entities (the useless default method doesn't work, despite EnumHitType having an ENTITY field...)
* You can also use this for seeking.
*
* @param world
* @param x startX
* @param y startY
* @param z startZ
* @param tx endX
* @param ty endY
* @param tz endZ
* @param borderSize extra area to examine around line for entities
* @param excluded any excluded entities (the player, etc)
* @return a MovingObjectPosition of either the block hit (no entity hit), the entity hit (hit an entity), or null for nothing hit
*/
public static MovingObjectPosition tracePath(World world, float x, float y, float z, float tx, float ty, float tz, float borderSize, HashSet<Entity> excluded, boolean collideablesOnly){
Vec3 startVec = Vec3.createVectorHelper(x, y, z);
Vec3 lookVec = Vec3.createVectorHelper(tx-x, ty-y, tz-z);
Vec3 endVec = Vec3.createVectorHelper(tx, ty, tz);
float minX = x < tx ? x : tx;
float minY = y < ty ? y : ty;
float minZ = z < tz ? z : tz;
float maxX = x > tx ? x : tx;
float maxY = y > ty ? y : ty;
float maxZ = z > tz ? z : tz;
AxisAlignedBB bb = AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ).expand(borderSize, borderSize, borderSize);
List<Entity> allEntities = world.getEntitiesWithinAABBExcludingEntity(null, bb);
MovingObjectPosition blockHit = world.rayTraceBlocks(startVec, endVec);
startVec = Vec3.createVectorHelper(x, y, z);
endVec = Vec3.createVectorHelper(tx, ty, tz);
float maxDistance = (float) endVec.distanceTo(startVec);
if(blockHit!=null)
{
maxDistance = (float) blockHit.hitVec.distanceTo(startVec);
}
Entity closestHitEntity = null;
float closestHit = maxDistance;
float currentHit = 0.f;
AxisAlignedBB entityBb;// = ent.getBoundingBox();
MovingObjectPosition intercept;
for(Entity ent : allEntities)
{
if((ent.canBeCollidedWith() || !collideablesOnly) && ((excluded != null && !excluded.contains(ent)) || excluded == null))
{
float entBorder = ent.getCollisionBorderSize();
entityBb = ent.boundingBox;
if(entityBb!=null)
{
entityBb = entityBb.expand(entBorder, entBorder, entBorder);
intercept = entityBb.calculateIntercept(startVec, endVec);
if(intercept!=null)
{
currentHit = (float) intercept.hitVec.distanceTo(startVec);
if(currentHit < closestHit || currentHit==0)
{
closestHit = currentHit;
closestHitEntity = ent;
}
}
}
}
}
if(closestHitEntity!=null)
{
blockHit = new MovingObjectPosition(closestHitEntity);
}
return blockHit;
}
// Just what benefit does having posY be the eye position on the first person client actually give?
/**
* Gets the y coordinate of the given player's eyes. This is to cover an inconsistency between the value of
* EntityPlayer.posY on the first person client and everywhere else; in first person (i.e. when
* Minecraft.getMinecraft().thePlayer == player) player.posY is the eye position, but everywhere else it is the
* feet position. This is intended for use when spawning particles, since this is the only situation where the
* discrepancy is likely to matter.
*/
public static double getPlayerEyesPos(EntityPlayer player){
return Wizardry.proxy.getPlayerEyesPos(player);
}
/**
* Gets the y coordinate of the given entity's feet. This is to cover an inconsistency between the value of
* EntityPlayer.posY on the first person client and everywhere else; in first person (i.e. when
* Minecraft.getMinecraft().thePlayer == player) player.posY is the eye position, but everywhere else it is the
* feet position. This is intended for use when spawning particles, since this is the only situation where the
* discrepancy is likely to matter.
*/
public static double getEntityFeetPos(Entity entity){
if(entity instanceof EntityPlayer){
// For some reason, EntityPlayer.getEyeHeight() always returns 0.12, so I have replicated the behaviour
// of the same method from EntityLivingBase and subtracted that instead.
return getPlayerEyesPos((EntityPlayer)entity) - entity.height*0.85f;
}else{
return entity.posY;
}
}
/**
* Verifies that the given string is a valid string representation of a UUID. More specifically, returns true if and
* only if the given string is not null and matches the regular expression:<p>
* <center><code>/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/<p></code></center>
* which is the regex equivlent of the standard string representation of a UUID as described in {@link UUID#toString()}.
* This method is intended to be used as a check to prevent an {@link IllegalArgumentException} from occurring when
* calling {@link UUID#fromString(String)}.
* @param string The string to be checked
* @return Whether the given string is a valid string representation of a UUID
*/
public static boolean verifyUUIDString(String string){
return string != null && string.matches("/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/");
}
/**
* Returns whether the given target can be attacked by the given attacker. It is up to the caller of this method
* to work out what this means; it doesn't necessarily mean the target is completely immune (for example, revenge
* targeting might reasonably bypass this). This method is intended for use where the damage is indirect and/or
* unavoidable; direct attacks should not check this method. Currently this means the following situations check
* this method:
* <p>
* - AI targeting for summoned creatures<br>
* - AI targeting for mind-controlled creatures<br>
* - Constructs with an area of effect<br>
* - Instantaneous spells with an area of effect around the caster (e.g. forest's curse, thunderstorm)<br>
* - Any lightning chaining effects<br>
* - Any projectiles which seek targets
* <p>
* Also note that the friendly fire option is dealt with
* in the event handler. This method acts as a sort of wrapper for all the ADS stuff in {@link ExtendedPlayer}; more
* details about the ally designation system can be found there.
*
* @param attacker The entity that cast the spell originally
* @param target The entity being attacked
*
* @return False under any of the following circumstances, true otherwise:
* <p>
* - The target is the attacker (this isn't as stupid as it sounds - anything with an AoE might cause this to be
* true, as can summoned creatures)
* <p>
* - The target and the attacker are both players and the target is an ally of the attacker (but the
* attacker need not be an ally of the target)
* <p>
* - The target is a creature that was summoned/controlled by the attacker or by an ally of the attacker.
*/
public static boolean isValidTarget(Entity attacker, Entity target){
// Don't need to check if either entity is null since instanceof does this anyway.
// Tests whether the target is the attacker
if(target == attacker) return false;
// Tests whether the target is a creature that was summoned by the attacker
if(target instanceof EntitySummonedCreature && ((EntitySummonedCreature)target).getCaster() == attacker){
return false;
}
// Tests whether the target is a creature that was mind controlled by the attacker
if(target instanceof EntityLiving && ((EntityLivingBase)target).isPotionActive(Wizardry.mindControl)){
NBTTagCompound entityNBT = target.getEntityData();
if(entityNBT != null && entityNBT.hasKey(MindControl.NBT_KEY)){
if(attacker == WizardryUtilities.getEntityByUUID(target.worldObj, UUID.fromString(entityNBT.getString(MindControl.NBT_KEY)))){
return false;
}
}
}
// Ally section
if(attacker instanceof EntityPlayer && ExtendedPlayer.get((EntityPlayer)attacker) != null){
if(target instanceof EntityPlayer){
// Tests whether the target is an ally of the attacker
if(ExtendedPlayer.get((EntityPlayer)attacker).isPlayerAlly((EntityPlayer)target)){
return false;
}
}else if(target instanceof EntitySummonedCreature){
// Tests whether the target is a creature that was summoned by an ally of the attacker
if(((EntitySummonedCreature)target).getCaster() instanceof EntityPlayer
&& ExtendedPlayer.get((EntityPlayer)attacker).isPlayerAlly((EntityPlayer)((EntitySummonedCreature)target).getCaster())){
return false;
}
}else if(target instanceof EntityLiving && ((EntityLivingBase)target).isPotionActive(Wizardry.mindControl)){
// Tests whether the target is a creature that was mind controlled by an ally of the attacker
NBTTagCompound entityNBT = target.getEntityData();
if(entityNBT != null && entityNBT.hasKey(MindControl.NBT_KEY)){
Entity controller = WizardryUtilities.getEntityByUUID(target.worldObj, UUID.fromString(entityNBT.getString(MindControl.NBT_KEY)));
if(controller instanceof EntityPlayer && ExtendedPlayer.get((EntityPlayer)attacker).isPlayerAlly((EntityPlayer)controller)){
return false;
}
}
}
}
return true;
}
/** Helper method for testing if the second player is an ally of the first player. Makes the code neater. */
public static boolean isPlayerAlly(EntityPlayer allyOf, EntityPlayer possibleAlly) {
ExtendedPlayer properties = ExtendedPlayer.get(allyOf);
if(properties != null && properties.isPlayerAlly(possibleAlly)) return true;
return false;
}
/**
* See {@link WizardryUtilities#getStandardWeightedRandomSpellId(Random, boolean)}. isContinuous defaults to false.
*/
public static int getStandardWeightedRandomSpellId(Random random){
return getStandardWeightedRandomSpellId(random, false);
}
/**
* Helper method which gets a spell id according to the standard weighting. The tier is a weighted random value;
* the actual spell within that tier is completely random. Will not return the id of a spell which has been
* disabled in the config. This is for simple stuff like chests and drops; more complex generators like wizard
* trades don't use this method.
* <p>
* For reference, the standard weighting is as follows:
* Basic: 60%, Apprentice: 25%, Advanced: 10%, Master: 5%
*
* @param random An instance of the Random class
* @param nonContinuous Whether the spells must be non-continuous (used for scrolls)
* @return A random spell id number
*/
public static int getStandardWeightedRandomSpellId(Random random, boolean nonContinuous){
int randomiser = random.nextInt(20);
EnumTier tier;
if(randomiser < 12){
tier = EnumTier.BASIC;
}else if(randomiser < 17){
tier = EnumTier.APPRENTICE;
}else if(randomiser < 19){
tier = EnumTier.ADVANCED;
}else{
tier = EnumTier.MASTER;
}
List<Spell> spells = Spell.getSpells(new Spell.TierElementFilter(tier, null));
if(nonContinuous) spells.retainAll(Spell.getSpells(Spell.nonContinuousSpells));
// Ensures the tier chosen actually has spells in it, and if not uses BASIC instead. BASIC always has at least
// the NONE spell since this spell cannot be disabled.
if(spells.isEmpty()){
spells = Spell.getSpells(new Spell.TierElementFilter(EnumTier.BASIC, null));
if(nonContinuous) spells.retainAll(Spell.getSpells(Spell.nonContinuousSpells));
}
// Finds a random spell in the list and returns its id.
return spells.get(random.nextInt(spells.size())).id();
}
/**
* Helper method to return the appropriate armour item based on element and slot.
* Currently used to iterate through armour for registering charging recipes and for chest generation.
* @param slot 0 = head, 1 = body, 2 = legs, 3 = feet
*/
public static Item getArmour(EnumElement element, int slot){
Item armour = null;
if(element == null){
switch(slot){
case 0:
armour = Wizardry.wizardHat;
break;
case 1:
armour = Wizardry.wizardRobe;
break;
case 2:
armour = Wizardry.wizardLeggings;
break;
case 3:
armour = Wizardry.wizardBoots;
break;
default:
break;
}
}else{
switch(element){
case FIRE:
switch(slot){
case 0:
armour = Wizardry.wizardHatFire;
break;
case 1:
armour = Wizardry.wizardRobeFire;
break;
case 2:
armour = Wizardry.wizardLeggingsFire;
break;
case 3:
armour = Wizardry.wizardBootsFire;
break;
default:
break;
}
break;
case HEALING:
switch(slot){
case 0:
armour = Wizardry.wizardHatHealing;
break;
case 1:
armour = Wizardry.wizardRobeHealing;
break;
case 2:
armour = Wizardry.wizardLeggingsHealing;
break;
case 3:
armour = Wizardry.wizardBootsHealing;
break;
default:
break;
}
break;
case ICE:
switch(slot){
case 0:
armour = Wizardry.wizardHatIce;
break;
case 1:
armour = Wizardry.wizardRobeIce;
break;
case 2:
armour = Wizardry.wizardLeggingsIce;
break;
case 3:
armour = Wizardry.wizardBootsIce;
break;
default:
break;
}
break;
case LIGHTNING:
switch(slot){
case 0:
armour = Wizardry.wizardHatLightning;
break;
case 1:
armour = Wizardry.wizardRobeLightning;
break;
case 2:
armour = Wizardry.wizardLeggingsLightning;
break;
case 3:
armour = Wizardry.wizardBootsLightning;
break;
default:
break;
}
break;
case NECROMANCY:
switch(slot){
case 0:
armour = Wizardry.wizardHatNecromancy;
break;
case 1:
armour = Wizardry.wizardRobeNecromancy;
break;
case 2:
armour = Wizardry.wizardLeggingsNecromancy;
break;
case 3:
armour = Wizardry.wizardBootsNecromancy;
break;
default:
break;
}
break;
case SORCERY:
switch(slot){
case 0:
armour = Wizardry.wizardHatSorcery;
break;
case 1:
armour = Wizardry.wizardRobeSorcery;
break;
case 2:
armour = Wizardry.wizardLeggingsSorcery;
break;
case 3:
armour = Wizardry.wizardBootsSorcery;
break;
default:
break;
}
break;
case EARTH:
switch(slot){
case 0:
armour = Wizardry.wizardHatEarth;
break;
case 1:
armour = Wizardry.wizardRobeEarth;
break;
case 2:
armour = Wizardry.wizardLeggingsEarth;
break;
case 3:
armour = Wizardry.wizardBootsEarth;
break;
default:
break;
}
break;
default:
switch(slot){
case 0:
armour = Wizardry.wizardHat;
break;
case 1:
armour = Wizardry.wizardRobe;
break;
case 2:
armour = Wizardry.wizardLeggings;
break;
case 3:
armour = Wizardry.wizardBoots;
break;
default:
break;
}
break;
}
}
return armour;
}
/**
* Helper method to return the appropriate wand based on tier and element.
* Currently used in the packet handler for upgrading wands, for chest generation and to iterate through
* wands for charging recipes.
*/
public static Item getWand(EnumTier tier, EnumElement element){
Item wand = null;
if(element == null){
switch(tier){
case BASIC:
wand = Wizardry.magicWand;
break;
case APPRENTICE:
wand = Wizardry.apprenticeWand;
break;
case ADVANCED:
wand = Wizardry.advancedWand;
break;
case MASTER:
wand = Wizardry.masterWand;
break;
default:
break;
}
}else{
switch(element){
case FIRE:
switch(tier){
case BASIC:
wand = Wizardry.basicFireWand;
break;
case APPRENTICE:
wand = Wizardry.apprenticeFireWand;
break;
case ADVANCED:
wand = Wizardry.advancedFireWand;
break;
case MASTER:
wand = Wizardry.masterFireWand;
break;
default:
break;
}
break;
case HEALING:
switch(tier){
case BASIC:
wand = Wizardry.basicHealingWand;
break;
case APPRENTICE:
wand = Wizardry.apprenticeHealingWand;
break;
case ADVANCED:
wand = Wizardry.advancedHealingWand;
break;
case MASTER:
wand = Wizardry.masterHealingWand;
break;
default:
break;
}
break;
case ICE:
switch(tier){
case BASIC:
wand = Wizardry.basicIceWand;
break;
case APPRENTICE:
wand = Wizardry.apprenticeIceWand;
break;
case ADVANCED:
wand = Wizardry.advancedIceWand;
break;
case MASTER:
wand = Wizardry.masterIceWand;
break;
default:
break;
}
break;
case LIGHTNING:
switch(tier){
case BASIC:
wand = Wizardry.basicLightningWand;
break;
case APPRENTICE:
wand = Wizardry.apprenticeLightningWand;
break;
case ADVANCED:
wand = Wizardry.advancedLightningWand;
break;
case MASTER:
wand = Wizardry.masterLightningWand;
break;
default:
break;
}
break;
case NECROMANCY:
switch(tier){
case BASIC:
wand = Wizardry.basicNecromancyWand;
break;
case APPRENTICE:
wand = Wizardry.apprenticeNecromancyWand;
break;
case ADVANCED:
wand = Wizardry.advancedNecromancyWand;
break;
case MASTER:
wand = Wizardry.masterNecromancyWand;
break;
default:
break;
}
break;
case SORCERY:
switch(tier){
case BASIC:
wand = Wizardry.basicSorceryWand;
break;
case APPRENTICE:
wand = Wizardry.apprenticeSorceryWand;
break;
case ADVANCED:
wand = Wizardry.advancedSorceryWand;
break;
case MASTER:
wand = Wizardry.masterSorceryWand;
break;
default:
break;
}
break;
case EARTH:
switch(tier){
case BASIC:
wand = Wizardry.basicEarthWand;
break;
case APPRENTICE:
wand = Wizardry.apprenticeEarthWand;
break;
case ADVANCED:
wand = Wizardry.advancedEarthWand;
break;
case MASTER:
wand = Wizardry.masterEarthWand;
break;
default:
break;
}
break;
default:
switch(tier){
case BASIC:
wand = Wizardry.magicWand;
break;
case APPRENTICE:
wand = Wizardry.apprenticeWand;
break;
case ADVANCED:
wand = Wizardry.advancedWand;
break;
case MASTER:
wand = Wizardry.masterWand;
break;
default:
break;
}
break;
}
}
return wand;
}
}
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,126 +1,80 @@
package electroblob.wizardry.block;
import java.util.Random;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.WizardryGuiHandler;
import electroblob.wizardry.client.GuiArcaneWorkbench;
import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.inventory.InventoryHelper;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IIcon;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public class BlockArcaneWorkbench extends BlockContainer{
public IIcon[] icons = new IIcon[6];
public class BlockArcaneWorkbench extends BlockContainer {
private static final AxisAlignedBB AABB = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.75D, 1.0D);
public BlockArcaneWorkbench(){
super(Material.rock);
this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.75F, 1.0F);
this.setLightLevel(0.8f);
this.setCreativeTab(CreativeTabs.tabDecorations);
this.setBlockTextureName("wizardry:arcane_workbench");
super(Material.ROCK);
this.setLightLevel(0.8f);
}
@Override
public void registerBlockIcons(IIconRegister par1IconRegister) {
this.icons[0] = par1IconRegister.registerIcon(this.textureName + "_bottom");
this.icons[1] = par1IconRegister.registerIcon(this.textureName + "_top");
this.icons[2] = par1IconRegister.registerIcon(this.textureName + "_side");
this.icons[3] = par1IconRegister.registerIcon(this.textureName + "_side");
this.icons[4] = par1IconRegister.registerIcon(this.textureName + "_side");
this.icons[5] = par1IconRegister.registerIcon(this.textureName + "_side");
}
@Override
public IIcon getIcon(int side, int meta) {
return this.icons[side];
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){
return AABB;
}
@Override
public TileEntity createNewTileEntity(World world, int metadata) {
public TileEntity createNewTileEntity(World world, int metadata){
return new TileEntityArcaneWorkbench();
}
@Override
public boolean renderAsNormalBlock()
{
return false;
}
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos){
return false;
}
@Override
public boolean isOpaqueCube()
{
return false;
}
public EnumBlockRenderType getRenderType(IBlockState state){
return EnumBlockRenderType.MODEL;
}
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int metadata, float what, float these, float are) {
TileEntity tileEntity = world.getTileEntity(x, y, z);
if (tileEntity == null || player.isSneaking()) {
public boolean isOpaqueCube(IBlockState state){
return false;
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState block, EntityPlayer player, EnumHand hand,
EnumFacing side, float hitX, float hitY, float hitZ){
TileEntity tileEntity = world.getTileEntity(pos);
if(tileEntity == null || player.isSneaking()){
return false;
}
player.openGui(Wizardry.instance, WizardryGuiHandler.ARCANE_WORKBENCH, world, x, y, z);
player.openGui(Wizardry.instance, WizardryGuiHandler.ARCANE_WORKBENCH, world, pos.getX(), pos.getY(), pos.getZ());
return true;
}
@Override
public void breakBlock(World par1World, int par2, int par3, int par4, Block block, int par6)
{
Random random = new Random();
TileEntityArcaneWorkbench tileentityarcaneworkbench = (TileEntityArcaneWorkbench)par1World.getTileEntity(par2, par3, par4);
public void breakBlock(World world, BlockPos pos, IBlockState block){
TileEntity tileentity = world.getTileEntity(pos);
if (tileentityarcaneworkbench != null)
{
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; par1World.spawnEntityInWorld(entityitem))
{
int k1 = random.nextInt(21) + 10;
if (k1 > itemstack.stackSize)
{
k1 = itemstack.stackSize;
}
itemstack.stackSize -= k1;
entityitem = new EntityItem(par1World, (double)((float)par2 + f), (double)((float)par3 + f1), (double)((float)par4 + 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);
if(tileentity instanceof TileEntityArcaneWorkbench){
InventoryHelper.dropInventoryItems(world, pos, (TileEntityArcaneWorkbench)tileentity);
}
super.breakBlock(par1World, par2, par3, par4, block, par6);
}
super.breakBlock(world, pos, block);
}
}
@@ -1,16 +0,0 @@
package electroblob.wizardry.block;
import java.util.Random;
import electroblob.wizardry.Wizardry;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.item.Item;
public class BlockCrystal extends Block {
public BlockCrystal(Material material) {
super(material);
setHarvestLevel("pickaxe", 2);
}
}
@@ -2,142 +2,71 @@ package electroblob.wizardry.block;
import java.util.Random;
import electroblob.wizardry.EnumParticleType;
import electroblob.wizardry.Wizardry;
import net.minecraft.block.Block;
import electroblob.wizardry.registry.WizardryBlocks;
import electroblob.wizardry.util.WizardryParticleType;
import net.minecraft.block.BlockBush;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.EnumPlantType;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.event.entity.player.BonemealEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
public class BlockCrystalFlower extends Block implements IPlantable {
// Extending BlockBush allows me to remove nearly everything from this class.
@Mod.EventBusSubscriber
public class BlockCrystalFlower extends BlockBush {
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);
this.setLightLevel(0.5f);
this.setBlockBounds(0.5F - 0.2f, 0.0F, 0.5F - 0.2f, 0.5F + 0.2f, 0.2f * 3.0F, 0.5F + 0.2f);
this.setTickRandomly(true);
this.setTickRandomly(true);
this.setSoundType(SoundType.PLANT);
}
@Override
public void randomDisplayTick(World world, int x, int y, int z, Random random){
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){
return AABB;
}
@Override
public void randomDisplayTick(IBlockState state, World world, BlockPos pos, Random random){
if(world.isRemote && random.nextBoolean()){
Wizardry.proxy.spawnParticle(EnumParticleType.SPARKLE, world, x+random.nextDouble(), y+random.nextDouble()/2+0.5, z+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));
}
}
/**
* Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
*/
@Override
public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
{
return super.canPlaceBlockAt(par1World, par2, par3, par4) && canBlockStay(par1World, par2, par3, par4);
}
/**
* Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
* cleared to be reused)
*/
@Override
public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
{
return null;
}
/**
* Gets passed in the blockID of the block below and supposed to return true if its allowed to grow on the type of
* blockID passed in. Args: blockID
*/
protected boolean canThisPlantGrowOnThisBlockID(Block par1)
{
return par1 == Blocks.grass || par1 == Blocks.dirt || par1 == Blocks.farmland;
}
/**
* Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
* their own) Args: x, y, z, neighbor blockID
*/
@Override
public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, Block par5)
{
super.onNeighborBlockChange(par1World, par2, par3, par4, par5);
this.checkFlowerChange(par1World, par2, par3, par4);
}
/**
* Ticks the block if it's been scheduled
*/
@Override
public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
{
this.checkFlowerChange(par1World, par2, par3, par4);
}
protected final void checkFlowerChange(World par1World, int par2, int par3, int par4)
{
if (!this.canBlockStay(par1World, par2, par3, par4))
{
this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0);
par1World.setBlock(par2, par3, par4, Blocks.air, 0, 2);
}
}
/**
* Can this block stay at this position. Similar to canPlaceBlockAt except gets checked often with plants.
*/
@Override
public boolean canBlockStay(World par1World, int par2, int par3, int par4)
{
Block soil = par1World.getBlock(par2, par3 - 1, par4);
return (par1World.getFullBlockLightValue(par2, par3, par4) >= 8 || par1World.canBlockSeeTheSky(par2, par3, par4)) &&
(soil != null && soil.canSustainPlant(par1World, par2, par3 - 1, par4, ForgeDirection.UP, this));
}
/**
* Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two
* adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
*/
@Override
public boolean isOpaqueCube()
{
return false;
}
/**
* If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
*/
@Override
public boolean renderAsNormalBlock()
{
return false;
}
/**
* The type of render function that is called for this block
*/
@Override
public int getRenderType()
{
return 1;
}
@Override
public EnumPlantType getPlantType(IBlockAccess world, int x, int y, int z) {
public EnumPlantType getPlantType(IBlockAccess world, BlockPos pos){
return EnumPlantType.Plains;
}
@Override
public Block getPlant(IBlockAccess world, int x, int y, int z) {
return this;
}
@SubscribeEvent
public static void onBonemealEvent(BonemealEvent event){
// Grows crystal flowers when bonemeal is used on grass
if(event.getBlock().getBlock() == Blocks.GRASS){
@Override
public int getPlantMetadata(IBlockAccess world, int x, int y, int z) {
return 0;
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(8) - event.getWorld().rand.nextInt(8));
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);
}
}
}
}
@@ -2,33 +2,56 @@ package electroblob.wizardry.block;
import java.util.Random;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.registry.WizardryItems;
import net.minecraft.block.Block;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.item.Item;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public class BlockCrystalOre extends Block {
public BlockCrystalOre(Material material) {
public BlockCrystalOre(Material material){
super(material);
setStepSound(Block.soundTypeStone);
setBlockName("crystalOre");
this.setSoundType(SoundType.STONE);
setResistance(5.0F);
setHarvestLevel("pickaxe", 2);
}
@Override
public int quantityDropped(int meta, 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){
return random.nextInt(2) + 1 + random.nextInt(fortune);
int i = random.nextInt(fortune + 2) - 1;
if(i < 0) i = 0;
return (random.nextInt(3) + 1) * (i + 1);
}else{
return random.nextInt(2) + 1;
return random.nextInt(3) + 1;
}
}
}
@Override
public Item getItemDropped(IBlockState state, Random random, int fortune){
return WizardryItems.magic_crystal;
}
@Override
public Item getItemDropped(int Metadata, Random random, int fortune){
return Wizardry.magicCrystal;
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;
}
}
@@ -1,40 +1,59 @@
package electroblob.wizardry.block;
import java.util.Random;
import electroblob.wizardry.tileentity.TileEntityMagicLight;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
public class BlockMagicLight extends BlockContainer {
public BlockMagicLight(Material par2Material) {
private static final AxisAlignedBB AABB = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
public BlockMagicLight(Material par2Material){
super(par2Material);
this.setLightLevel(1.0f);
this.setBlockBounds(0, 0, 0, 0, 0, 0);
}
public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
{
return null;
}
@Override
public TileEntity createNewTileEntity(World world, int metadata) {
return new TileEntityMagicLight(600);
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.
return NULL_AABB;
}
@Override
public boolean renderAsNormalBlock()
{
return false;
}
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){
return AABB;
}
@Override
public boolean isOpaqueCube(){
public boolean isCollidable(){
return false;
}
@Override
public TileEntity createNewTileEntity(World world, int metadata){
return new TileEntityMagicLight(600);
}
@Override
public boolean isOpaqueCube(IBlockState state){
return false;
}
@Override
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos){
return false;
}
@Override
public EnumBlockRenderType getRenderType(IBlockState state){
return EnumBlockRenderType.ENTITYBLOCK_ANIMATED;
}
}
@@ -2,89 +2,110 @@ package electroblob.wizardry.block;
import java.util.Random;
import electroblob.wizardry.EnumElement;
import electroblob.wizardry.MagicDamage;
import electroblob.wizardry.MagicDamage.DamageType;
import electroblob.wizardry.WizardryUtilities;
import electroblob.wizardry.tileentity.TileEntityPlayerSave;
import electroblob.wizardry.util.MagicDamage;
import electroblob.wizardry.util.MagicDamage.DamageType;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.init.MobEffects;
import net.minecraft.item.Item;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.DamageSource;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
// TODO: Apparently you shouldn't extend BlockContainer. I feel like BlockArcaneWorkbench should, but what about the rest?
public class BlockSnare extends BlockContainer {
public BlockSnare(Material par2Material){
super(par2Material);
this.setBlockBounds(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 material){
super(material);
this.setSoundType(SoundType.PLANT);
}
@Override
public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4){
return null;
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){
return AABB;
}
@Override
public boolean hasTileEntity(int metadata){
public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos){
return NULL_AABB;
}
@Override
public boolean hasTileEntity(IBlockState state){
return true;
}
@Override
public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity){
public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entity){
if(!world.isRemote && entity instanceof EntityLivingBase){
if(world.getTileEntity(x, y, z) instanceof TileEntityPlayerSave){
TileEntityPlayerSave tileentity = (TileEntityPlayerSave)world.getTileEntity(x, y, z);
if(world.getTileEntity(pos) instanceof TileEntityPlayerSave){
TileEntityPlayerSave tileentity = (TileEntityPlayerSave)world.getTileEntity(pos);
if(WizardryUtilities.isValidTarget(tileentity.getCaster(), entity)){
((EntityLivingBase)entity).attackEntityFrom(MagicDamage.causeDirectMagicDamage(tileentity.getCaster(), DamageType.MAGIC), 6);
((EntityLivingBase)entity).addPotionEffect(new PotionEffect(Potion.moveSlowdown.id, 100, 2));
world.func_147480_a(x, y, z, false);
((EntityLivingBase)entity).attackEntityFrom(
MagicDamage.causeDirectMagicDamage(tileentity.getCaster(), DamageType.MAGIC), 6);
((EntityLivingBase)entity).addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, 100, 2));
world.destroyBlock(pos, false);
}
}
}
}
// The similarly named onNeighborChange method does NOT do the same thing.
@SuppressWarnings("deprecation")
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, Block block)
{
super.onNeighborBlockChange(world, x, y, z, block);
if(!world.isSideSolid(x, y-1, z, ForgeDirection.UP)){
world.setBlockToAir(x, y, z);
}
}
@Override
public boolean renderAsNormalBlock()
{
return false;
}
@Override
public boolean isOpaqueCube()
{
return false;
}
@Override
public int getRenderType(){
return 23;
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)){
world.setBlockToAir(pos);
}
}
@Override
public Item getItemDropped(int a, Random random, int b){
public BlockRenderLayer getRenderLayer() {
return BlockRenderLayer.CUTOUT;
}
@Override
public EnumBlockRenderType getRenderType(IBlockState state){
return EnumBlockRenderType.MODEL;
}
@Override
public boolean isOpaqueCube(IBlockState state){
return false;
}
@Override
public boolean isFullCube(IBlockState state){
return false;
}
@Override
public Item getItemDropped(IBlockState state, Random rand, int fortune){
return null;
}
@Override
public TileEntity createNewTileEntity(World world, int metadata) {
public TileEntity createNewTileEntity(World world, int metadata){
return new TileEntityPlayerSave();
}
@@ -2,73 +2,114 @@ package electroblob.wizardry.block;
import java.util.Random;
import electroblob.wizardry.EnumParticleType;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.registry.WizardryBlocks;
import electroblob.wizardry.tileentity.TileEntityTimer;
import electroblob.wizardry.util.WizardryParticleType;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
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.
@Mod.EventBusSubscriber
public class BlockSpectral extends BlockContainer {
public BlockSpectral(Material material) {
public BlockSpectral(Material material){
super(material);
this.setSoundType(SoundType.GLASS);
}
// Replaces getRenderBlockPass
@Override
public int getRenderBlockPass()
{
return 1;
}
public BlockRenderLayer getRenderLayer(){
return BlockRenderLayer.TRANSLUCENT;
}
@Override
public boolean isOpaqueCube()
{
return false;
}
public EnumBlockRenderType getRenderType(IBlockState state){
return EnumBlockRenderType.MODEL;
}
// Apparently it's OK to override this, despite it being deprecated. More
// importantly, it being deprecated is not
// Forge's doing, rather it is Mojang themselves misusing the @Deprecated
// annotation to mean 'internal, don't call'.
@Override
public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
{
Block block = par1IBlockAccess.getBlock(par2, par3, par4);
return block == this ? false : super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5);
}
public boolean isOpaqueCube(IBlockState state){
return false;
}
@Override
public void randomDisplayTick(World world, int x, int y, int z, Random random){
// Middle of block
Wizardry.proxy.spawnParticle(EnumParticleType.DUST, world, x+random.nextDouble(), y+random.nextDouble(), z+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(EnumParticleType.DUST, world, x+random.nextDouble(), y+1, z+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(EnumParticleType.DUST, world, x+random.nextDouble(), y+1, z+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.
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos){
return false;
}
@Override
public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
return 15;
}
@Override
public TileEntity createNewTileEntity(World world, int metadata) {
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;
}
@Override
public TileEntity createNewTileEntity(World world, int metadata){
return new TileEntityTimer(1200);
}
/**
* Returns the quantity of items to drop on block destruction.
*/
@Override
public int quantityDropped(Random par1Random)
{
return 0;
}
@Override
public int quantityDropped(Random par1Random){
return 0;
}
@SuppressWarnings("deprecation")
@SideOnly(Side.CLIENT)
@Override
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);
}
@SubscribeEvent
public static void onBlockPlaceEvent(BlockEvent.PlaceEvent event){
// Spectral blocks cannot be built on
if(event.getPlacedAgainst() == WizardryBlocks.spectral_block){
event.setCanceled(true);
}
}
}
@@ -2,171 +2,168 @@ package electroblob.wizardry.block;
import java.util.Random;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.spell.Petrify;
import electroblob.wizardry.tileentity.TileEntityStatue;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.init.Blocks;
import net.minecraft.block.state.IBlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.Facing;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BlockStatue extends BlockContainer {
private boolean isIce;
public BlockStatue(Material par2Material) {
super(par2Material);
this.isIce = par2Material == Material.ice;
public BlockStatue(Material material){
super(material);
this.isIce = material == Material.ICE;
if(this.isIce){
this.slipperiness = 0.98F;
this.setDefaultSlipperiness(0.98f);
this.setSoundType(SoundType.GLASS);
}
}
@Override
public void setBlockBoundsBasedOnState(IBlockAccess world, int x, int y, int z) {
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!
if(!this.isIce){
if(world.getTileEntity(x, y, z) instanceof TileEntityStatue){
if(world.getTileEntity(pos) instanceof TileEntityStatue){
TileEntityStatue statue = (TileEntityStatue)world.getTileEntity(x, y, z);
TileEntityStatue statue = (TileEntityStatue)world.getTileEntity(pos);
if(statue.creature != null){
// Block bounds are set to match the width and height of the entity, clamped to within 1 block.
this.setBlockBounds((float)Math.max(0.5 - statue.creature.width/2, 0), 0,
(float)Math.max(0.5 - statue.creature.width/2, 0),
(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
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.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
// the top of the entity model.
statue.position == statue.parts ? (float)Math.min(statue.creature.height - statue.parts + 1, 1) : 1,
(float)Math.min(0.5 + statue.creature.width/2, 1));
}
}
}
}
@Override
public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) {
if(!this.isIce){
if(world.getTileEntity(x, y, z) instanceof TileEntityStatue){
TileEntityStatue statue = (TileEntityStatue)world.getTileEntity(x, y, z);
if(statue.creature != null){
// Block bounds are set to match the width and height of the entity, clamped to within 1 block.
return AxisAlignedBB.getBoundingBox(x + Math.max(0.5 - statue.creature.width/2, 0),
y, z + Math.max(0.5 - statue.creature.width/2, 0),
x + 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
// the top of the entity model
statue.position == statue.parts ? y + (float)Math.min(statue.creature.height - statue.parts + 1, 1) : y + 1,
z + Math.min(0.5 + statue.creature.width/2, 1));
statue.position == statue.parts
? (float)Math.min(statue.creature.height - statue.parts + 1, 1)
: 1,
(float)Math.min(0.5 + statue.creature.width / 2, 1));
}
}
}
return super.getCollisionBoundingBoxFromPool(world, x, y, z);
return FULL_BLOCK_AABB;
}
// 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.
// The number of these methods is quite simply ridiculous. This one seems to be for placement logic and block
// connections (fences, glass panes, etc.)...
@Override
public boolean renderAsNormalBlock(){
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
public boolean canRenderInPass(int pass){
return this.isIce ? super.canRenderInPass(pass) : false;
public BlockRenderLayer getRenderLayer(){
return this.isIce ? BlockRenderLayer.TRANSLUCENT : BlockRenderLayer.SOLID;
}
@Override
public boolean isOpaqueCube(){
return false;// !this.isIce;
public EnumBlockRenderType getRenderType(IBlockState state){
return this.isIce ? EnumBlockRenderType.MODEL : EnumBlockRenderType.ENTITYBLOCK_ANIMATED;
}
@Override
public int getRenderBlockPass()
{
return this.isIce? 1 : 0;
}
@Override
public TileEntity createNewTileEntity(World world, int metadata) {
public TileEntity createNewTileEntity(World world, int metadata){
return new TileEntityStatue(this.isIce);
}
/*
@Override
public void randomDisplayTick(World world, int x, int y, int z, Random random){
if(this.isIce){
float brightness = 0.5f + (random.nextFloat()/2);
Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySparkleFX(world, x + random.nextDouble(), y + random.nextDouble(), z + random.nextDouble(), 0, 0, 0, null, brightness, brightness + 0.1f, 1.0f, true));
}
}
*/
/**
* Returns the quantity of items to drop on block destruction.
*/
@Override
public int quantityDropped(Random par1Random)
{
public int quantityDropped(Random random){
return 0;
}
/**
* Returns true if the given side of this block type should be rendered, if the adjacent block is at the given
* coordinates. Args: blockAccess, x, y, z, side
*/
@Override
@SideOnly(Side.CLIENT)
public boolean shouldSideBeRendered(IBlockAccess p_149646_1_, int p_149646_2_, int p_149646_3_, int p_149646_4_, int p_149646_5_)
{
Block block = p_149646_1_.getBlock(p_149646_2_, p_149646_3_, p_149646_4_);
public void breakBlock(World world, BlockPos pos, IBlockState state){
return block == this ? false : super.shouldSideBeRendered(p_149646_1_, p_149646_2_, p_149646_3_, p_149646_4_, p_149646_5_);
}
if(!world.isRemote){
TileEntityStatue tileentity = (TileEntityStatue)world.getTileEntity(pos);
@Override
public void breakBlock(World par1World, int x, int y, int z, Block block, int par6)
{
if(!par1World.isRemote){
TileEntityStatue tileentity = (TileEntityStatue)par1World.getTileEntity(x, y, z);
if(tileentity != null){
if(tileentity.parts == 2){
if(tileentity.position == 2){
// func_147480_a is the method that causes the block to smash as if broken by a player.
// Used to be called destroyBlock. The boolean is whether the block should drop items.
par1World.func_147480_a(x, y-1, z, false);
world.destroyBlock(pos.down(), false);
}else{
par1World.func_147480_a(x, y+1, z, false);
world.destroyBlock(pos.up(), false);
}
}else if(tileentity.parts == 3){
if(tileentity.position == 3){
par1World.func_147480_a(x, y-1, z, false);
par1World.func_147480_a(x, y-2, z, false);
world.destroyBlock(pos.down(), false);
world.destroyBlock(pos.down(2), false);
}else if(tileentity.position == 2){
par1World.func_147480_a(x, y-1, z, false);
par1World.func_147480_a(x, y+1, z, false);
world.destroyBlock(pos.down(), false);
world.destroyBlock(pos.up(), false);
}else{
par1World.func_147480_a(x, y+1, z, false);
par1World.func_147480_a(x, y+2, z, false);
world.destroyBlock(pos.up(), false);
world.destroyBlock(pos.up(2), false);
}
}
}
// This is only when position == 1 because world.destroyBlock calls this function for the other blocks.
if(tileentity != null && tileentity.position == 1 && tileentity.creature != null){
tileentity.creature.getEntityData().removeTag(Petrify.NBT_KEY);
tileentity.creature.isDead = false;
par1World.spawnEntityInWorld(tileentity.creature);
world.spawnEntity(tileentity.creature);
}
}
super.breakBlock(par1World, x, y, z, block, par6);
super.breakBlock(world, pos, state);
}
@SuppressWarnings("deprecation")
@SideOnly(Side.CLIENT)
@Override
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);
}
}
@@ -2,148 +2,141 @@ package electroblob.wizardry.block;
import java.util.Random;
import electroblob.wizardry.ExtendedPlayer;
import electroblob.wizardry.WizardData;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.WizardryRegistry;
import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardryBlocks;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
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);
public BlockTransportationStone(Material material){
super(material);
this.setBlockBounds(0.0625f*5, 0, 0.0625f*5, 0.0625f*11, 0.0625f*6, 0.0625f*11);
this.setTickRandomly(true);
this.setTickRandomly(true);
}
@Override
public boolean isOpaqueCube(){
public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos){
return AABB;
}
// The number of these methods is quite simply ridiculous. This one seems to be for placement logic and block
// 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 renderAsNormalBlock(){
public boolean isBlockNormalCube(IBlockState state){
return false;
}
// ... this one is for most other game logic...
@Override
public void onNeighborBlockChange(World world, int x, int y, int z, Block block)
{
super.onNeighborBlockChange(world, x, y, z, block);
if(!world.isSideSolid(x, y-1, z, ForgeDirection.UP)){
this.dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0);
world.setBlockToAir(x, y, z);
}
}
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 void updateTick(World world, int x, int y, int z, Random random)
{
if(!world.isSideSolid(x, y-1, z, ForgeDirection.UP)){
this.dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0);
world.setBlockToAir(x, y, z);
}
}
public boolean isNormalCube(IBlockState state, IBlockAccess world, BlockPos pos){
return false;
}
// ... and this one is for rendering.
@Override
public boolean canPlaceBlockAt(World par1World, int x, int y, int z)
{
return super.canPlaceBlockAt(par1World, x, y, z) && par1World.isSideSolid(x, y-1, z, ForgeDirection.UP);
}
public boolean isOpaqueCube(IBlockState state){
return false;
}
@SuppressWarnings("deprecation")
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer entityplayer, int par6, float par7, float par8, float par9)
{
if(entityplayer.getHeldItem() != null && entityplayer.getHeldItem().getItem() instanceof ItemWand){
if(ExtendedPlayer.get(entityplayer) != null){
ExtendedPlayer extendedplayer = ExtendedPlayer.get(entityplayer);
int x1=x-1, z1=z-1;
if(testForCircle(world, x1, y, z1)){
extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId);
if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name);
return true;
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
public boolean canPlaceBlockAt(World world, BlockPos pos){
return super.canPlaceBlockAt(world, pos) && world.isSideSolid(pos.down(), EnumFacing.UP);
}
@Override
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand,
EnumFacing side, float hitX, float hitY, float hitZ){
ItemStack stack = player.getHeldItem(hand);
if(stack.getItem() instanceof ItemWand){
if(WizardData.get(player) != null){
WizardData data = WizardData.get(player);
for(int x = -1; x <= 1; x++){
for(int z = -1; z <= 1; z++){
BlockPos pos1 = pos.add(x, 0, z);
if(testForCircle(world, pos1)){
data.setStoneCircleLocation(pos1, world.provider.getDimension());
if(!world.isRemote) player.sendMessage(
new TextComponentTranslation("tile." + Wizardry.MODID + ":transportation_stone.confirm",
Spells.transportation.getNameForTranslationFormatted()));
return true;
}
}
}
x1=x;
z1=z-1;
if(testForCircle(world, x1, y, z1)){
extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId);
if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name);
return true;
}
x1=x+1;
z1=z-1;
if(testForCircle(world, x1, y, z1)){
extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId);
if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name);
return true;
}
x1=x-1;
z1=z;
if(testForCircle(world, x1, y, z1)){
extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId);
if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name);
return true;
}
x1=x+1;
z1=z;
if(testForCircle(world, x1, y, z1)){
extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId);
if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name);
return true;
}
x1=x-1;
z1=z+1;
if(testForCircle(world, x1, y, z1)){
extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId);
if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name);
return true;
}
x1=x;
z1=z+1;
if(testForCircle(world, x1, y, z1)){
extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId);
if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name);
return true;
}
x1=x+1;
z1=z+1;
if(testForCircle(world, x1, y, z1)){
extendedplayer.setStoneLocation(x1, y, z1, world.provider.dimensionId);
if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.confirm", WizardryRegistry.transportation.getDisplayNameWithFormatting()));//"You will now be returned here upon casting " + EnumSpell.TRANSPORTATION.name);
return true;
}
if(!world.isRemote) entityplayer.addChatMessage(new ChatComponentTranslation("tile.transportationStone.invalid"));//"You must make a circle with 8 stones of transportation first!");
if(!world.isRemote)
player.sendMessage(new TextComponentTranslation("tile." + Wizardry.MODID + ":transportation_stone.invalid"));
return true;
}
}
return false;
}
return false;
}
/** Returns whether the specified location is surrounded by a complete cicle of 8 transportation stones. */
public static boolean testForCircle(World world, int x, int y, int z){
return world.getBlock(x-1, y, z-1) == Wizardry.transportationStone
&& world.getBlock(x, y, z-1) == Wizardry.transportationStone
&& world.getBlock(x+1, y, z-1) == Wizardry.transportationStone
&& world.getBlock(x-1, y, z) == Wizardry.transportationStone
&& !world.getBlock(x, y, z).getMaterial().blocksMovement()
&& world.getBlock(x+1, y, z) == Wizardry.transportationStone
&& world.getBlock(x-1, y, z+1) == Wizardry.transportationStone
&& world.getBlock(x, y, z+1) == Wizardry.transportationStone
&& world.getBlock(x+1, y, z+1) == Wizardry.transportationStone;
public static boolean testForCircle(World world, BlockPos pos){
if(world.getBlockState(pos).getMaterial().blocksMovement()) return false;
for(int x = -1; x <= 1; x++){
for(int z = -1; z <= 1; z++){
if(world.getBlockState(pos.add(x, 0, z)).getBlock() != WizardryBlocks.transportation_stone){
if(x != 0 || z != 0) return false;
}
}
}
return true;
}
}
@@ -2,60 +2,66 @@ package electroblob.wizardry.block;
import java.util.Random;
import electroblob.wizardry.EnumParticleType;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.tileentity.TileEntityTimer;
import net.minecraft.block.Block;
import net.minecraft.block.BlockContainer;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.EnumBlockRenderType;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
// For future reference - extend BlockContainer whenever possible because it has methods for removing tile entities on block break.
public class BlockVanishingCobweb extends BlockContainer {
public BlockVanishingCobweb(Material material) {
public BlockVanishingCobweb(Material material){
super(material);
}
@SideOnly(Side.CLIENT)
public BlockRenderLayer getBlockLayer(){
return BlockRenderLayer.CUTOUT;
}
@Override
public int getRenderType()
{
return 1;
}
public EnumBlockRenderType getRenderType(IBlockState state){
return EnumBlockRenderType.MODEL;
}
@Override
public boolean isOpaqueCube()
{
return false;
}
@Override
public TileEntity createNewTileEntity(World world, int metadata) {
public boolean isOpaqueCube(IBlockState state){
return false;
}
@Override
public AxisAlignedBB getCollisionBoundingBox(IBlockState state, IBlockAccess world, BlockPos pos){
return NULL_AABB;
}
@Override
public boolean isFullCube(IBlockState state){
return false;
}
@Override
public TileEntity createNewTileEntity(World world, int metadata){
return new TileEntityTimer(400);
}
@Override
public void onEntityCollidedWithBlock(World world, int x, int y, int z, Entity entity)
{
entity.setInWeb();
}
@Override
public AxisAlignedBB getCollisionBoundingBoxFromPool(World p_149668_1_, int p_149668_2_, int p_149668_3_, int p_149668_4_) {
return null;
}
/**
* Returns the quantity of items to drop on block destruction.
*/
@Override
public int quantityDropped(Random par1Random)
{
return 0;
}
@Override
public void onEntityCollision(World world, BlockPos pos, IBlockState state, Entity entity){
entity.setInWeb();
}
@Override
public int quantityDropped(Random par1Random){
return 0;
}
}
@@ -5,32 +5,25 @@ import java.util.HashMap;
import org.lwjgl.input.Keyboard;
import cpw.mods.fml.client.config.GuiConfigEntries.NumberSliderEntry;
import cpw.mods.fml.client.registry.ClientRegistry;
import cpw.mods.fml.client.registry.RenderingRegistry;
import electroblob.wizardry.CommonProxy;
import electroblob.wizardry.EnumParticleType;
import electroblob.wizardry.ExtendedPlayer;
import electroblob.wizardry.SpellGlyphData;
import electroblob.wizardry.WandHelper;
import electroblob.wizardry.WizardData;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.WizardryRegistry;
import electroblob.wizardry.WizardryUtilities;
import electroblob.wizardry.client.model.ModelSpiritHorse;
import electroblob.wizardry.client.model.ModelSpiritWolf;
import electroblob.wizardry.client.model.ModelWizardArmour;
import electroblob.wizardry.client.particle.EntityBlizzardFX;
import electroblob.wizardry.client.particle.EntityDarkMagicFX;
import electroblob.wizardry.client.particle.EntityDustFX;
import electroblob.wizardry.client.particle.EntityIceFX;
import electroblob.wizardry.client.particle.EntityLeafFX;
import electroblob.wizardry.client.particle.EntityMagicBubbleFX;
import electroblob.wizardry.client.particle.EntityMagicFireFX;
import electroblob.wizardry.client.particle.EntityPathFX;
import electroblob.wizardry.client.particle.EntitySnowFX;
import electroblob.wizardry.client.particle.EntitySparkFX;
import electroblob.wizardry.client.particle.EntitySparkleFX;
import electroblob.wizardry.client.particle.EntityTornadoFX;
import electroblob.wizardry.client.particle.ParticleBlizzard;
import electroblob.wizardry.client.particle.ParticleDarkMagic;
import electroblob.wizardry.client.particle.ParticleDust;
import electroblob.wizardry.client.particle.ParticleGiantBubble;
import electroblob.wizardry.client.particle.ParticleIce;
import electroblob.wizardry.client.particle.ParticleLeaf;
import electroblob.wizardry.client.particle.ParticleMagicFlame;
import electroblob.wizardry.client.particle.ParticlePath;
import electroblob.wizardry.client.particle.ParticleRotatingSparkle;
import electroblob.wizardry.client.particle.ParticleSnow;
import electroblob.wizardry.client.particle.ParticleSpark;
import electroblob.wizardry.client.particle.ParticleSparkle;
import electroblob.wizardry.client.particle.ParticleTornado;
import electroblob.wizardry.client.renderer.LayerStone;
import electroblob.wizardry.client.renderer.RenderArc;
import electroblob.wizardry.client.renderer.RenderArcaneWorkbench;
import electroblob.wizardry.client.renderer.RenderBlackHole;
@@ -39,7 +32,6 @@ import electroblob.wizardry.client.renderer.RenderBubble;
import electroblob.wizardry.client.renderer.RenderDecay;
import electroblob.wizardry.client.renderer.RenderDecoy;
import electroblob.wizardry.client.renderer.RenderEvilWizard;
import electroblob.wizardry.client.renderer.RenderFallingGrass;
import electroblob.wizardry.client.renderer.RenderFireRing;
import electroblob.wizardry.client.renderer.RenderForceArrow;
import electroblob.wizardry.client.renderer.RenderHammer;
@@ -49,25 +41,14 @@ import electroblob.wizardry.client.renderer.RenderLightningDisc;
import electroblob.wizardry.client.renderer.RenderLightningPulse;
import electroblob.wizardry.client.renderer.RenderMagicArrow;
import electroblob.wizardry.client.renderer.RenderMagicLight;
import electroblob.wizardry.client.renderer.RenderMagicSlime;
import electroblob.wizardry.client.renderer.RenderMeteor;
import electroblob.wizardry.client.renderer.RenderPhoenix;
import electroblob.wizardry.client.renderer.RenderProjectile;
import electroblob.wizardry.client.renderer.RenderSigil;
import electroblob.wizardry.client.renderer.RenderSilverfishMinion;
import electroblob.wizardry.client.renderer.RenderSkeletonMinion;
import electroblob.wizardry.client.renderer.RenderSpiderMinion;
import electroblob.wizardry.client.renderer.RenderSpiritHorse;
import electroblob.wizardry.client.renderer.RenderSpiritWolf;
import electroblob.wizardry.client.renderer.RenderStatue;
import electroblob.wizardry.client.renderer.RenderTranslucentItem;
import electroblob.wizardry.client.renderer.RenderWizard;
import electroblob.wizardry.client.renderer.RenderWraithMinion;
import electroblob.wizardry.client.renderer.RenderZombieMinion;
import electroblob.wizardry.entity.EntityArc;
import electroblob.wizardry.entity.EntityFallingGrass;
import electroblob.wizardry.entity.EntityMagicSlime;
import electroblob.wizardry.entity.EntityMeteor;
import electroblob.wizardry.entity.EntityShield;
import electroblob.wizardry.entity.construct.EntityArrowRain;
import electroblob.wizardry.entity.construct.EntityBlackHole;
@@ -86,7 +67,6 @@ import electroblob.wizardry.entity.construct.EntityIceSpike;
import electroblob.wizardry.entity.construct.EntityLightningPulse;
import electroblob.wizardry.entity.construct.EntityLightningSigil;
import electroblob.wizardry.entity.construct.EntityTornado;
import electroblob.wizardry.entity.living.EntityBlazeMinion;
import electroblob.wizardry.entity.living.EntityDecoy;
import electroblob.wizardry.entity.living.EntityEvilWizard;
import electroblob.wizardry.entity.living.EntityIceGiant;
@@ -94,15 +74,12 @@ import electroblob.wizardry.entity.living.EntityIceWraith;
import electroblob.wizardry.entity.living.EntityLightningWraith;
import electroblob.wizardry.entity.living.EntityPhoenix;
import electroblob.wizardry.entity.living.EntityShadowWraith;
import electroblob.wizardry.entity.living.EntitySilverfishMinion;
import electroblob.wizardry.entity.living.EntitySkeletonMinion;
import electroblob.wizardry.entity.living.EntitySpiderMinion;
import electroblob.wizardry.entity.living.EntitySpiritHorse;
import electroblob.wizardry.entity.living.EntitySpiritWolf;
import electroblob.wizardry.entity.living.EntityStormElemental;
import electroblob.wizardry.entity.living.EntitySummonedCreature;
import electroblob.wizardry.entity.living.EntityWizard;
import electroblob.wizardry.entity.living.EntityZombieMinion;
import electroblob.wizardry.entity.living.ISpellCaster;
import electroblob.wizardry.entity.living.ISummonedCreature;
import electroblob.wizardry.entity.projectile.EntityDarknessOrb;
import electroblob.wizardry.entity.projectile.EntityDart;
import electroblob.wizardry.entity.projectile.EntityFirebolt;
@@ -120,459 +97,523 @@ import electroblob.wizardry.entity.projectile.EntitySmokeBomb;
import electroblob.wizardry.entity.projectile.EntitySpark;
import electroblob.wizardry.entity.projectile.EntitySparkBomb;
import electroblob.wizardry.entity.projectile.EntityThunderbolt;
import electroblob.wizardry.item.ItemFlamingAxe;
import electroblob.wizardry.item.ItemFrostAxe;
import electroblob.wizardry.event.SpellCastEvent;
import electroblob.wizardry.event.SpellCastEvent.Source;
import electroblob.wizardry.item.ItemScroll;
import electroblob.wizardry.item.ItemSpectralArmour;
import electroblob.wizardry.item.ItemSpectralBow;
import electroblob.wizardry.item.ItemSpectralPickaxe;
import electroblob.wizardry.item.ItemSpectralSword;
import electroblob.wizardry.item.ItemSpellBook;
import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.packet.PacketCastContinuousSpell;
import electroblob.wizardry.packet.PacketCastSpell;
import electroblob.wizardry.packet.PacketNPCCastSpell;
import electroblob.wizardry.packet.PacketPlayerSync.Message;
import electroblob.wizardry.packet.PacketTransportation;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.spell.Clairvoyance;
import electroblob.wizardry.spell.None;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench;
import electroblob.wizardry.tileentity.TileEntityMagicLight;
import electroblob.wizardry.tileentity.TileEntityStatue;
import net.minecraft.block.Block;
import electroblob.wizardry.util.WandHelper;
import electroblob.wizardry.util.WizardryParticleType;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.model.ModelSlime;
import net.minecraft.client.particle.EntityDiggingFX;
import net.minecraft.client.renderer.entity.RenderBlaze;
import net.minecraft.client.resources.I18n;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.monster.EntityBlaze;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumParticleTypes;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Vec3;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.config.Property;
import net.minecraftforge.fml.client.config.GuiConfigEntries.NumberSliderEntry;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
/**
* The client proxy for wizardry.
*
* @author Electroblob
* @since Wizardry 1.0
*/
public class ClientProxy extends CommonProxy {
/** Static instance of the mixed font renderer */
public static MixedFontRenderer mixedFontRenderer;
// Key Bindings
public static final KeyBinding nextSpell = new KeyBinding("key.next_spell", Keyboard.KEY_N, "key.categories.wizardry");
public static final KeyBinding previousSpell = new KeyBinding("key.previous_spell", Keyboard.KEY_B, "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.MODID + ".previous_spell", Keyboard.KEY_B, "key.categories." + Wizardry.MODID);
// Armour Model
public static ModelBiped wizardArmourModel = new ModelWizardArmour(0.75f);
public static final ModelBiped WIZARD_ARMOUR_MODEL = new ModelWizardArmour(0.75f);
// SECTION Registry
// ===============================================================================================================
@Override
public ModelBiped getWizardArmourModel(){
return wizardArmourModel;
return WIZARD_ARMOUR_MODEL;
}
@Override
public double getPlayerEyesPos(EntityPlayer player){
return Minecraft.getMinecraft().thePlayer == player ? player.posY : player.posY + player.eyeHeight;
}
@Override
public Vec3 getWandTipPosition(EntityLivingBase entity){
// Behaves differently in first person
if(Minecraft.getMinecraft().thePlayer == entity && Minecraft.getMinecraft().gameSettings.thirdPersonView == 0){
return Vec3.createVectorHelper(entity.posX, entity.boundingBox.minY + 1.2, entity.posZ);
}else{
return super.getWandTipPosition(entity);
}
public void registerKeyBindings(){
ClientRegistry.registerKeyBinding(NEXT_SPELL);
ClientRegistry.registerKeyBinding(PREVIOUS_SPELL);
}
@Override
public void registerKeyBindings(){
ClientRegistry.registerKeyBinding(nextSpell);
ClientRegistry.registerKeyBinding(previousSpell);
}
@Override
public void registerEventHandlers(){
super.registerEventHandlers();
MinecraftForge.EVENT_BUS.register(new WizardryClientEventHandler());
}
@Override
public void registerSpellHUD(){
public void registerSpellHUD(){
MinecraftForge.EVENT_BUS.register(new GuiSpellDisplay(Minecraft.getMinecraft()));
}
@Override
public void setToNumberSliderEntry(Property property) {
public void initGuiBits(){
mixedFontRenderer = new MixedFontRenderer(Minecraft.getMinecraft().gameSettings, new ResourceLocation("textures/font/ascii.png"),
Minecraft.getMinecraft().renderEngine, false);
GuiWizardHandbook.initDisplayRecipes();
}
// SECTION Misc
// ===============================================================================================================
@Override
public void setToNumberSliderEntry(Property property){
property.setConfigEntryClass(NumberSliderEntry.class);
}
@Override
public World getTheWorld(){
return Minecraft.getMinecraft().world;
}
@Override
public void playMovingSound(Entity entity, SoundEvent sound, float volume, float pitch, boolean repeat){
Minecraft.getMinecraft().getSoundHandler().playSound(new MovingSoundEntity(entity, sound, volume, pitch, repeat));
}
// SECTION Items
// ===============================================================================================================
@Override
public FontRenderer getFontRenderer(ItemStack stack){
Spell spell = WizardryRegistry.none;
Spell spell = Spells.none;
if(stack.getItem() instanceof ItemWand){
spell = WandHelper.getCurrentSpell(stack);
}else if(stack.getItem() instanceof ItemSpellBook || stack.getItem() instanceof ItemScroll){
spell = Spell.get(stack.getItemDamage());
}
if(Wizardry.discoveryMode && ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer) != null && !Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode
&& !ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer).hasSpellBeenDiscovered(spell)){
if(Minecraft.getMinecraft().player != null && Wizardry.settings.discoveryMode && WizardData.get(Minecraft.getMinecraft().player) != null
&& !Minecraft.getMinecraft().player.capabilities.isCreativeMode
&& !WizardData.get(Minecraft.getMinecraft().player).hasSpellBeenDiscovered(spell)){
return mixedFontRenderer;
}
return null;
}
@Override
public String getScrollDisplayName(ItemStack scroll){
// Displays [Empty slot] if spell is continuous.
Spell spell = Spell.get(scroll.getItemDamage());
if(spell.isContinuous) spell = WizardryRegistry.none;
EntityPlayer player = Minecraft.getMinecraft().thePlayer;
boolean discovered = true;
// 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(player != null && Wizardry.discoveryMode && !player.capabilities.isCreativeMode
&& ExtendedPlayer.get(player) != null && !ExtendedPlayer.get(player).hasSpellBeenDiscovered(spell)){
if(spell.isContinuous) spell = Spells.none;
EntityPlayer player = Minecraft.getMinecraft().player;
boolean discovered = true;
// 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(player != null && Wizardry.settings.discoveryMode && !player.capabilities.isCreativeMode && WizardData.get(player) != null
&& !WizardData.get(player).hasSpellBeenDiscovered(spell)){
discovered = false;
}
if(discovered){
return I18n.format("item.scroll.name", spell.getDisplayName()).trim();
return I18n.format("item." + Wizardry.MODID + ":scroll.name", spell.getDisplayName()).trim();
}else{
return I18n.format("item.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
public void spawnParticle(EnumParticleType 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){
switch(type){
case BLIZZARD:
Minecraft.getMinecraft().effectRenderer.addEffect(new EntityBlizzardFX(world, r, g, b, maxAge, x, z, radius, y));
break;
case BRIGHT_DUST:
Minecraft.getMinecraft().effectRenderer.addEffect(new EntityDustFX(world, x, y, z, velX, velY, velZ, r, g, b, false));
break;
case DARK_MAGIC:
Minecraft.getMinecraft().effectRenderer.addEffect(new EntityDarkMagicFX(world, x, y, z, velX, velY, velZ, r, g, b));
break;
case DUST:
Minecraft.getMinecraft().effectRenderer.addEffect(new EntityDustFX(world, x, y, z, velX, velY, velZ, r, g, b, true));
break;
case ICE:
Minecraft.getMinecraft().effectRenderer.addEffect(new EntityIceFX(world, x, y, z, velX, velY, velZ, maxAge));
break;
case LEAF:
Minecraft.getMinecraft().effectRenderer.addEffect(new EntityLeafFX(world, x, y, z, velX, velY, velZ, maxAge));
break;
case MAGIC_BUBBLE:
Minecraft.getMinecraft().effectRenderer.addEffect(new EntityMagicBubbleFX(world, x, y, z, velX, velY, velZ));
break;
case MAGIC_FIRE:
Minecraft.getMinecraft().effectRenderer.addEffect(new EntityMagicFireFX(world, x, y, z, velX, velY, velZ, maxAge, r == 0 ? 1 + world.rand.nextFloat() : r));
break;
case PATH:
Minecraft.getMinecraft().effectRenderer.addEffect(new EntityPathFX(world, x, y, z, velX, velY, velZ, r, g, b, maxAge));
break;
case SNOW:
Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySnowFX(world, x, y, z, velX, velY, velZ));
break;
case SPARK:
Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySparkFX(world, x, y, z, velX, velY, velZ));
break;
case SPARKLE:
Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySparkleFX(world, x, y, z, velX, velY, velZ, r, g, b, maxAge, doGravity));
break;
}
}
@Override
public void spawnDigParticle(World world, double x, double y, double z, double velX, double velY, double velZ, Block block){
Minecraft.getMinecraft().effectRenderer.addEffect(new EntityDiggingFX(world, x, y, z, velX, velY, velZ, block, 0));
}
@Override
public void spawnTornadoParticle(World world, double x, double y, double z, double velX, double velZ, double radius, int maxAge, Block block, int metadata){
Minecraft.getMinecraft().effectRenderer.addEffect(new EntityTornadoFX(world, maxAge, x, z, radius, y, velX, velZ, block, metadata, world.rand.nextInt(6)));
}
@Override
public void playMovingSound(Entity entity, String soundName, float volume, float pitch, boolean repeat){
Minecraft.getMinecraft().getSoundHandler().playSound(new MovingSoundEntity(entity, soundName, volume, pitch, repeat));
public double getConjuredBowDurability(ItemStack stack){
EntityPlayer player = Minecraft.getMinecraft().player;
if(player.getActiveItemStack() == stack){
return (double)(stack.getItemDamage() + (player.getItemInUseMaxCount())) / (double)stack.getMaxDamage();
}
return super.getConjuredBowDurability(stack);
}
// SECTION Particles
// ===============================================================================================================
@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){
// 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!)
// 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(r, 0, 1);
g = MathHelper.clamp(g, 0, 1);
b = MathHelper.clamp(b, 0, 1);
switch(type){
case BLIZZARD:
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleBlizzard(world, maxAge, x, z, radius, y));
break;
case BRIGHT_DUST:
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleDust(world, x, y, z, velX, velY, velZ, r, g, b, false));
break;
case DARK_MAGIC:
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleDarkMagic(world, x, y, z, velX, velY, velZ, r, g, b));
break;
case DUST:
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleDust(world, x, y, z, velX, velY, velZ, r, g, b, true));
break;
case ICE:
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleIce(world, x, y, z, velX, velY, velZ, maxAge));
break;
case LEAF:
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleLeaf(world, x, y, z, velX, velY, velZ, maxAge));
break;
case MAGIC_BUBBLE:
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleGiantBubble(world, x, y, z, velX, velY, velZ));
break;
case MAGIC_FIRE:
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleMagicFlame(world, x, y, z, velX, velY, velZ, maxAge, r == 0 ? 1 + world.rand.nextFloat() : r));
break;
case PATH:
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticlePath(world, x, y, z, velX, velY, velZ, r, g, b, maxAge));
break;
case SNOW:
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleSnow(world, x, y, z, velX, velY, velZ));
break;
case SPARK:
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleSpark(world, x, y, z, velX, velY, velZ));
break;
case SPARKLE:
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleSparkle(world, x, y, z, velX, velY, velZ, r, g, b, maxAge, doGravity));
break;
case SPARKLE_ROTATING:
Minecraft.getMinecraft().effectRenderer.addEffect(new ParticleRotatingSparkle(world, maxAge, x, z, radius, y, r, g, b));
break;
default:
break;
}
}
@Override
public void spawnTornadoParticle(World world, double x, double y, double z, double velX, double velZ, double radius, int maxAge,
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
// ===============================================================================================================
@Override
public void handleCastSpellPacket(PacketCastSpell.Message message){
World world = Minecraft.getMinecraft().theWorld;
World world = Minecraft.getMinecraft().world;
Entity caster = world.getEntityByID(message.casterID);
Entity target = world.getEntityByID(message.targetID);
Spell spell = Spell.get(message.spellID);
// Should always be true
if(caster instanceof EntityPlayer){
ItemStack stack = ((EntityPlayer)caster).getHeldItem();
if(stack != null) ((EntityPlayer)caster).setItemInUse(stack, stack.getMaxItemUseDuration());
((EntityPlayer)caster).setActiveHand(message.hand);
// Duration isn't needed because it only ever affects things server-side, and anything that is
// seen client-side gets synced elsewhere.
spell.cast(world, (EntityPlayer)caster, 0, message.damageMultiplier, message.rangeMultiplier, 1, message.blastMultiplier);
// Updates the spell discovery data client-side. Could be done by calling sync(), but that means sending
// another packet unnecessarily.
if(ExtendedPlayer.get((EntityPlayer)caster) != null){
ExtendedPlayer.get((EntityPlayer)caster).discoverSpell(spell);
spell.cast(world, (EntityPlayer)caster, message.hand, 0, message.modifiers);
Source source = Source.OTHER;
Item item = ((EntityPlayer)caster).getHeldItem(message.hand).getItem();
if(item instanceof ItemWand){
source = Source.WAND;
}else if(item instanceof ItemScroll){
source = Source.SCROLL;
}
}
else if(caster instanceof EntityLiving && target instanceof EntityLivingBase){
spell.cast(world, (EntityLiving)caster, (EntityLivingBase)target, message.damageMultiplier, message.rangeMultiplier, 1, message.blastMultiplier);
// 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.
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post((EntityPlayer)caster, spell, message.modifiers, source));
}else{
Wizardry.logger.warn("Recieved a PacketCastSpell, but the caster ID was not the ID of a player");
}
}
@Override
public void handleCastContinuousSpellPacket(PacketCastContinuousSpell.Message message){
World world = Minecraft.getMinecraft().world;
Entity caster = world.getEntityByID(message.casterID);
Spell spell = Spell.get(message.spellID);
// Should always be true
if(caster instanceof EntityPlayer){
WizardData data = WizardData.get((EntityPlayer)caster);
if(data != null){
if(data.isCasting()){
WizardData.get((EntityPlayer)caster).stopCastingContinuousSpell();
}else{
WizardData.get((EntityPlayer)caster).startCastingContinuousSpell(spell, message.modifiers);
}
}
}else{
Wizardry.logger.warn("Recieved a PacketCastContinuousSpell, but the caster ID was not the ID of a player");
}
}
@Override
public void handleNPCCastSpellPacket(PacketNPCCastSpell.Message message){
World world = Minecraft.getMinecraft().world;
Entity caster = world.getEntityByID(message.casterID);
Entity target = message.targetID == -1 ? null : world.getEntityByID(message.targetID);
Spell spell = Spell.get(message.spellID);
// Should always be true
if(caster instanceof EntityLiving){
if(target instanceof EntityLivingBase){
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.
MinecraftForge.EVENT_BUS.post(new SpellCastEvent.Post((EntityLiving)caster, spell, message.modifiers, Source.NPC));
}
if(caster instanceof ISpellCaster){
if(spell.isContinuous || spell instanceof None){
((ISpellCaster)caster).setContinuousSpell(spell);
((EntityLiving)caster).setAttackTarget((EntityLivingBase)target);
}
}
}else{
Wizardry.logger.warn("Recieved a PacketNPCCastSpell, but the caster ID was not the ID of an EntityLiving");
}
}
@Override
public void handleTransportationPacket(PacketTransportation.Message message){
World world = Minecraft.getMinecraft().theWorld;
World world = Minecraft.getMinecraft().world;
Entity caster = world.getEntityByID(message.casterID);
for(int i=0; i<20; i++){
// 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);
for(int i = 0; i < 20; i++){
double radius = 1;
double angle = world.rand.nextDouble()*Math.PI*2;
double x = caster.posX + radius*Math.cos(angle);
double y = WizardryUtilities.getEntityFeetPos(caster) + world.rand.nextDouble()*2;
double z = caster.posZ + radius*Math.sin(angle);
Minecraft.getMinecraft().effectRenderer.addEffect(new EntitySparkleFX(world, x, y, z, 0, 0.02, 0, 0.6f, 1.0f, 0.6f, 80 + world.rand.nextInt(10)));
double angle = world.rand.nextDouble() * Math.PI * 2;
double x = caster.posX + radius * Math.cos(angle);
double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble() * 2;
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)));
}
for(int i=0; i<20; i++){
for(int i = 0; i < 20; i++){
double radius = 1;
double angle = world.rand.nextDouble()*Math.PI*2;
double x = caster.posX + radius*Math.cos(angle);
double y = WizardryUtilities.getEntityFeetPos(caster) + world.rand.nextDouble()*2;
double z = caster.posZ + radius*Math.sin(angle);
world.spawnParticle("happyVillager", x, y, z, 0, 0.02, 0);
double angle = world.rand.nextDouble() * Math.PI * 2;
double x = caster.posX + radius * Math.cos(angle);
double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble() * 2;
double z = caster.posZ + radius * Math.sin(angle);
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 angle = world.rand.nextDouble()*Math.PI*2;
double x = caster.posX + radius*Math.cos(angle);
double y = WizardryUtilities.getEntityFeetPos(caster) + world.rand.nextDouble()*2;
double z = caster.posZ + radius*Math.sin(angle);
world.spawnParticle("enchantmenttable", x, y, z, 0, 0.02, 0);
double angle = world.rand.nextDouble() * Math.PI * 2;
double x = caster.posX + radius * Math.cos(angle);
double y = caster.getEntityBoundingBox().minY + world.rand.nextDouble() * 2;
double z = caster.posZ + radius * Math.sin(angle);
world.spawnParticle(EnumParticleTypes.ENCHANTMENT_TABLE, x, y, z, 0, 0.02, 0);
}
}
@Override
public void handlePlayerSyncPacket(Message message){
ExtendedPlayer properties = ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer);
WizardData properties = WizardData.get(Minecraft.getMinecraft().player);
if(properties != null){
properties.spellsDiscovered = message.spellsDiscovered;
if(message.selectedMinionID == -1){
properties.selectedMinion = null;
}else{
Entity entity = Minecraft.getMinecraft().theWorld.getEntityByID(message.selectedMinionID);
if(entity instanceof EntitySummonedCreature){
properties.selectedMinion = new WeakReference(entity);
Entity entity = Minecraft.getMinecraft().world.getEntityByID(message.selectedMinionID);
if(entity instanceof ISummonedCreature){
properties.selectedMinion = new WeakReference<ISummonedCreature>((ISummonedCreature)entity);
}else{
properties.selectedMinion = null;
}
}
}
}
@Override
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.randomDescriptions = new HashMap<Spell, String>();
for(Spell spell : Spell.getSpells(Spell.allSpells)){
// -1 because the none spell isn't included
data.randomNames.put(spell, message.names.get(spell.id() - 1));
data.randomDescriptions.put(spell, message.descriptions.get(spell.id() - 1));
}
}
@Override
public void handleCastContinuousSpellPacket(PacketCastContinuousSpell.Message message){
World world = Minecraft.getMinecraft().theWorld;
Entity caster = world.getEntityByID(message.casterID);
Spell spell = Spell.get(message.spellID);
// This should always be true
if(caster instanceof EntityPlayer){
ExtendedPlayer properties = ExtendedPlayer.get((EntityPlayer)caster);
if(properties != null){
if(properties.isCasting()){
ExtendedPlayer.get((EntityPlayer)caster).stopCastingContinuousSpell();
}else{
ExtendedPlayer.get((EntityPlayer)caster).startCastingContinuousSpell(spell, message.damageMultiplier, message.rangeMultiplier, 1, message.blastMultiplier);
}
}
}
public void handleClairvoyancePacket(electroblob.wizardry.packet.PacketClairvoyance.Message message){
Clairvoyance.spawnPathPaticles(Minecraft.getMinecraft().world, message.path, message.durationMultiplier);
}
// SECTION Rendering
// ===============================================================================================================
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");
/** Static instance of the statue renderer, used to access the block breaking texture. */
public static RenderStatue renderStatue;
@Override
public void handleClairvoyancePacket(electroblob.wizardry.packet.PacketClairvoyance.Message message) {
Clairvoyance.spawnPathPaticles(Minecraft.getMinecraft().theWorld, message.path, message.durationMultiplier);
public void initialiseLayers(){
LayerStone.initialiseLayers();
}
@Override
public double getWandDisplayDamage(ItemStack stack){
ExtendedPlayer properties = ExtendedPlayer.get(net.minecraft.client.Minecraft.getMinecraft().thePlayer);
// If the player is creative or this wand is not the wand being used, the arbitrary placeholder damage is not displayed.
if(net.minecraft.client.Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode || net.minecraft.client.Minecraft.getMinecraft().thePlayer.getHeldItem() != stack){
return (double)stack.getItemDamageForDisplay() / (double)stack.getMaxDamage();
}else{
return (double)(stack.getItemDamageForDisplay() + properties.damageToApply) / (double)stack.getMaxDamage();
}
}
@Override
public int getConjuredItemDisplayDamage(ItemStack stack){
if(stack.getItem() instanceof ItemSpectralSword){
ExtendedPlayer properties = ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer);
return stack.getItemDamage() + properties.conjuredSwordDuration;
}else if(stack.getItem() instanceof ItemSpectralPickaxe){
ExtendedPlayer properties = ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer);
return stack.getItemDamage() + properties.conjuredPickaxeDuration;
}else if(stack.getItem() instanceof ItemSpectralBow){
ExtendedPlayer properties = ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer);
return stack.getItemDamage() + properties.conjuredBowDuration;
}else if(stack.getItem() instanceof ItemSpectralArmour){
ExtendedPlayer properties = ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer);
return stack.getItemDamage() + properties.conjuredArmourDuration;
}else if(stack.getItem() instanceof ItemFlamingAxe){
ExtendedPlayer properties = ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer);
return stack.getItemDamage() + properties.flamingAxeDuration;
}else if(stack.getItem() instanceof ItemFrostAxe){
ExtendedPlayer properties = ExtendedPlayer.get(Minecraft.getMinecraft().thePlayer);
return stack.getItemDamage() + properties.frostAxeDuration;
}
return 0;
}
@Override
public void registerRenderers() {
mixedFontRenderer = new MixedFontRenderer(Minecraft.getMinecraft().gameSettings,
new ResourceLocation("textures/font/ascii.png"), Minecraft.getMinecraft().renderEngine, false);
public void registerRenderers(){
// Minions
RenderingRegistry.registerEntityRenderingHandler(EntityZombieMinion.class, new RenderZombieMinion());
RenderingRegistry.registerEntityRenderingHandler(EntitySkeletonMinion.class, new RenderSkeletonMinion());
RenderingRegistry.registerEntityRenderingHandler(EntitySpiderMinion.class, new RenderSpiderMinion());
RenderingRegistry.registerEntityRenderingHandler(EntityBlazeMinion.class, new RenderWraithMinion(new ResourceLocation("textures/entity/blaze.png")));
RenderingRegistry.registerEntityRenderingHandler(EntityIceWraith.class, new RenderWraithMinion(new ResourceLocation("wizardry:textures/entity/ice_wraith.png")));
RenderingRegistry.registerEntityRenderingHandler(EntityLightningWraith.class, new RenderWraithMinion(new ResourceLocation("wizardry:textures/entity/lightning_wraith.png")));
RenderingRegistry.registerEntityRenderingHandler(EntityMagicSlime.class, new RenderMagicSlime(new ModelSlime(16), new ModelSlime(0), 0.25F));
RenderingRegistry.registerEntityRenderingHandler(EntityIceGiant.class, new RenderIceGiant());
RenderingRegistry.registerEntityRenderingHandler(EntityPhoenix.class, new RenderPhoenix());
RenderingRegistry.registerEntityRenderingHandler(EntitySilverfishMinion.class, new RenderSilverfishMinion());
// 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.
// An anonymous class in a lambda expression! No point writing a separate class really, is there?
RenderingRegistry.registerEntityRenderingHandler(EntityLightningWraith.class, manager -> new RenderBlaze(manager){
@Override
protected ResourceLocation getEntityTexture(EntityBlaze entity){
return LIGHTNING_WRAITH_TEXTURE;
}
});
RenderingRegistry.registerEntityRenderingHandler(EntityIceWraith.class, manager -> new RenderBlaze(manager){
@Override
protected ResourceLocation getEntityTexture(EntityBlaze entity){
return ICE_WRAITH_TEXTURE;
}
});
RenderingRegistry.registerEntityRenderingHandler(EntityIceGiant.class, RenderIceGiant::new);
RenderingRegistry.registerEntityRenderingHandler(EntityPhoenix.class, RenderPhoenix::new);
// Projectiles
RenderingRegistry.registerEntityRenderingHandler(EntityMagicMissile.class, new RenderMagicArrow(new ResourceLocation("wizardry:textures/entity/magic_missile.png"), false, 8.0, 4.0, 16, 9, false));
RenderingRegistry.registerEntityRenderingHandler(EntityIceShard.class, new RenderMagicArrow(new ResourceLocation("wizardry:textures/entity/ice_shard.png"), false, 8.0, 2.0, 16, 5, false));
RenderingRegistry.registerEntityRenderingHandler(EntityLightningArrow.class, new RenderMagicArrow(new ResourceLocation("wizardry:textures/entity/lightning_arrow.png"), true, 8.0, 2.0, 16, 5, false));
RenderingRegistry.registerEntityRenderingHandler(EntityDart.class, new RenderMagicArrow(new ResourceLocation("wizardry:textures/entity/dart.png"), false, 8.0, 2.0, 16, 5, true));
RenderingRegistry.registerEntityRenderingHandler(EntityIceLance.class, new RenderMagicArrow(new ResourceLocation("wizardry:textures/entity/ice_lance.png"), false, 16.0, 3.0, 22, 5, true));
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(EntityIceShard.class, manager -> new RenderMagicArrow(manager,
new ResourceLocation(Wizardry.MODID, "textures/entity/ice_shard.png"), false, 8.0, 2.0, 16, 5, 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(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, new RenderForceArrow());
RenderingRegistry.registerEntityRenderingHandler(EntityForceArrow.class, RenderForceArrow::new);
// Creatures
RenderingRegistry.registerEntityRenderingHandler(EntitySpiritWolf.class, new RenderSpiritWolf(new ModelSpiritWolf(), new ModelSpiritWolf(), 0.5f));
RenderingRegistry.registerEntityRenderingHandler(EntitySpiritHorse.class, new RenderSpiritHorse(new ModelSpiritHorse(), 0.5f));
RenderingRegistry.registerEntityRenderingHandler(EntityWizard.class, new RenderWizard());
RenderingRegistry.registerEntityRenderingHandler(EntityEvilWizard.class, new RenderEvilWizard());
RenderingRegistry.registerEntityRenderingHandler(EntityDecoy.class, new RenderDecoy());
RenderingRegistry.registerEntityRenderingHandler(EntitySpiritWolf.class, manager -> new RenderSpiritWolf(manager));
RenderingRegistry.registerEntityRenderingHandler(EntitySpiritHorse.class, manager -> new RenderSpiritHorse(manager));
RenderingRegistry.registerEntityRenderingHandler(EntityWizard.class, RenderWizard::new);
RenderingRegistry.registerEntityRenderingHandler(EntityEvilWizard.class, RenderEvilWizard::new);
RenderingRegistry.registerEntityRenderingHandler(EntityDecoy.class, RenderDecoy::new);
// Throwables
RenderingRegistry.registerEntityRenderingHandler(EntitySparkBomb.class, new RenderProjectile(0.6f, new ResourceLocation("wizardry:textures/entity/spark_bomb.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntityFirebomb.class, new RenderProjectile(0.6f, new ResourceLocation("wizardry:textures/items/firebomb.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntityPoisonBomb.class, new RenderProjectile(0.6f, new ResourceLocation("wizardry:textures/items/poison_bomb.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntityIceCharge.class, new RenderProjectile(0.6f, new ResourceLocation("wizardry:textures/entity/ice_charge.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntityForceOrb.class, new RenderProjectile(0.7f, new ResourceLocation("wizardry:textures/entity/force_orb.png"), true));
RenderingRegistry.registerEntityRenderingHandler(EntitySpark.class, new RenderProjectile(0.4f, new ResourceLocation("wizardry:textures/entity/spark.png"), true));
RenderingRegistry.registerEntityRenderingHandler(EntityDarknessOrb.class, new RenderProjectile(0.6f, new ResourceLocation("wizardry:textures/entity/darkness_orb.png"), true));
RenderingRegistry.registerEntityRenderingHandler(EntityFirebolt.class, new RenderProjectile(0.2f, new ResourceLocation("wizardry:textures/entity/firebolt.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntityLightningDisc.class, new RenderLightningDisc(new ResourceLocation("wizardry:textures/entity/lightning_sigil.png"), 2.0f));
RenderingRegistry.registerEntityRenderingHandler(EntitySmokeBomb.class, new RenderProjectile(0.6f, new ResourceLocation("wizardry:textures/items/smoke_bomb.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntitySparkBomb.class,
manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/entity/spark_bomb.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntityFirebomb.class,
manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/items/firebomb.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntityPoisonBomb.class,
manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/items/poison_bomb.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntityIceCharge.class,
manager -> new RenderProjectile(manager, 0.6f, new ResourceLocation(Wizardry.MODID, "textures/entity/ice_charge.png"), false));
RenderingRegistry.registerEntityRenderingHandler(EntityForceOrb.class,
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
RenderingRegistry.registerEntityRenderingHandler(EntityArc.class, new RenderArc());
RenderingRegistry.registerEntityRenderingHandler(EntityBlackHole.class, new RenderBlackHole());
RenderingRegistry.registerEntityRenderingHandler(EntityShield.class, new RenderBlank());
RenderingRegistry.registerEntityRenderingHandler(EntityMeteor.class, new RenderMeteor());
RenderingRegistry.registerEntityRenderingHandler(EntityBubble.class, new RenderBubble());
RenderingRegistry.registerEntityRenderingHandler(EntityHammer.class, new RenderHammer());
RenderingRegistry.registerEntityRenderingHandler(EntityFallingGrass.class, new RenderFallingGrass());
RenderingRegistry.registerEntityRenderingHandler(EntityIceSpike.class, new RenderIceSpike());
RenderingRegistry.registerEntityRenderingHandler(EntityArc.class, RenderArc::new);
RenderingRegistry.registerEntityRenderingHandler(EntityBlackHole.class, RenderBlackHole::new);
RenderingRegistry.registerEntityRenderingHandler(EntityShield.class, RenderBlank::new);
RenderingRegistry.registerEntityRenderingHandler(EntityBubble.class, RenderBubble::new);
RenderingRegistry.registerEntityRenderingHandler(EntityHammer.class, RenderHammer::new);
RenderingRegistry.registerEntityRenderingHandler(EntityIceSpike.class, RenderIceSpike::new);
// Stuff that doesn't render
RenderingRegistry.registerEntityRenderingHandler(EntityBlizzard.class, new RenderBlank());
RenderingRegistry.registerEntityRenderingHandler(EntityTornado.class, new RenderBlank());
RenderingRegistry.registerEntityRenderingHandler(EntityArrowRain.class, new RenderBlank());
RenderingRegistry.registerEntityRenderingHandler(EntityShadowWraith.class, new RenderBlank());
RenderingRegistry.registerEntityRenderingHandler(EntityForcefield.class, new RenderBlank());
RenderingRegistry.registerEntityRenderingHandler(EntityThunderbolt.class, new RenderBlank());
RenderingRegistry.registerEntityRenderingHandler(EntityStormElemental.class, new RenderBlank());
RenderingRegistry.registerEntityRenderingHandler(EntityEarthquake.class, new RenderBlank());
RenderingRegistry.registerEntityRenderingHandler(EntityHailstorm.class, new RenderBlank());
RenderingRegistry.registerEntityRenderingHandler(EntityBlizzard.class, RenderBlank::new);
RenderingRegistry.registerEntityRenderingHandler(EntityTornado.class, RenderBlank::new);
RenderingRegistry.registerEntityRenderingHandler(EntityArrowRain.class, RenderBlank::new);
RenderingRegistry.registerEntityRenderingHandler(EntityShadowWraith.class, RenderBlank::new);
RenderingRegistry.registerEntityRenderingHandler(EntityForcefield.class, RenderBlank::new);
RenderingRegistry.registerEntityRenderingHandler(EntityThunderbolt.class, RenderBlank::new);
RenderingRegistry.registerEntityRenderingHandler(EntityStormElemental.class, RenderBlank::new);
RenderingRegistry.registerEntityRenderingHandler(EntityEarthquake.class, RenderBlank::new);
RenderingRegistry.registerEntityRenderingHandler(EntityHailstorm.class, RenderBlank::new);
// Runes on ground
RenderingRegistry.registerEntityRenderingHandler(EntityHealAura.class, new RenderSigil(new ResourceLocation("wizardry:textures/entity/healing_aura.png"), 5.0f, false));
RenderingRegistry.registerEntityRenderingHandler(EntityFireSigil.class, new RenderSigil(new ResourceLocation("wizardry:textures/entity/fire_sigil.png"), 2.0f, true));
RenderingRegistry.registerEntityRenderingHandler(EntityFrostSigil.class, new RenderSigil(new ResourceLocation("wizardry:textures/entity/frost_sigil.png"), 2.0f, true));
RenderingRegistry.registerEntityRenderingHandler(EntityLightningSigil.class, new RenderSigil(new ResourceLocation("wizardry:textures/entity/lightning_sigil.png"), 2.0f, true));
RenderingRegistry.registerEntityRenderingHandler(EntityFireRing.class, new RenderFireRing(new ResourceLocation("wizardry:textures/entity/ring_of_fire.png"), 5.0f));
RenderingRegistry.registerEntityRenderingHandler(EntityDecay.class, new RenderDecay());
RenderingRegistry.registerEntityRenderingHandler(EntityLightningPulse.class, new RenderLightningPulse(8.0f));
//RenderingRegistry.registerBlockHandler(new RenderSigilBlock());
RenderingRegistry.registerEntityRenderingHandler(EntityHealAura.class,
manager -> new RenderSigil(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/healing_aura.png"), 5.0f, false));
RenderingRegistry.registerEntityRenderingHandler(EntityFireSigil.class,
manager -> new RenderSigil(manager, new ResourceLocation(Wizardry.MODID, "textures/entity/fire_sigil.png"), 2.0f, true));
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(EntityLightningPulse.class, manager -> new RenderLightningPulse(manager, 8.0f));
// TESRs
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityArcaneWorkbench.class, new RenderArcaneWorkbench());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityStatue.class, new RenderStatue());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityStatue.class, renderStatue = new RenderStatue());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMagicLight.class, new RenderMagicLight());
// Items
MinecraftForgeClient.registerItemRenderer(Wizardry.spectralSword, new RenderTranslucentItem());
MinecraftForgeClient.registerItemRenderer(Wizardry.spectralPickaxe, new RenderTranslucentItem());
MinecraftForgeClient.registerItemRenderer(Wizardry.spectralBow, new RenderTranslucentItem());
MinecraftForgeClient.registerItemRenderer(Wizardry.spectralHelmet, new RenderTranslucentItem());
MinecraftForgeClient.registerItemRenderer(Wizardry.spectralChestplate, new RenderTranslucentItem());
MinecraftForgeClient.registerItemRenderer(Wizardry.spectralLeggings, new RenderTranslucentItem());
MinecraftForgeClient.registerItemRenderer(Wizardry.spectralBoots, new RenderTranslucentItem());
}
}
@@ -1,77 +1,81 @@
package electroblob.wizardry.client;
import cpw.mods.fml.client.config.GuiButtonExt;
import cpw.mods.fml.client.config.GuiEditArray;
import cpw.mods.fml.client.config.GuiEditArrayEntries;
import cpw.mods.fml.client.config.GuiSelectString;
import cpw.mods.fml.client.config.GuiUtils;
import cpw.mods.fml.client.config.GuiEditArrayEntries.StringEntry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.EntityList;
import cpw.mods.fml.client.config.IConfigElement;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.I18n;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.client.config.GuiButtonExt;
import net.minecraftforge.fml.client.config.GuiEditArray;
import net.minecraftforge.fml.client.config.GuiEditArrayEntries;
import net.minecraftforge.fml.client.config.GuiEditArrayEntries.StringEntry;
import net.minecraftforge.fml.client.config.GuiSelectString;
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.
*/
public class EntityNameEntry extends StringEntry {
protected final GuiButtonExt btnValue;
protected Object entityClass;
public EntityNameEntry(GuiEditArray owningScreen, GuiEditArrayEntries owningEntryList, IConfigElement configElement, Object value)
{
super(owningScreen, owningEntryList, configElement, value);
this.btnValue = new GuiButtonExt(0, 0, 0, owningEntryList.controlWidth, 18, I18n.format(this.textFieldValue.getText()));
//this.btnValue.enabled = owningScreen.enabled;
}
public EntityNameEntry(GuiEditArray owningScreen, GuiEditArrayEntries owningEntryList, IConfigElement configElement,
Object value){
super(owningScreen, owningEntryList, configElement, value);
this.btnValue = new GuiButtonExt(0, 0, 0, owningEntryList.controlWidth, 18,
I18n.format(this.textFieldValue.getText()));
// this.btnValue.enabled = owningScreen.enabled;
}
@Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, Tessellator tessellator, 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;
@Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY,
boolean isSelected, float partialTicks){
//super.drawEntry(slotIndex, x, y, listWidth, slotHeight, mouseX, mouseY, isSelected, partial);
this.btnValue.x = listWidth / 4;
this.btnValue.y = y;
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);
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);
this.btnValue.drawButton(owningEntryList.mc, mouseX, mouseY);
}
this.btnValue.drawButton(owningEntryList.getMC(), mouseX, mouseY, partialTicks);
}
/**
* Returns true if the mouse has been pressed on this control.
*/
@Override
public boolean mousePressed(int index, int x, int y, int mouseEvent, int relativeX, int relativeY)
{
if (this.btnValue.mousePressed(owningEntryList.mc, x, y))
{
btnValue.func_146113_a(owningEntryList.mc.getSoundHandler());
Minecraft.getMinecraft().displayGuiScreen(new GuiSelectString(this.owningScreen, configElement, index, EntityList.classToStringMapping, this.getValue(), true));
owningEntryList.recalculateState();
return true;
}
@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;
}
return super.mousePressed(index, x, y, mouseEvent, relativeX, relativeY);
}
return super.mousePressed(index, x, y, mouseEvent, relativeX, relativeY);
}
/**
* Fired when the mouse button is released. Arguments: index, x, y, mouseEvent, relativeX, relativeY
*/
@Override
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
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
public Object getValue()
{
return this.textFieldValue.getText();
}
@Override
public Object getValue(){
return this.textFieldValue.getText();
}
}
@@ -1,90 +1,178 @@
package electroblob.wizardry.client;
import codechicken.nei.VisiblityData;
import codechicken.nei.api.INEIGuiHandler;
import codechicken.nei.api.TaggedInventoryArea;
import cpw.mods.fml.common.Optional.Interface;
import cpw.mods.fml.common.Optional.Method;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import electroblob.wizardry.ExtendedPlayer;
import org.lwjgl.input.Keyboard;
import electroblob.wizardry.SpellGlyphData;
import electroblob.wizardry.WandHelper;
import electroblob.wizardry.WizardData;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.constants.Element;
import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.packet.PacketControlInput;
import electroblob.wizardry.packet.WizardryPacketHandler;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.tileentity.ContainerArcaneWorkbench;
import electroblob.wizardry.tileentity.SlotWizardry;
import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench;
import java.awt.Rectangle;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import electroblob.wizardry.util.WandHelper;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
@Interface(iface = "codechicken.nei.api.INEIGuiHandler", modid = "NotEnoughItems")
public class GuiArcaneWorkbench extends GuiContainer implements INEIGuiHandler {
public class GuiArcaneWorkbench extends GuiContainer {
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 arcaneWorkbenchInventory;
private static final int tooltipWidth = 164;
private static final int tooltipHeight = 155;
public GuiArcaneWorkbench(InventoryPlayer invPlayer, TileEntityArcaneWorkbench entity) {
private final int tooltipWidth = 164;
// 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));
this.playerInventory = invPlayer;
this.arcaneWorkbenchInventory = entity;
xSize = 176;
xSize = xSizeNoTip;
ySize = 220;
}
@Override
public void drawScreen(int p_73863_1_, int p_73863_2_, float p_73863_3_){
if(this.hasWand()){
this.drawDefaultBackground();
// Tests if there is a wand in the workbench and edits the positioning accordingly
if(this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getHasStack() && this.inventorySlots
.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack().getItem() instanceof ItemWand){
xSize = xSizeNoTip + tooltipWidth;
guiLeft = (this.width - this.xSize) / 2;
this.applyBtn.x = (this.width - tooltipWidth) / 2 + 48;
}else{
xSize = xSizeNoTip;
guiLeft = (this.width - this.xSize) / 2;
this.applyBtn.x = this.width / 2 + 48;
}
if(this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getHasStack()){
this.applyBtn.enabled = true;
}else{
this.applyBtn.enabled = false;
}
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_);
}
/**
* Draw the foreground layer for the GuiContainer (everything in front of the items)
*/
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY){
@Override
public void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY){
this.fontRendererObj.drawString(this.arcaneWorkbenchInventory.hasCustomInventoryName() ? this.arcaneWorkbenchInventory.getInventoryName() : I18n.format(this.arcaneWorkbenchInventory.getInventoryName()), 8, 6, 4210752);
this.fontRendererObj.drawString(this.playerInventory.hasCustomInventoryName() ? this.playerInventory.getInventoryName() : I18n.format(this.playerInventory.getInventoryName()), 8, this.ySize - 96 + 2, 4210752);
GlStateManager.color(1F, 1F, 1F, 1F);
Minecraft.getMinecraft().renderEngine.bindTexture(texture);
if(this.hasWand()){
// Main inventory
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSizeNoTip, ySize);
// Changing slots
for(int i = 0; i < ContainerArcaneWorkbench.CRYSTAL_SLOT; i++){
Slot slot = this.inventorySlots.getSlot(i);
if(slot.xPos >= 0 && slot.yPos >= 0)
this.drawTexturedModalRect(guiLeft + slot.xPos - 10, guiTop + slot.yPos - 10, 0, 220, 36, 36);
}
// 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){
// Tooltip box
drawTexturedModalRect(guiLeft + xSizeNoTip, guiTop, xSizeNoTip, 0, 256 - xSizeNoTip - 4, ySize);
drawTexturedModalRect(guiLeft + 252, guiTop, xSizeNoTip + 4, 0, tooltipWidth - 2 * (256 - xSizeNoTip - 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();
this.fontRendererObj.drawStringWithShadow("\u00A7f" + wand.getDisplayName(), xSize + 6, 6, 0);
this.fontRendererObj.drawStringWithShadow("\u00A77" + StatCollector.translateToLocal("container.arcaneWorkbench.mana") + " " + (wand.getMaxDamage() - wand.getItemDamage()) + "/" + wand.getMaxDamage(), xSize + 6, 20, 0);
Spell[] spells = WandHelper.getSpells(wand);
int i = 0;
for(Spell spell : spells){
boolean discovered = true;
if(!this.mc.player.capabilities.isCreativeMode && WizardData.get(this.mc.player) != null){
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
// mods to add their own.
Minecraft.getMinecraft().renderEngine
.bindTexture(discovered ? spell.element.getIcon() : Element.MAGIC.getIcon());
// Renders the little element icon
WizardryUtilities.drawTexturedRect(guiLeft + xSizeNoTip + 5, guiTop + 34 + 10 * i++, 8, 8);
}
int x = 0;
int y = guiTop + 50 + spells.length * 10;
// Look how much shorter this is with the WandHelper class!
for(Item item : WandHelper.getSpecialUpgrades()){
int level = WandHelper.getUpgradeLevel(wand, item);
if(level > 0){
ItemStack stack = new ItemStack(item, level);
GlStateManager.enableDepth();
this.itemRender.renderItemAndEffectIntoGUI(stack, guiLeft + xSizeNoTip + 6 + x, y);
this.itemRender.renderItemOverlayIntoGUI(this.fontRenderer, stack, guiLeft + xSizeNoTip + 6 + x, y,
null);
x += 18;
GlStateManager.disableDepth();
}
}
}
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!
GlStateManager.disableBlend();
GlStateManager.enableAlpha();
}
@Override
protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY){
this.fontRenderer
.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){
ItemStack wand = this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack();
this.fontRenderer.drawStringWithShadow("\u00A7f" + wand.getDisplayName(), xSizeNoTip + 6, 6, 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);
@@ -94,34 +182,37 @@ public class GuiArcaneWorkbench extends GuiContainer implements INEIGuiHandler {
boolean discovered = true;
if(!this.mc.thePlayer.capabilities.isCreativeMode && ExtendedPlayer.get(this.mc.thePlayer) != null){
discovered = ExtendedPlayer.get(this.mc.thePlayer).hasSpellBeenDiscovered(spell);
if(!this.mc.player.capabilities.isCreativeMode && WizardData.get(this.mc.player) != null){
discovered = WizardData.get(this.mc.player).hasSpellBeenDiscovered(spell);
}
if(discovered){
this.fontRendererObj.drawStringWithShadow(spell.getDisplayNameWithFormatting(), xSize + 16, y, 0);
this.fontRenderer.drawStringWithShadow(spell.getDisplayNameWithFormatting(), xSizeNoTip + 16, y, 0);
}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;
}
if(WandHelper.getTotalUpgrades(wand) > 0){
this.fontRendererObj.drawStringWithShadow("\u00A7f" + StatCollector.translateToLocal("container.arcaneWorkbench.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;
y = guiTop + 50 + spells.length*10;
y = 50 + spells.length * 10;
// Wand upgrade tooltips
for(Item item : WandHelper.getSpecialUpgrades()){
int level = WandHelper.getUpgradeLevel(wand, item);
if(level > 0){
// No idea why this is -16 instead of +6, but it works!
if(isPointInRegion(xSize -16 + x, y, 16, 16, mouseX + guiLeft, mouseY + guiTop)){
// The javadoc for isPointInRegion is ambiguous; what it means is that the REGION is
// relative to the GUI but the POINT isn't.
if(isPointInRegion(xSizeNoTip + 6 + x, y, 16, 16, mouseX, mouseY)){
ItemStack stack = new ItemStack(item, level);
this.drawItemStackTooltip(stack, mouseX - guiLeft, mouseY - guiTop);
this.renderToolTip(stack, mouseX - guiLeft, mouseY - guiTop);
}
x += 18;
}
@@ -131,295 +222,30 @@ public class GuiArcaneWorkbench extends GuiContainer implements INEIGuiHandler {
}
@Override
public void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY) {
GL11.glColor4f(1F, 1F, 1F, 1F);
Minecraft.getMinecraft().renderEngine.bindTexture(texture);
// Main inventory
drawTexturedModalRect(guiLeft, guiTop, 0, 0, xSize, ySize);
// Changing slots
for(int i=0; i<ContainerArcaneWorkbench.CRYSTAL_SLOT; i++){
Slot slot = this.inventorySlots.getSlot(i);
if(slot.xDisplayPosition >=0 && slot.yDisplayPosition >= 0)
this.drawTexturedModalRect(guiLeft + slot.xDisplayPosition - 10, guiTop + slot.yDisplayPosition - 10,
64, 220, 36, 36);
}
// Tooltip only drawn if there is a wand
if(this.hasWand()){
// Tooltip box
drawTexturedModalRect(guiLeft + xSize, guiTop, xSize, 0, 256 - xSize - 4, ySize);
drawTexturedModalRect(guiLeft + 252, guiTop, xSize + 4, 0, tooltipWidth - 2*(256 - xSize - 4), ySize);
drawTexturedModalRect(guiLeft + xSize + tooltipWidth - (256 - xSize - 4), guiTop, xSize + 4, 0, 256 - xSize - 4, ySize);
ItemStack wand = this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack();
Spell[] spells = WandHelper.getSpells(wand);
int i=0;
for(Spell spell : spells){
boolean discovered = true;
if(!this.mc.thePlayer.capabilities.isCreativeMode && ExtendedPlayer.get(this.mc.thePlayer) != null){
discovered = ExtendedPlayer.get(this.mc.thePlayer).hasSpellBeenDiscovered(spell);
}
// Renders the little element icon if there is an element
this.drawTexturedModalRect(guiLeft + xSize + 5, guiTop + 34 + 10*i++, discovered ? spell.element.ordinal()*8 : 0, 220, 8, 8);
}
int x = 0;
int y = guiTop + 50 + spells.length*10;
// Look how much shorter this is with the WandHelper class!
for(Item item : WandHelper.getSpecialUpgrades()){
int level = WandHelper.getUpgradeLevel(wand, item);
if(level > 0){
ItemStack stack = new ItemStack(item, level);
itemRender.renderItemAndEffectIntoGUI(this.fontRendererObj, this.mc.getTextureManager(), stack, guiLeft + xSize + 6 + x, y);
itemRender.renderItemOverlayIntoGUI(this.fontRendererObj, this.mc.getTextureManager(), stack, guiLeft + xSize + 6 + x, y);
x += 18;
}
}
}
Minecraft.getMinecraft().renderEngine.bindTexture(texture);
for(Object object : this.inventorySlots.inventorySlots){
if(object instanceof Slot){
Slot slot = (Slot)object;
// Tests whether I have added a background texture and if so actually renders it
if(!slot.getHasStack() && slot instanceof SlotWizardry && ((SlotWizardry)slot).backgroundIndex > -1){
// Taken directly from GuiContainer#func_146977_a, with a few changes.
this.zLevel = 100.0F;
itemRender.zLevel = 100.0F;
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_BLEND);
this.drawTexturedModalRect(guiLeft + slot.xDisplayPosition, guiTop + slot.yDisplayPosition, ((SlotWizardry)slot).backgroundIndex*16, 240, 16, 16);
GL11.glDisable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_LIGHTING);
itemRender.zLevel = 0.0F;
this.zLevel = 0.0F;
}
}
}
}
@SuppressWarnings("unchecked")
public void initGui()
{
this.mc.thePlayer.openContainer = this.inventorySlots;
public void initGui(){
this.mc.player.openContainer = this.inventorySlots;
this.guiLeft = (this.width - this.xSize) / 2;
this.guiTop = (this.height - this.ySize) / 2;
Keyboard.enableRepeatEvents(true);
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));
}
public void onGuiClosed()
{
@Override
public void onGuiClosed(){
super.onGuiClosed();
Keyboard.enableRepeatEvents(false);
}
/**
* Fired when a control is clicked. This is the equivalent of ActionListener.actionPerformed(ActionEvent e).
*/
protected void actionPerformed(GuiButton par1GuiButton)
{
if (par1GuiButton.enabled)
{
if (par1GuiButton.id == 0)
{
@Override
protected void actionPerformed(GuiButton button){
if(button.enabled){
if(button.id == 0){
// Packet building
IMessage msg = new PacketControlInput.Message(0);
IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.APPLY_BUTTON);
WizardryPacketHandler.net.sendToServer(msg);
}
}
}
protected boolean isPointInRegion(int par1, int par2, int par3, int par4, int par5, int par6)
{
int k1 = this.width/2 - xSize/2;
int l1 = this.height/2 - this.ySize/2;
par5 -= k1;
par6 -= l1;
return par5 >= par1 - 1 && par5 < par1 + par3 + 1 && par6 >= par2 - 1 && par6 < par2 + par4 + 1;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
protected void drawItemStackTooltip(ItemStack par1ItemStack, int par2, int par3)
{
List list = par1ItemStack.getTooltip(this.mc.thePlayer, this.mc.gameSettings.advancedItemTooltips);
for (int k = 0; k < list.size(); ++k)
{
if (k == 0)
{
list.set(k, par1ItemStack.getRarity().rarityColor + (String)list.get(k));
}
else
{
list.set(k, EnumChatFormatting.GRAY + (String)list.get(k));
}
}
FontRenderer font = par1ItemStack.getItem().getFontRenderer(par1ItemStack);
drawHoveringText(list, par2, par3, (font == null ? fontRendererObj : font));
}
@SuppressWarnings("rawtypes")
protected void drawHoveringText(List par1List, int par2, int par3, FontRenderer font)
{
if (!par1List.isEmpty())
{
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
RenderHelper.disableStandardItemLighting();
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_DEPTH_TEST);
int k = 0;
Iterator iterator = par1List.iterator();
while (iterator.hasNext())
{
String s = (String)iterator.next();
int l = font.getStringWidth(s);
if (l > k)
{
k = l;
}
}
int i1 = par2 + 12;
int j1 = par3 - 12;
int k1 = 8;
if (par1List.size() > 1)
{
k1 += 2 + (par1List.size() - 1) * 10;
}
if (i1 + k > this.width)
{
i1 -= 28 + k;
}
if (j1 + k1 + 6 > this.height)
{
j1 = this.height - k1 - 6;
}
this.zLevel = 300.0F;
itemRender.zLevel = 300.0F;
int l1 = -267386864;
this.drawGradientRect(i1 - 3, j1 - 4, i1 + k + 3, j1 - 3, l1, l1);
this.drawGradientRect(i1 - 3, j1 + k1 + 3, i1 + k + 3, j1 + k1 + 4, l1, l1);
this.drawGradientRect(i1 - 3, j1 - 3, i1 + k + 3, j1 + k1 + 3, l1, l1);
this.drawGradientRect(i1 - 4, j1 - 3, i1 - 3, j1 + k1 + 3, l1, l1);
this.drawGradientRect(i1 + k + 3, j1 - 3, i1 + k + 4, j1 + k1 + 3, l1, l1);
int i2 = 1347420415;
int j2 = (i2 & 16711422) >> 1 | i2 & -16777216;
this.drawGradientRect(i1 - 3, j1 - 3 + 1, i1 - 3 + 1, j1 + k1 + 3 - 1, i2, j2);
this.drawGradientRect(i1 + k + 2, j1 - 3 + 1, i1 + k + 3, j1 + k1 + 3 - 1, i2, j2);
this.drawGradientRect(i1 - 3, j1 - 3, i1 + k + 3, j1 - 3 + 1, i2, i2);
this.drawGradientRect(i1 - 3, j1 + k1 + 2, i1 + k + 3, j1 + k1 + 3, j2, j2);
for(int k2 = 0; k2 < par1List.size(); ++k2){
String s1 = (String)par1List.get(k2);
font.drawStringWithShadow(s1, i1, j1, -1);
if(k2 == 0){
j1 += 2;
}
j1 += 10;
}
this.zLevel = 0.0F;
itemRender.zLevel = 0.0F;
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_DEPTH_TEST);
RenderHelper.enableStandardItemLighting();
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
}
}
/**
* @return A list of TaggedInventoryAreas that will be used with the savestates.
*/
@Method(modid = "NotEnoughItems")
@Override
public List<TaggedInventoryArea> getInventoryAreas(GuiContainer gui) {
return Collections.emptyList();
}
/**
* NEI will give the specified item to the InventoryRange returned if the player's inventory is full.
* Should not return null, just an empty list
*/
@Method(modid = "NotEnoughItems")
@Override
public Iterable<Integer> getItemSpawnSlots(GuiContainer gui, ItemStack item) {
return Collections.emptyList();
}
/**
* Handles clicks while an itemstack has been dragged from the item panel. Use this to set configurable slots and the like.
* Changes made to the stackSize of the dragged stack will be kept
* @param gui The current gui instance
* @param mousex The x position of the mouse
* @param mousey The y position of the mouse
* @param draggedStack The stack being dragged from the item panel
* @param button The button presed
* @return True if the drag n drop was handled. False to resume processing through other routes. The held stack will be deleted if draggedStack.stackSize == 0
*/
@Method(modid = "NotEnoughItems")
@Override
public boolean handleDragNDrop(GuiContainer gui, int mousex, int mousey, ItemStack draggedStack, int button) {
return false;
}
/**
* Used to prevent the item panel from drawing on top of other gui elements.
* This function will also be called with a 1x1 size rectangle on the mouse position for determining if the given coordinate should override item panel functions such as scrolling
* @param x The x coordinate of the rectangle bounding the slot
* @param y The y coordinate of the rectangle bounding the slot
* @param w The w coordinate of the rectangle bounding the slot
* @param h The h coordinate of the rectangle bounding the slot
* @return true if the item panel slot within the specified rectangle should not be rendered.
*/
@Method(modid = "NotEnoughItems")
@Override
public boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h) {
if(this.hasWand()) {
Rectangle itemPanel = new Rectangle(x, y, w, h);
Rectangle tooltip = new Rectangle(this.guiLeft + this.xSize, this.guiTop, tooltipWidth, tooltipHeight);
return itemPanel.intersects(tooltip);
}
return false;
}
@Method(modid = "NotEnoughItems")
@Override
public VisiblityData modifyVisiblity(GuiContainer gui, VisiblityData currentVisibility) {
return currentVisibility;
}
private boolean hasWand() {
return this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getHasStack()
&& this.inventorySlots.getSlot(ContainerArcaneWorkbench.WAND_SLOT).getStack().getItem() instanceof ItemWand;
}
}
}
@@ -1,73 +1,42 @@
package electroblob.wizardry.client;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StatCollector;
import org.lwjgl.opengl.GL11;
import net.minecraft.client.resources.I18n;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
class GuiButtonApply extends GuiButton {
private static final ResourceLocation texture = new ResourceLocation("wizardry:textures/gui/handbook.png");
public GuiButtonApply(int id, int x, int y){
super(id, x, y, 32, 16, StatCollector.translateToLocal("container.arcaneWorkbench.apply"));
}
public GuiButtonApply(int id, int x, int y){
super(id, x, y, 32, 16, I18n.format("container." + Wizardry.MODID + ":arcane_workbench.apply"));
}
/**
* Draws this button to the screen.
*/
public void drawButton(Minecraft minecraft, int par2, int par3){
// Whether the button is highlighted
this.field_146123_n = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height;
@Override
public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
// Whether the button is highlighted
this.hovered = mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
int k = 100;
int l = 220;
int colour = 14737632;
if(this.enabled){
if(this.field_146123_n){
k += this.width*2;
colour = 16777120;
}
}else{
k += this.width;
colour = 10526880;
}
this.drawTexturedRect(this.xPosition, this.yPosition, k, l, this.width, this.height, 256, 256);
this.drawCenteredString(minecraft.fontRenderer, this.displayString, this.xPosition + this.width / 2, this.yPosition + (this.height - 8) / 2, colour);
int k = 36;
int l = 220;
int colour = 14737632;
}
if(this.enabled){
if(this.hovered){
k += this.width * 2;
colour = 16777120;
}
}else{
k += this.width;
colour = 10526880;
}
/**
* Draws a textured rectangle, taking the size of the image and the bit needed into account.
* @param x The x position of the rectangle
* @param y The y position of the rectangle
* @param u The x position of the top left corner of the section of the image wanted
* @param v The y position of the top left corner of the section of the image wanted
* @param width The width of the section
* @param height The height of the section
* @param textureWidth The width of the actual image.
* @param textureHeight The height of the actual image.
*/
public void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight)
{
float f = 1F / (float)textureWidth;
float f1 = 1F / (float)textureHeight;
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.addVertexWithUV((double)(x), (double)(y + height), 0, (double)((float)(u) * f), (double)((float)(v + height) * f1));
tessellator.addVertexWithUV((double)(x + width), (double)(y + height), 0, (double)((float)(u + width) * f), (double)((float)(v + height) * f1));
tessellator.addVertexWithUV((double)(x + width), (double)(y), 0, (double)((float)(u + width) * f), (double)((float)(v) * f1));
tessellator.addVertexWithUV((double)(x), (double)(y), 0, (double)((float)(u) * f), (double)((float)(v) * f1));
tessellator.draw();
}
}
WizardryUtilities.drawTexturedRect(this.x, this.y, k, l, this.width, this.height, 256, 256);
this.drawCenteredString(minecraft.fontRenderer, this.displayString, this.x + this.width / 2,
this.y + (this.height - 8) / 2, colour);
}
}
@@ -1,27 +1,20 @@
package electroblob.wizardry.client;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
class GuiButtonInvisible extends GuiButton {
public GuiButtonInvisible(int id, int x, int y, int width, int height){
super(id, x, y, width, height, "");
}
public GuiButtonInvisible(int id, int x, int y, int width, int 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.field_146123_n = par2 >= this.xPosition && par3 >= this.yPosition && par2 < this.xPosition + this.width && par3 < this.yPosition + this.height;
}
}
@@ -1,78 +0,0 @@
package electroblob.wizardry.client;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
@SideOnly(Side.CLIENT)
class GuiButtonNextPage extends GuiButton
{
/**
* True for pointing right (next page), false for pointing left (previous page).
*/
private final boolean nextPage;
private static final ResourceLocation texture = new ResourceLocation("wizardry:textures/gui/handbook.png");
public GuiButtonNextPage(int id, int x, int y, boolean par4)
{
super(id, x, y, 23, 13, "");
this.nextPage = par4;
}
/**
* Draws this button to the screen.
*/
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;
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
par1Minecraft.getTextureManager().bindTexture(texture);
int k = 0;
int l = 192;
if (flag)
{
k += 23;
}
if (!this.nextPage)
{
l += 13;
}
this.drawTexturedRect(this.xPosition, this.yPosition, k, l, 23, 13, 288, 256);
}
}
/**
* Draws a textured rectangle, taking the size of the image and the bit needed into account.
* @param x The x position of the rectangle
* @param y The y position of the rectangle
* @param u The x position of the top left corner of the section of the image wanted
* @param v The y position of the top left corner of the section of the image wanted
* @param width The width of the section
* @param height The height of the section
* @param textureWidth The width of the actual image.
* @param textureHeight The height of the actual image.
*/
public void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight)
{
float f = 1F / (float)textureWidth;
float f1 = 1F / (float)textureHeight;
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.addVertexWithUV((double)(x), (double)(y + height), 0, (double)((float)(u) * f), (double)((float)(v + height) * f1));
tessellator.addVertexWithUV((double)(x + width), (double)(y + height), 0, (double)((float)(u + width) * f), (double)((float)(v + height) * f1));
tessellator.addVertexWithUV((double)(x + width), (double)(y), 0, (double)((float)(u + width) * f), (double)((float)(v) * f1));
tessellator.addVertexWithUV((double)(x), (double)(y), 0, (double)((float)(u) * f), (double)((float)(v) * f1));
tessellator.draw();
}
}
@@ -0,0 +1,47 @@
package electroblob.wizardry.client;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
class GuiButtonTurnPage extends GuiButton {
/** True for pointing right (next page), false for pointing left (previous page). */
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){
super(id, x, y, 23, 13, "");
this.nextPage = isNextPage;
}
@Override
public void drawButton(Minecraft minecraft, int mouseX, int mouseY, float partialTicks){
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(flag){
k += 23;
}
if(!this.nextPage){
l += 13;
}
WizardryUtilities.drawTexturedRect(this.x, this.y, k, l, 23, 13, 288, 256);
}
}
}
@@ -3,102 +3,128 @@ package electroblob.wizardry.client;
import java.util.ArrayList;
import java.util.List;
import cpw.mods.fml.client.config.DummyConfigElement.DummyCategoryElement;
import cpw.mods.fml.client.config.GuiConfig;
import cpw.mods.fml.client.config.GuiConfigEntries;
import cpw.mods.fml.client.config.GuiConfigEntries.CategoryEntry;
import cpw.mods.fml.client.config.IConfigElement;
import electroblob.wizardry.Settings;
import electroblob.wizardry.Wizardry;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.util.StatCollector;
import net.minecraft.client.resources.I18n;
import net.minecraftforge.common.config.ConfigElement;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.fml.client.config.DummyConfigElement.DummyCategoryElement;
import net.minecraftforge.fml.client.config.GuiConfig;
import net.minecraftforge.fml.client.config.GuiConfigEntries;
import net.minecraftforge.fml.client.config.GuiConfigEntries.CategoryEntry;
import net.minecraftforge.fml.client.config.IConfigElement;
public class GuiConfigWizardry extends GuiConfig {
public GuiConfigWizardry(GuiScreen parent){
super(parent, getConfigEntries(), Wizardry.MODID, false, false, Wizardry.NAME + " - " + StatCollector.translateToLocal("config.title.general"));
//this.titleLine2 = "File location: " + Wizardry.config.getConfigFile().getAbsolutePath();
super(parent, getConfigEntries(), Wizardry.MODID, false, false,
Wizardry.NAME + " - " + I18n.format("config." + Wizardry.MODID + ".title.general"));
// this.titleLine2 = "File location: " + Wizardry.config.getConfigFile().getAbsolutePath();
}
private static List<IConfigElement> getConfigEntries(){
List<IConfigElement> configList = new ArrayList<IConfigElement>(1);
configList.add(new DummyCategoryElement("spellsConfig", "config.category.spells", SpellsCategory.class));
configList.add(new DummyCategoryElement("resistancesConfig", "config.category.resistances", ResistancesCategory.class));
configList.add(new DummyCategoryElement("idsConfig", "config.category.ids", IDsCategory.class));
configList.addAll(new ConfigElement(Wizardry.config.getCategory(Configuration.CATEGORY_GENERAL)).getChildElements());
configList.add(new DummyCategoryElement("gameplayConfig", "config." + Wizardry.MODID + ".category." + Settings.GAMEPLAY_CATEGORY, GameplayCategory.class));
configList.add(new DummyCategoryElement("worldgenConfig", "config." + Wizardry.MODID + ".category." + Settings.WORLDGEN_CATEGORY, WorldgenCategory.class));
configList.add(new DummyCategoryElement("commandsConfig", "config." + Wizardry.MODID + ".category." + Settings.COMMANDS_CATEGORY, CommandsCategory.class));
configList.add(new DummyCategoryElement("clientConfig", "config." + Wizardry.MODID + ".category." + Settings.CLIENT_CATEGORY, ClientCategory.class));
configList.add(new DummyCategoryElement("spellsConfig", "config." + Wizardry.MODID + ".category." + Settings.SPELLS_CATEGORY, SpellsCategory.class));
configList.add(new DummyCategoryElement("resistancesConfig", "config." + Wizardry.MODID + ".category." + Settings.RESISTANCES_CATEGORY, ResistancesCategory.class));
configList.addAll(new ConfigElement(Wizardry.settings.getConfigCategory(Configuration.CATEGORY_GENERAL)).getChildElements());
return configList;
}
/** Spells category of the config gui. This adds a button which opens up the spells category config. */
public static class SpellsCategory extends CategoryEntry
{
public SpellsCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop)
{
super(owningScreen, owningEntryList, prop);
}
@Override
protected GuiScreen buildChildScreen()
{
// This GuiConfig object specifies the configID of the object and as such will force-save when it is closed.
// The parent GuiConfig object's entryList will also be refreshed to reflect the changes.
GuiConfig spellsMenu = new GuiConfig(this.owningScreen,
(new ConfigElement(Wizardry.config.getCategory(Wizardry.SPELLS_CATEGORY))).getChildElements(),
this.owningScreen.modID, Wizardry.SPELLS_CATEGORY, false, false,
Wizardry.NAME + " - " + StatCollector.translateToLocal("config.title.spells"));
spellsMenu.titleLine2 = StatCollector.translateToLocal("config.subtitle.spells");
return spellsMenu;
}
}
/** Resistances category of the config gui. */
public static class ResistancesCategory extends CategoryEntry
{
public ResistancesCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop)
{
super(owningScreen, owningEntryList, prop);
}
@Override
protected GuiScreen buildChildScreen()
{
// This GuiConfig object specifies the configID of the object and as such will force-save when it is closed.
// The parent GuiConfig object's entryList will also be refreshed to reflect the changes.
GuiConfig idsMenu = new GuiConfig(this.owningScreen,
(new ConfigElement(Wizardry.config.getCategory(Wizardry.RESISTANCES_CATEGORY))).getChildElements(),
this.owningScreen.modID, Wizardry.RESISTANCES_CATEGORY, false, false,
Wizardry.NAME + " - " + StatCollector.translateToLocal("config.title.resistances"));
idsMenu.titleLine2 = StatCollector.translateToLocal("config.subtitle.resistances");
return idsMenu;
}
}
/** IDs category of the config gui. */
public static class IDsCategory extends CategoryEntry
{
public IDsCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop)
{
super(owningScreen, owningEntryList, prop);
}
@Override
protected GuiScreen buildChildScreen()
{
// This GuiConfig object specifies the configID of the object and as such will force-save when it is closed.
// The parent GuiConfig object's entryList will also be refreshed to reflect the changes.
GuiConfig idsMenu = new GuiConfig(this.owningScreen,
(new ConfigElement(Wizardry.config.getCategory(Wizardry.IDS_CATEGORY))).getChildElements(),
this.owningScreen.modID, Wizardry.IDS_CATEGORY, false, false,
Wizardry.NAME + " - " + StatCollector.translateToLocal("config.title.ids"));
idsMenu.titleLine2 = StatCollector.translateToLocal("config.subtitle.ids");
return idsMenu;
}
}
// The reason this system is so convoluted is that it's designed for use with the @Config annotation. The problem is,
// I'm not sure whether that will play well with the load phases. Hmmm...
public static abstract class CategoryBase extends CategoryEntry {
public CategoryBase(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
super(owningScreen, owningEntryList, prop);
}
@Override
protected GuiScreen buildChildScreen(){
String category = this.getCategory();
// This GuiConfig object specifies the configID of the object and as such will force-save when it is closed.
// The parent GuiConfig object's entryList will also be refreshed to reflect the changes.
GuiConfig childScreen = new GuiConfig(this.owningScreen,
(new ConfigElement(Wizardry.settings.getConfigCategory(category))).getChildElements(),
this.owningScreen.modID, category, false, false,
Wizardry.NAME + " - " + I18n.format("config." + Wizardry.MODID + ".title." + category));
childScreen.titleLine2 = I18n.format("config." + Wizardry.MODID + ".subtitle." + category);
return childScreen;
}
protected abstract String getCategory();
}
/** Gameplay category of the config gui. */
public static class GameplayCategory extends CategoryBase {
public GameplayCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
super(owningScreen, owningEntryList, prop);
}
@Override protected String getCategory() { return Settings.GAMEPLAY_CATEGORY; }
}
/** Spells category of the config gui. */
public static class SpellsCategory extends CategoryBase {
public SpellsCategory(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop){
super(owningScreen, owningEntryList, prop);
}
@Override protected 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; }
}
}
@@ -1,40 +1,37 @@
package electroblob.wizardry.client;
import org.lwjgl.opengl.GL11;
import electroblob.wizardry.WizardryGuiHandler;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ContainerWorkbench;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
/** Crafting table GUI that doesn't require a crafting table container object. */
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_, int p_i1084_3_, int p_i1084_4_, int p_i1084_5_)
{
super(new ContainerWorkbench(p_i1084_1_, p_i1084_2_, p_i1084_3_, p_i1084_4_, p_i1084_5_));
}
/**
* Draw the foreground layer for the GuiContainer (everything in front of the items)
*/
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);
}
private static final ResourceLocation craftingTableGuiTextures = new ResourceLocation(
"textures/gui/container/crafting_table.png");
protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_)
{
GL11.glColor4f(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);
}
public GuiPortableCrafting(InventoryPlayer p_i1084_1_, World p_i1084_2_, BlockPos pos){
super(new ContainerWorkbench(p_i1084_1_, p_i1084_2_, pos));
}
/**
* Draw the foreground layer for the GuiContainer (everything in front of the items)
*/
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);
}
}
@@ -2,152 +2,111 @@ package electroblob.wizardry.client;
import org.lwjgl.input.Keyboard;
import electroblob.wizardry.EnumTier;
import electroblob.wizardry.ExtendedPlayer;
import electroblob.wizardry.SpellGlyphData;
import electroblob.wizardry.WizardData;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.WizardryGuiHandler;
import electroblob.wizardry.WizardryRegistry;
import electroblob.wizardry.constants.Tier;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
public class GuiSpellBook extends GuiScreen {
private int xSize, ySize;
private Spell spell;
private static final ResourceLocation texture = new ResourceLocation(Wizardry.MODID, "textures/gui/spellbook.png");
public GuiSpellBook(Spell spell) {
public GuiSpellBook(Spell spell){
super();
xSize = 288;
ySize = 180;
this.spell = spell;
}
/**
* Draws the screen and all the components in it.
*/
public void drawScreen(int par1, int par2, float par3) {
int xPos = this.width/2 - xSize/2;
int yPos = this.height/2 - this.ySize/2;
EntityPlayer player = Minecraft.getMinecraft().thePlayer;
boolean discovered = true;
if(Wizardry.discoveryMode && !player.capabilities.isCreativeMode && ExtendedPlayer.get(player) != null
&& !ExtendedPlayer.get(player).hasSpellBeenDiscovered(spell)){
* Draws the screen and all the components in it.
*/
public void drawScreen(int par1, int par2, float par3){
int xPos = this.width / 2 - xSize / 2;
int yPos = this.height / 2 - this.ySize / 2;
EntityPlayer player = Minecraft.getMinecraft().player;
boolean discovered = true;
if(Wizardry.settings.discoveryMode && !player.capabilities.isCreativeMode && WizardData.get(player) != null
&& !WizardData.get(player).hasSpellBeenDiscovered(spell)){
discovered = false;
}
// Draws spell illustration on opposite page, underneath the book so it shows through the hole.
Minecraft.getMinecraft().renderEngine.bindTexture(discovered ? spell.icon : WizardryRegistry.none.icon);
this.drawTexturedRect(xPos + 145, yPos + 20, 0, 0, 128, 128, 128, 128);
Minecraft.getMinecraft().renderEngine.bindTexture(texture);
this.drawTexturedRect(xPos, yPos, 0, 0, xSize, ySize, xSize, 256);
super.drawScreen(par1, par2, par3);
// 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());
WizardryUtilities.drawTexturedRect(xPos + 145, yPos + 20, 0, 0, 128, 128, 128, 128);
Minecraft.getMinecraft().renderEngine.bindTexture(texture);
WizardryUtilities.drawTexturedRect(xPos, yPos, 0, 0, xSize, ySize, xSize, 256);
super.drawScreen(par1, par2, par3);
if(discovered){
this.fontRendererObj.drawString(spell.getDisplayName(), xPos+17, yPos+14, 0);
this.fontRendererObj.drawString(spell.type.getDisplayName(), xPos+17, yPos+25, 0x777777);
this.fontRenderer.drawString(spell.getDisplayName(), xPos + 17, yPos + 14, 0);
this.fontRenderer.drawString(spell.type.getDisplayName(), xPos + 17, yPos + 25, 0x777777);
}else{
this.mc.standardGalacticFontRenderer.drawString(SpellGlyphData.getGlyphName(spell, player.worldObj), xPos+17, yPos+14, 0);
this.mc.standardGalacticFontRenderer.drawString(spell.type.getDisplayName(), xPos+17, yPos+25, 0x777777);
this.mc.standardGalacticFontRenderer.drawString(SpellGlyphData.getGlyphName(spell, player.world), xPos + 17,
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 == EnumTier.BASIC){
// Basic is usually white but this doesn't show up.
this.fontRendererObj.drawString("Tier: \u00A77" + EnumTier.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.colour + 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();
Keyboard.enableRepeatEvents(true);
this.buttonList.clear();
}
public void onGuiClosed()
{
super.onGuiClosed();
Keyboard.enableRepeatEvents(false);
}
Keyboard.enableRepeatEvents(true);
this.buttonList.clear();
}
/**
* Draws a textured rectangle, taking the size of the image and the bit needed into account. Client side only, of course.
* @param x The x position of the rectangle
* @param y The y position of the rectangle
* @param u The x position of the top left corner of the section of the image wanted
* @param v The y position of the top left corner of the section of the image wanted
* @param width The width of the section
* @param height The height of the section
* @param textureWidth The width of the actual image.
* @param textureHeight The height of the actual image.
*/
public static void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight)
{
float f = 1F / (float)textureWidth;
float f1 = 1F / (float)textureHeight;
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.addVertexWithUV((double)(x), (double)(y + height), 0, (double)((float)(u) * f), (double)((float)(v + height) * f1));
tessellator.addVertexWithUV((double)(x + width), (double)(y + height), 0, (double)((float)(u + width) * f), (double)((float)(v + height) * f1));
tessellator.addVertexWithUV((double)(x + width), (double)(y), 0, (double)((float)(u + width) * f), (double)((float)(v) * f1));
tessellator.addVertexWithUV((double)(x), (double)(y), 0, (double)((float)(u) * f), (double)((float)(v) * f1));
tessellator.draw();
public void onGuiClosed(){
super.onGuiClosed();
Keyboard.enableRepeatEvents(false);
}
}
@@ -2,26 +2,29 @@ package electroblob.wizardry.client;
import java.util.List;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import electroblob.wizardry.ExtendedPlayer;
import electroblob.wizardry.Settings.GuiPosition;
import electroblob.wizardry.SpellGlyphData;
import electroblob.wizardry.WandHelper;
import electroblob.wizardry.WizardData;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.WizardryRegistry;
import electroblob.wizardry.constants.Constants;
import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.spell.None;
import electroblob.wizardry.registry.Spells;
import electroblob.wizardry.registry.WizardryItems;
import electroblob.wizardry.registry.WizardryPotions;
import electroblob.wizardry.spell.Spell;
import electroblob.wizardry.util.WandHelper;
import electroblob.wizardry.util.WizardryUtilities;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GlStateManager.DestFactor;
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagIntArray;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
public class GuiSpellDisplay extends Gui {
@@ -29,7 +32,7 @@ public class GuiSpellDisplay extends Gui {
private static final ResourceLocation hudTexture = new ResourceLocation(Wizardry.MODID, "textures/gui/spell_hud.png");
public GuiSpellDisplay(Minecraft par1Minecraft) {
public GuiSpellDisplay(Minecraft par1Minecraft){
super();
this.mc = par1Minecraft;
}
@@ -37,133 +40,113 @@ public class GuiSpellDisplay extends Gui {
@SubscribeEvent
public void draw(RenderGameOverlayEvent event){
EntityPlayer player = this.mc.thePlayer;
EntityPlayer player = this.mc.player;
if(player.getHeldItem() != null && player.getHeldItem().getItem() instanceof ItemWand){
// If the player has a wand in each hand, only displays for the one in the main hand.
int width = event.resolution.getScaledWidth();
int height = event.resolution.getScaledHeight();
ItemStack wand = player.getHeldItemMainhand();
Spell spell = WandHelper.getCurrentSpell(player.getHeldItem());
int cooldown = WandHelper.getCurrentCooldown(player.getHeldItem());
if(!(wand.getItem() instanceof ItemWand)){
wand = player.getHeldItemOffhand();
// If the player isn't holding a wand, then nothing else needs to be done.
if(!(wand.getItem() instanceof ItemWand)) return;
}
float cooldownMultiplier = 1.0f - WandHelper.getUpgradeLevel(player.getHeldItem(), Wizardry.cooldownUpgrade)*Wizardry.COOLDOWN_REDUCTION_PER_LEVEL;
int width = event.getResolution().getScaledWidth();
int height = event.getResolution().getScaledHeight();
if(player.isPotionActive(Wizardry.fontOfMana)){
// Dividing by this rather than setting it takes upgrades and font of mana into account simultaneously
cooldownMultiplier /= 2 + player.getActivePotionEffect(Wizardry.fontOfMana).getAmplifier();
}
Spell spell = WandHelper.getCurrentSpell(wand);
int cooldown = WandHelper.getCurrentCooldown(wand);
// Coordinates of the top left corner of the HUD.
int left = 0;
int top = 0;
boolean mirror = false;
float cooldownMultiplier = 1.0f - WandHelper.getUpgradeLevel(wand, WizardryItems.cooldown_upgrade) * Constants.COOLDOWN_REDUCTION_PER_LEVEL;
if(Wizardry.spellHUDPosition.equals("Bottom left")){
left = 0;
top = height-36;
}else if(Wizardry.spellHUDPosition.equals("Top left")){
left = 0;
top = 0;
}else if(Wizardry.spellHUDPosition.equals("Top right")){
left = width-128;
top = 0;
mirror = true;
}else if(Wizardry.spellHUDPosition.equals("Bottom right")){
left = width-128;
top = height-36;
mirror = true;
}
if(player.isPotionActive(WizardryPotions.font_of_mana)){
// Dividing by this rather than setting it takes upgrades and font of mana into account simultaneously
cooldownMultiplier /= 2 + player.getActivePotionEffect(WizardryPotions.font_of_mana).getAmplifier();
}
boolean discovered = true;
// Coordinates of the top left corner of the HUD.
int left = 0;
int top = 0;
boolean mirror = false;
if(!player.capabilities.isCreativeMode && ExtendedPlayer.get(player) != null){
discovered = ExtendedPlayer.get(player).hasSpellBeenDiscovered(spell);
}
if(Wizardry.settings.spellHUDPosition == GuiPosition.BOTTOM_LEFT){
left = 0;
top = height - 36;
}else if(Wizardry.settings.spellHUDPosition == GuiPosition.TOP_LEFT){
left = 0;
top = 0;
}else if(Wizardry.settings.spellHUDPosition == GuiPosition.TOP_RIGHT){
left = width - 128;
top = 0;
mirror = true;
}else if(Wizardry.settings.spellHUDPosition == GuiPosition.BOTTOM_RIGHT){
left = width - 128;
top = height - 36;
mirror = true;
}
if(event.type == RenderGameOverlayEvent.ElementType.TEXT){
boolean discovered = true;
// Makes spells greyed out if they are in cooldown or if the player has the arcane jammer effect
String colour = cooldown > 0 || player.isPotionActive(Wizardry.arcaneJammer) ? "\u00A78" : spell.element.colour;
if(!discovered) colour = "\u00A79";
String spellName = discovered ? spell.getDisplayName() : SpellGlyphData.getGlyphName(spell, player.worldObj);
FontRenderer font = discovered ? this.mc.fontRenderer : this.mc.standardGalacticFontRenderer;
if(!player.capabilities.isCreativeMode && WizardData.get(player) != null){
discovered = WizardData.get(player).hasSpellBeenDiscovered(spell);
}
int maxWidth = 90;
if(event.getType() == RenderGameOverlayEvent.ElementType.TEXT){
if(font.getStringWidth(spellName) <= maxWidth){
// Single line is rendered more centrally
font.drawStringWithShadow(colour + spellName, mirror ? left+5 : left+41, top+13, 0xffffffff);
// 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();
if(!discovered) colour = "\u00A79";
String spellName = discovered ? spell.getDisplayName() : SpellGlyphData.getGlyphName(spell, player.world);
FontRenderer font = discovered ? this.mc.fontRenderer : this.mc.standardGalacticFontRenderer;
}else{
int maxWidth = 90;
int lineNumber = 0;
if(font.getStringWidth(spellName) <= maxWidth){
// Single line is rendered more centrally
font.drawStringWithShadow(colour + spellName, mirror ? left + 5 : left + 41, top + 13, 0xffffffff);
List lines = font.listFormattedStringToWidth(spellName, maxWidth);
}else{
for(Object line : lines){
if(line instanceof String){
font.drawStringWithShadow(colour + (String)line, mirror ? left+5 : left+41, top+6 + 11*lineNumber, 0xffffffff);
}
lineNumber++;
int lineNumber = 0;
List<String> lines = font.listFormattedStringToWidth(spellName, maxWidth);
for(Object line : lines){
if(line instanceof String){
font.drawStringWithShadow(colour + (String)line, mirror ? left + 5 : left + 41, top + 6 + 11 * lineNumber, 0xffffffff);
}
lineNumber++;
}
}else if(event.type == RenderGameOverlayEvent.ElementType.HOTBAR){
GL11.glPushMatrix();
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor3f(1.0f, 1.0f, 1.0f);
this.mc.renderEngine.bindTexture(hudTexture);
// Background of spell hud
this.drawTexturedModalRect(left, top, 0, mirror ? 36 : 0, 128, 36);
// Cooldown bar
if(cooldown > 0){
this.drawTexturedModalRect(mirror ? left+5 : left+41, height-8, 128, 6, 82, 6);
int l = (int)(((double)(spell.cooldown * cooldownMultiplier - cooldown)
/ (double)(spell.cooldown * cooldownMultiplier)) * 82);
this.drawTexturedModalRect(mirror ? left+5 : left+41, height-8, 128, 0, l, 6);
}
// Spell illustration
this.mc.renderEngine.bindTexture(discovered ? spell.icon : WizardryRegistry.none.icon);
this.drawTexturedRect(mirror ? left+94 : left+2, top+2, 0, 0, 32, 32, 32, 32);
GL11.glDisable(GL11.GL_BLEND);
GL11.glPopMatrix();
}
}else if(event.getType() == RenderGameOverlayEvent.ElementType.HOTBAR){
GlStateManager.enableBlend();
GlStateManager.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
GlStateManager.color(1, 1, 1);
this.mc.renderEngine.bindTexture(hudTexture);
// Background of spell hud
this.drawTexturedModalRect(left, top, 0, mirror ? 36 : 0, 128, 36);
// Cooldown bar
if(cooldown > 0){
this.drawTexturedModalRect(mirror ? left + 5 : left + 41, top + 28, 128, 6, 82, 6);
int l = (int)(((double)(spell.cooldown * cooldownMultiplier - cooldown) / (double)(spell.cooldown * cooldownMultiplier)) * 82);
this.drawTexturedModalRect(mirror ? left + 5 : left + 41, top + 28, 128, 0, l, 6);
}
// Spell illustration
this.mc.renderEngine.bindTexture(discovered ? spell.getIcon() : Spells.none.getIcon());
WizardryUtilities.drawTexturedRect(mirror ? left + 94 : left + 2, top + 2, 0, 0, 32, 32, 32, 32);
// Blend needs to be left enabled here because otherwise the hotbar becomes opaque
}
}
/**
* Draws a textured rectangle, taking the size of the image and the bit needed into account. Client side only, of course.
* @param x The x position of the rectangle
* @param y The y position of the rectangle
* @param u The x position of the top left corner of the section of the image wanted
* @param v The y position of the top left corner of the section of the image wanted
* @param width The width of the section
* @param height The height of the section
* @param textureWidth The width of the actual image.
* @param textureHeight The height of the actual image.
*/
public static void drawTexturedRect(int x, int y, int u, int v, int width, int height, int textureWidth, int textureHeight)
{
float f = 1F / (float)textureWidth;
float f1 = 1F / (float)textureHeight;
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.addVertexWithUV((double)(x), (double)(y + height), 0, (double)((float)(u) * f), (double)((float)(v + height) * f1));
tessellator.addVertexWithUV((double)(x + width), (double)(y + height), 0, (double)((float)(u + width) * f), (double)((float)(v + height) * f1));
tessellator.addVertexWithUV((double)(x + width), (double)(y), 0, (double)((float)(u + width) * f), (double)((float)(v) * f1));
tessellator.addVertexWithUV((double)(x), (double)(y), 0, (double)((float)(u) * f), (double)((float)(v) * f1));
tessellator.draw();
}
}
File diff suppressed because it is too large Load Diff
@@ -1,97 +1,98 @@
package electroblob.wizardry.client;
import java.util.ArrayList;
import java.util.List;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
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)
public class MixedFontRenderer extends FontRenderer {
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_);
}
@Override
public int drawString(String string, int x, int y, int colour, boolean shadow){
public int drawString(String string, float x, float y, int colour, boolean shadow){
int l = 0;
boolean sga = false;
while(string.indexOf('#') > -1){
String section = string.substring(0, string.indexOf('#'));
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);
}else{
l += Minecraft.getMinecraft().fontRenderer.drawString(section, x, y, colour, shadow);
}else{
l += Minecraft.getMinecraft().fontRenderer.drawString(section, x, y, colour, shadow);
x += Minecraft.getMinecraft().fontRenderer.getStringWidth(section);
}
}
string = string.substring(string.indexOf('#') + 1);
sga = !sga;
}
if(sga){
l += Minecraft.getMinecraft().standardGalacticFontRenderer.drawString(string, x, y, colour, shadow);
}else{
l += Minecraft.getMinecraft().fontRenderer.drawString(string, x, y, colour, shadow);
}
return l;
}
l += Minecraft.getMinecraft().standardGalacticFontRenderer.drawString(string, x, y, colour, shadow);
}else{
l += Minecraft.getMinecraft().fontRenderer.drawString(string, x, y, colour, shadow);
}
return l;
}
@Override
public int getStringWidth(String string){
int l = 0;
boolean sga = false;
while(string.indexOf('#') > -1){
String section = string.substring(0, string.indexOf('#'));
if(sga){
l += Minecraft.getMinecraft().standardGalacticFontRenderer.getStringWidth(section);
}else{
l += Minecraft.getMinecraft().fontRenderer.getStringWidth(section);
}
l += Minecraft.getMinecraft().standardGalacticFontRenderer.getStringWidth(section);
}else{
l += Minecraft.getMinecraft().fontRenderer.getStringWidth(section);
}
string = string.substring(string.indexOf('#') + 1);
sga = !sga;
}
if(sga){
l += Minecraft.getMinecraft().standardGalacticFontRenderer.getStringWidth(string);
}else{
l += Minecraft.getMinecraft().fontRenderer.getStringWidth(string);
}
return l;
l += Minecraft.getMinecraft().standardGalacticFontRenderer.getStringWidth(string);
}else{
l += Minecraft.getMinecraft().fontRenderer.getStringWidth(string);
}
return l;
}
// This doesn't work the same way yet
@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("#")){
Minecraft.getMinecraft().standardGalacticFontRenderer.drawSplitString(string.substring(1), x, y, width, colour);
}else{
Minecraft.getMinecraft().fontRenderer.drawSplitString(string, x, y, width, colour);
}
}
Minecraft.getMinecraft().standardGalacticFontRenderer.drawSplitString(string.substring(1), x, y, width,
colour);
}else{
Minecraft.getMinecraft().fontRenderer.drawSplitString(string, x, y, width, colour);
}
}
}
@@ -1,55 +1,52 @@
package electroblob.wizardry.client;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.audio.MovingSound;
import net.minecraft.entity.Entity;
import net.minecraft.util.MathHelper;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
// Copied from MovingSoundMinecart; if it ever breaks between updates take a look at that.
@SideOnly(Side.CLIENT)
public class MovingSoundEntity extends MovingSound
{
private final Entity source;
private float pitch = 0.0F;
public class MovingSoundEntity extends MovingSound {
private final Entity source;
private float distance = 0.0F;
public MovingSoundEntity(Entity entity, String soundName, float volume, float pitch, boolean repeat)
{
super(new ResourceLocation(soundName));
this.source = entity;
this.repeat = repeat;
this.volume = volume;
this.field_147663_c = pitch;
this.field_147665_h = 0;
}
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
// MovingSoundMinecart.
super(sound, SoundCategory.BLOCKS);
this.source = entity;
this.repeat = repeat;
this.volume = volume;
this.pitch = pitch;
this.repeatDelay = 0;
}
/**
* Updates the JList with a new model.
*/
public void update()
{
if (this.source.isDead && repeat)
{
this.donePlaying = true;
}
else
{
this.xPosF = (float)this.source.posX;
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);
/**
* Updates the JList with a new model.
*/
@Override
public void update(){
if(this.source.isDead && repeat){
this.donePlaying = true;
}else{
this.xPosF = (float)this.source.posX;
this.yPosF = (float)this.source.posY;
this.zPosF = (float)this.source.posZ;
float f = MathHelper.sqrt(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?
if ((double)f >= 0.01D)
{
this.pitch = MathHelper.clamp_float(this.pitch + 0.0025F, 0.0F, 1.0F);
this.volume = 0.0F + MathHelper.clamp_float(f, 0.0F, 0.5F) * 0.7F;
}
else
{
//this.pitch = 0.0F;
//this.volume = 0.0F;
}
}
}
// Is this something to do with the Doppler effect?
if((double)f >= 0.01D){
this.distance = MathHelper.clamp(this.distance + 0.0025F, 0.0F, 1.0F);
this.volume = 0.0F + MathHelper.clamp(f, 0.0F, 0.5F) * 0.7F;
}else{
// this.pitch = 0.0F;
// this.volume = 0.0F;
}
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,70 @@
package electroblob.wizardry.client;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.item.ItemWand;
import electroblob.wizardry.packet.PacketControlInput;
import electroblob.wizardry.packet.WizardryPacketHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
@Mod.EventBusSubscriber(Side.CLIENT)
public class WizardryKeyHandler {
static boolean NkeyPressed = false;
static boolean BkeyPressed = false;
// Changed to a tick event to allow mouse button keybinds
// The 'lag' that happened previously was actually because the code only fired when a keyboard key was pressed!
@SubscribeEvent
public static void onTickEvent(TickEvent.ClientTickEvent event){
if(event.phase == TickEvent.Phase.END) return; // Only really needs to be once per tick
if(Wizardry.proxy instanceof ClientProxy){
EntityPlayer player = Minecraft.getMinecraft().player;
if(player != null){
ItemStack wand = player.getHeldItemMainhand();
if(!(wand.getItem() instanceof ItemWand)){
wand = player.getHeldItemOffhand();
// If the player isn't holding a wand, then nothing else needs to be done.
if(!(wand.getItem() instanceof ItemWand)) return;
}
}
if(ClientProxy.NEXT_SPELL.isKeyDown() && Minecraft.getMinecraft().inGameHasFocus){
if(!NkeyPressed){
NkeyPressed = true;
// Packet building
IMessage msg = new PacketControlInput.Message(PacketControlInput.ControlType.NEXT_SPELL_KEY);
WizardryPacketHandler.net.sendToServer(msg);
}
}else{
NkeyPressed = false;
}
if(ClientProxy.PREVIOUS_SPELL.isKeyDown() && Minecraft.getMinecraft().inGameHasFocus){
if(!BkeyPressed){
BkeyPressed = true;
// Packet building
IMessage msg = new PacketControlInput.Message(
PacketControlInput.ControlType.PREVIOUS_SPELL_KEY);
WizardryPacketHandler.net.sendToServer(msg);
}
}else{
BkeyPressed = false;
}
}
}
}
@@ -4,80 +4,75 @@ import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity;
public class ModelHammer extends ModelBase
{
ModelRenderer Shape1;
ModelRenderer Shape2;
ModelRenderer Shape3;
ModelRenderer Shape4;
ModelRenderer Shape5;
ModelRenderer Shape6;
public ModelHammer()
{
textureWidth = 64;
textureHeight = 64;
Shape1 = new ModelRenderer(this, 0, 0);
Shape1.addBox(0F, 0F, 0F, 20, 12, 12);
Shape1.setRotationPoint(-10F, 12F, -6F);
Shape1.setTextureSize(64, 64);
Shape1.mirror = true;
setRotation(Shape1, 0F, 0F, 0F);
Shape2 = new ModelRenderer(this, 0, 24);
Shape2.addBox(0F, 0F, 0F, 4, 14, 4);
Shape2.setRotationPoint(-2F, -2F, -2F);
Shape2.setTextureSize(64, 64);
Shape2.mirror = true;
setRotation(Shape2, 0F, 0F, 0F);
Shape3 = new ModelRenderer(this, 0, 49);
Shape3.addBox(0F, 0F, 0F, 5, 5, 5);
Shape3.setRotationPoint(-2.5F, -7F, -2.5F);
Shape3.setTextureSize(64, 64);
Shape3.mirror = true;
setRotation(Shape3, 0F, 0F, 0F);
Shape4 = new ModelRenderer(this, 0, 42);
Shape4.addBox(0F, 0F, 0F, 5, 2, 5);
Shape4.setRotationPoint(-2.5F, 10F, -2.5F);
Shape4.setTextureSize(64, 64);
Shape4.mirror = true;
setRotation(Shape4, 0F, 0F, 0F);
Shape5 = new ModelRenderer(this, 20, 24);
Shape5.addBox(0F, 0F, 0F, 2, 14, 14);
Shape5.setRotationPoint(-8F, 11F, -7F);
Shape5.setTextureSize(64, 64);
Shape5.mirror = true;
setRotation(Shape5, 0F, 0F, 0F);
Shape6 = new ModelRenderer(this, 20, 24);
Shape6.addBox(0F, 0F, 0F, 2, 14, 14);
Shape6.setRotationPoint(6F, 11F, -7F);
Shape6.setTextureSize(64, 64);
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);
setRotationAngles(f, f1, f2, f3, f4, f5, entity);
Shape1.render(f5);
Shape2.render(f5);
Shape3.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;
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);
}
public class ModelHammer extends ModelBase {
ModelRenderer Shape1;
ModelRenderer Shape2;
ModelRenderer Shape3;
ModelRenderer Shape4;
ModelRenderer Shape5;
ModelRenderer Shape6;
public ModelHammer(){
textureWidth = 64;
textureHeight = 64;
Shape1 = new ModelRenderer(this, 0, 0);
Shape1.addBox(0F, 0F, 0F, 20, 12, 12);
Shape1.setRotationPoint(-10F, 12F, -6F);
Shape1.setTextureSize(64, 64);
Shape1.mirror = true;
setRotation(Shape1, 0F, 0F, 0F);
Shape2 = new ModelRenderer(this, 0, 24);
Shape2.addBox(0F, 0F, 0F, 4, 14, 4);
Shape2.setRotationPoint(-2F, -2F, -2F);
Shape2.setTextureSize(64, 64);
Shape2.mirror = true;
setRotation(Shape2, 0F, 0F, 0F);
Shape3 = new ModelRenderer(this, 0, 49);
Shape3.addBox(0F, 0F, 0F, 5, 5, 5);
Shape3.setRotationPoint(-2.5F, -7F, -2.5F);
Shape3.setTextureSize(64, 64);
Shape3.mirror = true;
setRotation(Shape3, 0F, 0F, 0F);
Shape4 = new ModelRenderer(this, 0, 42);
Shape4.addBox(0F, 0F, 0F, 5, 2, 5);
Shape4.setRotationPoint(-2.5F, 10F, -2.5F);
Shape4.setTextureSize(64, 64);
Shape4.mirror = true;
setRotation(Shape4, 0F, 0F, 0F);
Shape5 = new ModelRenderer(this, 20, 24);
Shape5.addBox(0F, 0F, 0F, 2, 14, 14);
Shape5.setRotationPoint(-8F, 11F, -7F);
Shape5.setTextureSize(64, 64);
Shape5.mirror = true;
setRotation(Shape5, 0F, 0F, 0F);
Shape6 = new ModelRenderer(this, 20, 24);
Shape6.addBox(0F, 0F, 0F, 2, 14, 14);
Shape6.setRotationPoint(6F, 11F, -7F);
Shape6.setTextureSize(64, 64);
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);
setRotationAngles(f, f1, f2, f3, f4, f5, entity);
Shape1.render(f5);
Shape2.render(f5);
Shape3.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;
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,319 +3,309 @@ package electroblob.wizardry.client.model;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector3f;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.entity.living.EntityIceGiant;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.MathHelper;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ModelIceGiant extends ModelBase
{
/** The head model for the iron golem. */
public ModelRenderer iceGiantHead;
public class ModelIceGiant extends ModelBase {
/** The head model for the iron golem. */
public ModelRenderer iceGiantHead;
/** The body model for the iron golem. */
public ModelRenderer iceGiantBody;
/** The body model for the iron golem. */
public ModelRenderer iceGiantBody;
/** The right arm model for the iron golem. */
public ModelRenderer iceGiantRightArm;
/** The right arm model for the iron golem. */
public ModelRenderer iceGiantRightArm;
/** The left arm model for the iron golem. */
public ModelRenderer iceGiantLeftArm;
/** The left arm model for the iron golem. */
public ModelRenderer iceGiantLeftArm;
/** The left leg model for the Iron Golem. */
public ModelRenderer iceGiantLeftLeg;
/** The left leg model for the Iron Golem. */
public ModelRenderer iceGiantLeftLeg;
/** The right leg model for the Iron Golem. */
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;
/** The right leg model for the Iron Golem. */
public ModelRenderer iceGiantRightLeg;
public ModelIceGiant()
{
this(0.0F);
}
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(float par1)
{
this(par1, -7.0F);
}
public ModelIceGiant(){
this(0.0F);
}
public ModelIceGiant(float par1, float par2)
{
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){
this(par1, -7.0F);
}
/**
* 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);
}
public ModelIceGiant(float par1, float par2){
short short1 = 128;
short short2 = 128;
/**
* 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;
}
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);
/**
* 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();
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);
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;
}
}
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);
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_float(-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;
}
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);
}
/**
* 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;
}
}
@@ -3,137 +3,129 @@ package electroblob.wizardry.client.model;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.util.MathHelper;
import net.minecraft.util.math.MathHelper;
public class ModelPhoenix extends ModelBase {
ModelRenderer body;
ModelRenderer rightWing;
ModelRenderer leftWing;
ModelRenderer tailFeathers;
ModelRenderer tail;
ModelRenderer head;
ModelRenderer neck;
ModelRenderer beak;
ModelRenderer plume;
public ModelPhoenix()
{
textureWidth = 64;
textureHeight = 64;
/* For future reference:
* - setRotationPoint sets the origin of a part relative to that of its parent.
* - The first 3 arguments of addBox set the position of a part relative to its rotation point, and the last
* 3 arguments are the size of the part.
* (This means that rotation point and position seem to be the wrong way round, since changing the rotation point
* 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.
* - Mirror does nothing unless you set it before addBox.
* - Rotation is the usual pitch, yaw, roll.
*/
body = new ModelRenderer(this, 0, 34);
body.addBox(0F, 0F, -3F, 6, 15, 6);
body.setRotationPoint(-3F, 0F, -5F);
body.setTextureSize(64, 64);
body.mirror = true;
setRotation(body, 0.296706F, 0F, 0F);
rightWing = new ModelRenderer(this, 0, 0);
rightWing.mirror = true;
rightWing.addBox(-27F, -27F, 0F, 27, 34, 0);
rightWing.setRotationPoint(0F, 5F, 0F);
rightWing.setTextureSize(64, 64);
setRotation(rightWing, 0.1745329F, 0F, 0F);
leftWing = new ModelRenderer(this, 0, 0);
leftWing.addBox(0F, -27F, 0F, 27, 34, 0);
leftWing.setRotationPoint(6F, 5F, 0F);
leftWing.setTextureSize(64, 64);
setRotation(leftWing, 0.1745329F, 0F, 0F);
tailFeathers = new ModelRenderer(this, 0, 57);
tailFeathers.addBox(-5F, 0F, 0F, 10, 7, 0);
tailFeathers.setRotationPoint(0F, 7F, 1F);
tailFeathers.setTextureSize(64, 64);
tailFeathers.mirror = true;
setRotation(tailFeathers, 0.5235988F, 0F, 0F);
tail = new ModelRenderer(this, 20, 55);
tail.addBox(-1F, 0F, -1F, 2, 7, 2);
tail.setRotationPoint(3F, 15F, 2F);
tail.setTextureSize(64, 64);
tail.mirror = true;
setRotation(tail, 0.4014257F, 0F, 0F);
head = new ModelRenderer(this, 24, 34);
head.addBox(-2F, -4F, -5F, 4, 4, 6);
head.setRotationPoint(0F, -4F, 0F);
head.setTextureSize(64, 64);
head.mirror = true;
setRotation(head, 0F, 0F, 0F);
neck = new ModelRenderer(this, 24, 44);
neck.addBox(-1F, -4F, -1F, 2, 4, 2);
neck.setRotationPoint(0F, 0F, -4F);
neck.setTextureSize(64, 64);
neck.mirror = true;
setRotation(neck, 0.2443461F, 0F, 0F);
beak = new ModelRenderer(this, 32, 44);
beak.addBox(-0.5F, 4F, -1F, 1, 2, 3);
beak.setRotationPoint(0F, -5F, -8F);
beak.setTextureSize(64, 64);
beak.mirror = true;
setRotation(beak, 0.2792527F, 0F, 0F);
plume = new ModelRenderer(this, 28, 50);
plume.addBox(-0.03333334F, 1F, 0F, 0, 5, 5);
plume.setRotationPoint(0F, -7F, 0F);
plume.setTextureSize(64, 64);
plume.mirror = true;
setRotation(plume, 0F, 0F, 0F);
neck.addChild(head);
head.addChild(plume);
head.addChild(beak);
tail.addChild(tailFeathers);
body.addChild(tail);
body.addChild(rightWing);
body.addChild(leftWing);
}
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);
float f6 = (180F / (float)Math.PI);
this.neck.rotateAngleX = f4 / (180F / (float)Math.PI);
this.neck.rotateAngleY = f3 / (180F / (float)Math.PI);
this.neck.rotateAngleZ = 0.0F;
this.body.rotateAngleX = 0.3f + MathHelper.cos(f2 * 0.1F) * 0.15F;
this.body.rotateAngleY = 0.0F;
this.tail.rotateAngleX = this.body.rotateAngleX * 1.1f;
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;
body.render(f5);
neck.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);
}
ModelRenderer body;
ModelRenderer rightWing;
ModelRenderer leftWing;
ModelRenderer tailFeathers;
ModelRenderer tail;
ModelRenderer head;
ModelRenderer neck;
ModelRenderer beak;
ModelRenderer plume;
public ModelPhoenix(){
textureWidth = 64;
textureHeight = 64;
/* For future reference: - setRotationPoint sets the origin of a part relative to that of its parent. - The
* first 3 arguments of addBox set the position of a part relative to its rotation point, and the last 3
* arguments are the size of the part. (This means that rotation point and position seem to be the wrong way
* round, since changing the rotation point 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. - Mirror does nothing unless you set it before addBox. - Rotation is the usual pitch, yaw, roll. */
body = new ModelRenderer(this, 0, 34);
body.addBox(0F, 0F, -3F, 6, 15, 6);
body.setRotationPoint(-3F, 0F, -5F);
body.setTextureSize(64, 64);
body.mirror = true;
setRotation(body, 0.296706F, 0F, 0F);
rightWing = new ModelRenderer(this, 0, 0);
rightWing.mirror = true;
rightWing.addBox(-27F, -27F, 0F, 27, 34, 0);
rightWing.setRotationPoint(0F, 5F, 0F);
rightWing.setTextureSize(64, 64);
setRotation(rightWing, 0.1745329F, 0F, 0F);
leftWing = new ModelRenderer(this, 0, 0);
leftWing.addBox(0F, -27F, 0F, 27, 34, 0);
leftWing.setRotationPoint(6F, 5F, 0F);
leftWing.setTextureSize(64, 64);
setRotation(leftWing, 0.1745329F, 0F, 0F);
tailFeathers = new ModelRenderer(this, 0, 57);
tailFeathers.addBox(-5F, 0F, 0F, 10, 7, 0);
tailFeathers.setRotationPoint(0F, 7F, 1F);
tailFeathers.setTextureSize(64, 64);
tailFeathers.mirror = true;
setRotation(tailFeathers, 0.5235988F, 0F, 0F);
tail = new ModelRenderer(this, 20, 55);
tail.addBox(-1F, 0F, -1F, 2, 7, 2);
tail.setRotationPoint(3F, 15F, 2F);
tail.setTextureSize(64, 64);
tail.mirror = true;
setRotation(tail, 0.4014257F, 0F, 0F);
head = new ModelRenderer(this, 24, 34);
head.addBox(-2F, -4F, -5F, 4, 4, 6);
head.setRotationPoint(0F, -4F, 0F);
head.setTextureSize(64, 64);
head.mirror = true;
setRotation(head, 0F, 0F, 0F);
neck = new ModelRenderer(this, 24, 44);
neck.addBox(-1F, -4F, -1F, 2, 4, 2);
neck.setRotationPoint(0F, 0F, -4F);
neck.setTextureSize(64, 64);
neck.mirror = true;
setRotation(neck, 0.2443461F, 0F, 0F);
beak = new ModelRenderer(this, 32, 44);
beak.addBox(-0.5F, 4F, -1F, 1, 2, 3);
beak.setRotationPoint(0F, -5F, -8F);
beak.setTextureSize(64, 64);
beak.mirror = true;
setRotation(beak, 0.2792527F, 0F, 0F);
plume = new ModelRenderer(this, 28, 50);
plume.addBox(-0.03333334F, 1F, 0F, 0, 5, 5);
plume.setRotationPoint(0F, -7F, 0F);
plume.setTextureSize(64, 64);
plume.mirror = true;
setRotation(plume, 0F, 0F, 0F);
neck.addChild(head);
head.addChild(plume);
head.addChild(beak);
tail.addChild(tailFeathers);
body.addChild(tail);
body.addChild(rightWing);
body.addChild(leftWing);
}
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);
// float f6 = (180F / (float)Math.PI);
this.neck.rotateAngleX = f4 / (180F / (float)Math.PI);
this.neck.rotateAngleY = f3 / (180F / (float)Math.PI);
this.neck.rotateAngleZ = 0.0F;
this.body.rotateAngleX = 0.3f + MathHelper.cos(f2 * 0.1F) * 0.15F;
this.body.rotateAngleY = 0.0F;
this.tail.rotateAngleX = this.body.rotateAngleX * 1.1f;
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;
body.render(f5);
neck.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,58 +0,0 @@
package electroblob.wizardry.client.model;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.entity.living.EntitySkeletonMinion;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.client.model.ModelZombie;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.monster.EntitySkeleton;
@SideOnly(Side.CLIENT)
public class ModelSkeletonMinion extends ModelZombie
{
public ModelSkeletonMinion()
{
this(0.0F);
}
public ModelSkeletonMinion(float par1)
{
super(par1, 0.0F, 64, 32);
this.bipedRightArm = new ModelRenderer(this, 40, 16);
this.bipedRightArm.addBox(-1.0F, -2.0F, -1.0F, 2, 12, 2, par1);
this.bipedRightArm.setRotationPoint(-5.0F, 2.0F, 0.0F);
this.bipedLeftArm = new ModelRenderer(this, 40, 16);
this.bipedLeftArm.mirror = true;
this.bipedLeftArm.addBox(-1.0F, -2.0F, -1.0F, 2, 12, 2, par1);
this.bipedLeftArm.setRotationPoint(5.0F, 2.0F, 0.0F);
this.bipedRightLeg = new ModelRenderer(this, 0, 16);
this.bipedRightLeg.addBox(-1.0F, 0.0F, -1.0F, 2, 12, 2, par1);
this.bipedRightLeg.setRotationPoint(-2.0F, 12.0F, 0.0F);
this.bipedLeftLeg = new ModelRenderer(this, 0, 16);
this.bipedLeftLeg.mirror = true;
this.bipedLeftLeg.addBox(-1.0F, 0.0F, -1.0F, 2, 12, 2, par1);
this.bipedLeftLeg.setRotationPoint(2.0F, 12.0F, 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)
{
this.aimedBow = ((EntitySkeletonMinion)par1EntityLivingBase).getSkeletonType() == 1;
super.setLivingAnimations(par1EntityLivingBase, par2, par3, par4);
}
/**
* 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)
{
super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity);
}
}
@@ -1,559 +0,0 @@
package electroblob.wizardry.client.model;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.entity.living.EntitySpiritHorse;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.MathHelper;
@SideOnly(Side.CLIENT)
public class ModelSpiritHorse extends ModelBase
{
private ModelRenderer head;
private ModelRenderer mouthTop;
private ModelRenderer mouthBottom;
private ModelRenderer horseLeftEar;
private ModelRenderer horseRightEar;
private ModelRenderer field_110703_f;
private ModelRenderer field_110704_g;
private ModelRenderer neck;
private ModelRenderer field_110717_i;
private ModelRenderer mane;
private ModelRenderer body;
private ModelRenderer tailBase;
private ModelRenderer tailMiddle;
private ModelRenderer tailTip;
private ModelRenderer backLeftLeg;
private ModelRenderer backLeftShin;
private ModelRenderer backLeftHoof;
private ModelRenderer backRightLeg;
private ModelRenderer backRightShin;
private ModelRenderer backRightHoof;
private ModelRenderer frontRightLeg;
private ModelRenderer frontLeftShin;
private ModelRenderer frontLeftHoof;
private ModelRenderer field_110684_D;
private ModelRenderer frontRightShin;
private ModelRenderer frontRightHoof;
private ModelRenderer field_110687_G;
private ModelRenderer field_110695_H;
private ModelRenderer field_110696_I;
private ModelRenderer field_110697_J;
private ModelRenderer field_110698_K;
private ModelRenderer field_110691_L;
private ModelRenderer field_110692_M;
private ModelRenderer field_110693_N;
private ModelRenderer field_110694_O;
private ModelRenderer field_110700_P;
private ModelRenderer field_110699_Q;
private ModelRenderer field_110702_R;
private ModelRenderer field_110701_S;
public ModelSpiritHorse()
{
this.textureWidth = 128;
this.textureHeight = 128;
this.body = new ModelRenderer(this, 0, 34);
this.body.addBox(-5.0F, -8.0F, -19.0F, 10, 10, 24);
this.body.setRotationPoint(0.0F, 11.0F, 9.0F);
this.tailBase = new ModelRenderer(this, 44, 0);
this.tailBase.addBox(-1.0F, -1.0F, 0.0F, 2, 2, 3);
this.tailBase.setRotationPoint(0.0F, 3.0F, 14.0F);
this.func_110682_a(this.tailBase, -1.134464F, 0.0F, 0.0F);
this.tailMiddle = new ModelRenderer(this, 38, 7);
this.tailMiddle.addBox(-1.5F, -2.0F, 3.0F, 3, 4, 7);
this.tailMiddle.setRotationPoint(0.0F, 3.0F, 14.0F);
this.func_110682_a(this.tailMiddle, -1.134464F, 0.0F, 0.0F);
this.tailTip = new ModelRenderer(this, 24, 3);
this.tailTip.addBox(-1.5F, -4.5F, 9.0F, 3, 4, 7);
this.tailTip.setRotationPoint(0.0F, 3.0F, 14.0F);
this.func_110682_a(this.tailTip, -1.40215F, 0.0F, 0.0F);
this.backLeftLeg = new ModelRenderer(this, 78, 29);
this.backLeftLeg.addBox(-2.5F, -2.0F, -2.5F, 4, 9, 5);
this.backLeftLeg.setRotationPoint(4.0F, 9.0F, 11.0F);
this.backLeftShin = new ModelRenderer(this, 78, 43);
this.backLeftShin.addBox(-2.0F, 0.0F, -1.5F, 3, 5, 3);
this.backLeftShin.setRotationPoint(4.0F, 16.0F, 11.0F);
this.backLeftHoof = new ModelRenderer(this, 78, 51);
this.backLeftHoof.addBox(-2.5F, 5.1F, -2.0F, 4, 3, 4);
this.backLeftHoof.setRotationPoint(4.0F, 16.0F, 11.0F);
this.backRightLeg = new ModelRenderer(this, 96, 29);
this.backRightLeg.addBox(-1.5F, -2.0F, -2.5F, 4, 9, 5);
this.backRightLeg.setRotationPoint(-4.0F, 9.0F, 11.0F);
this.backRightShin = new ModelRenderer(this, 96, 43);
this.backRightShin.addBox(-1.0F, 0.0F, -1.5F, 3, 5, 3);
this.backRightShin.setRotationPoint(-4.0F, 16.0F, 11.0F);
this.backRightHoof = new ModelRenderer(this, 96, 51);
this.backRightHoof.addBox(-1.5F, 5.1F, -2.0F, 4, 3, 4);
this.backRightHoof.setRotationPoint(-4.0F, 16.0F, 11.0F);
this.frontRightLeg = new ModelRenderer(this, 44, 29);
this.frontRightLeg.addBox(-1.9F, -1.0F, -2.1F, 3, 8, 4);
this.frontRightLeg.setRotationPoint(4.0F, 9.0F, -8.0F);
this.frontLeftShin = new ModelRenderer(this, 44, 41);
this.frontLeftShin.addBox(-1.9F, 0.0F, -1.6F, 3, 5, 3);
this.frontLeftShin.setRotationPoint(4.0F, 16.0F, -8.0F);
this.frontLeftHoof = new ModelRenderer(this, 44, 51);
this.frontLeftHoof.addBox(-2.4F, 5.1F, -2.1F, 4, 3, 4);
this.frontLeftHoof.setRotationPoint(4.0F, 16.0F, -8.0F);
this.field_110684_D = new ModelRenderer(this, 60, 29);
this.field_110684_D.addBox(-1.1F, -1.0F, -2.1F, 3, 8, 4);
this.field_110684_D.setRotationPoint(-4.0F, 9.0F, -8.0F);
this.frontRightShin = new ModelRenderer(this, 60, 41);
this.frontRightShin.addBox(-1.1F, 0.0F, -1.6F, 3, 5, 3);
this.frontRightShin.setRotationPoint(-4.0F, 16.0F, -8.0F);
this.frontRightHoof = new ModelRenderer(this, 60, 51);
this.frontRightHoof.addBox(-1.6F, 5.1F, -2.1F, 4, 3, 4);
this.frontRightHoof.setRotationPoint(-4.0F, 16.0F, -8.0F);
this.head = new ModelRenderer(this, 0, 0);
this.head.addBox(-2.5F, -10.0F, -1.5F, 5, 5, 7);
this.head.setRotationPoint(0.0F, 4.0F, -10.0F);
this.func_110682_a(this.head, 0.5235988F, 0.0F, 0.0F);
this.mouthTop = new ModelRenderer(this, 24, 18);
this.mouthTop.addBox(-2.0F, -10.0F, -7.0F, 4, 3, 6);
this.mouthTop.setRotationPoint(0.0F, 3.95F, -10.0F);
this.func_110682_a(this.mouthTop, 0.5235988F, 0.0F, 0.0F);
this.mouthBottom = new ModelRenderer(this, 24, 27);
this.mouthBottom.addBox(-2.0F, -7.0F, -6.5F, 4, 2, 5);
this.mouthBottom.setRotationPoint(0.0F, 4.0F, -10.0F);
this.func_110682_a(this.mouthBottom, 0.5235988F, 0.0F, 0.0F);
this.head.addChild(this.mouthTop);
this.head.addChild(this.mouthBottom);
this.horseLeftEar = new ModelRenderer(this, 0, 0);
this.horseLeftEar.addBox(0.45F, -12.0F, 4.0F, 2, 3, 1);
this.horseLeftEar.setRotationPoint(0.0F, 4.0F, -10.0F);
this.func_110682_a(this.horseLeftEar, 0.5235988F, 0.0F, 0.0F);
this.horseRightEar = new ModelRenderer(this, 0, 0);
this.horseRightEar.addBox(-2.45F, -12.0F, 4.0F, 2, 3, 1);
this.horseRightEar.setRotationPoint(0.0F, 4.0F, -10.0F);
this.func_110682_a(this.horseRightEar, 0.5235988F, 0.0F, 0.0F);
this.field_110703_f = new ModelRenderer(this, 0, 12);
this.field_110703_f.addBox(-2.0F, -16.0F, 4.0F, 2, 7, 1);
this.field_110703_f.setRotationPoint(0.0F, 4.0F, -10.0F);
this.func_110682_a(this.field_110703_f, 0.5235988F, 0.0F, 0.2617994F);
this.field_110704_g = new ModelRenderer(this, 0, 12);
this.field_110704_g.addBox(0.0F, -16.0F, 4.0F, 2, 7, 1);
this.field_110704_g.setRotationPoint(0.0F, 4.0F, -10.0F);
this.func_110682_a(this.field_110704_g, 0.5235988F, 0.0F, -0.2617994F);
this.neck = new ModelRenderer(this, 0, 12);
this.neck.addBox(-2.05F, -9.8F, -2.0F, 4, 14, 8);
this.neck.setRotationPoint(0.0F, 4.0F, -10.0F);
this.func_110682_a(this.neck, 0.5235988F, 0.0F, 0.0F);
this.field_110687_G = new ModelRenderer(this, 0, 34);
this.field_110687_G.addBox(-3.0F, 0.0F, 0.0F, 8, 8, 3);
this.field_110687_G.setRotationPoint(-7.5F, 3.0F, 10.0F);
this.func_110682_a(this.field_110687_G, 0.0F, ((float)Math.PI / 2F), 0.0F);
this.field_110695_H = new ModelRenderer(this, 0, 47);
this.field_110695_H.addBox(-3.0F, 0.0F, 0.0F, 8, 8, 3);
this.field_110695_H.setRotationPoint(4.5F, 3.0F, 10.0F);
this.func_110682_a(this.field_110695_H, 0.0F, ((float)Math.PI / 2F), 0.0F);
this.field_110696_I = new ModelRenderer(this, 80, 0);
this.field_110696_I.addBox(-5.0F, 0.0F, -3.0F, 10, 1, 8);
this.field_110696_I.setRotationPoint(0.0F, 2.0F, 2.0F);
this.field_110697_J = new ModelRenderer(this, 106, 9);
this.field_110697_J.addBox(-1.5F, -1.0F, -3.0F, 3, 1, 2);
this.field_110697_J.setRotationPoint(0.0F, 2.0F, 2.0F);
this.field_110698_K = new ModelRenderer(this, 80, 9);
this.field_110698_K.addBox(-4.0F, -1.0F, 3.0F, 8, 1, 2);
this.field_110698_K.setRotationPoint(0.0F, 2.0F, 2.0F);
this.field_110692_M = new ModelRenderer(this, 74, 0);
this.field_110692_M.addBox(-0.5F, 6.0F, -1.0F, 1, 2, 2);
this.field_110692_M.setRotationPoint(5.0F, 3.0F, 2.0F);
this.field_110691_L = new ModelRenderer(this, 70, 0);
this.field_110691_L.addBox(-0.5F, 0.0F, -0.5F, 1, 6, 1);
this.field_110691_L.setRotationPoint(5.0F, 3.0F, 2.0F);
this.field_110694_O = new ModelRenderer(this, 74, 4);
this.field_110694_O.addBox(-0.5F, 6.0F, -1.0F, 1, 2, 2);
this.field_110694_O.setRotationPoint(-5.0F, 3.0F, 2.0F);
this.field_110693_N = new ModelRenderer(this, 80, 0);
this.field_110693_N.addBox(-0.5F, 0.0F, -0.5F, 1, 6, 1);
this.field_110693_N.setRotationPoint(-5.0F, 3.0F, 2.0F);
this.field_110700_P = new ModelRenderer(this, 74, 13);
this.field_110700_P.addBox(1.5F, -8.0F, -4.0F, 1, 2, 2);
this.field_110700_P.setRotationPoint(0.0F, 4.0F, -10.0F);
this.func_110682_a(this.field_110700_P, 0.5235988F, 0.0F, 0.0F);
this.field_110699_Q = new ModelRenderer(this, 74, 13);
this.field_110699_Q.addBox(-2.5F, -8.0F, -4.0F, 1, 2, 2);
this.field_110699_Q.setRotationPoint(0.0F, 4.0F, -10.0F);
this.func_110682_a(this.field_110699_Q, 0.5235988F, 0.0F, 0.0F);
this.field_110702_R = new ModelRenderer(this, 44, 10);
this.field_110702_R.addBox(2.6F, -6.0F, -6.0F, 0, 3, 16);
this.field_110702_R.setRotationPoint(0.0F, 4.0F, -10.0F);
this.field_110701_S = new ModelRenderer(this, 44, 5);
this.field_110701_S.addBox(-2.6F, -6.0F, -6.0F, 0, 3, 16);
this.field_110701_S.setRotationPoint(0.0F, 4.0F, -10.0F);
this.mane = new ModelRenderer(this, 58, 0);
this.mane.addBox(-1.0F, -11.5F, 5.0F, 2, 16, 4);
this.mane.setRotationPoint(0.0F, 4.0F, -10.0F);
this.func_110682_a(this.mane, 0.5235988F, 0.0F, 0.0F);
this.field_110717_i = new ModelRenderer(this, 80, 12);
this.field_110717_i.addBox(-2.5F, -10.1F, -7.0F, 5, 5, 12, 0.2F);
this.field_110717_i.setRotationPoint(0.0F, 4.0F, -10.0F);
this.func_110682_a(this.field_110717_i, 0.5235988F, 0.0F, 0.0F);
}
/**
* 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)
{
EntitySpiritHorse entityhorse = (EntitySpiritHorse)par1Entity;
int i = entityhorse.getHorseType();
float f6 = entityhorse.getGrassEatingAmount(0.0F);
boolean flag = entityhorse.isAdultHorse();
boolean flag1 = flag && entityhorse.isHorseSaddled();
boolean flag2 = flag && entityhorse.isChested();
boolean flag3 = i == 1 || i == 2;
float f7 = entityhorse.getHorseSize();
boolean flag4 = entityhorse.riddenByEntity != null;
if (flag1)
{
this.field_110717_i.render(par7);
this.field_110696_I.render(par7);
this.field_110697_J.render(par7);
this.field_110698_K.render(par7);
this.field_110691_L.render(par7);
this.field_110692_M.render(par7);
this.field_110693_N.render(par7);
this.field_110694_O.render(par7);
this.field_110700_P.render(par7);
this.field_110699_Q.render(par7);
if (flag4)
{
this.field_110702_R.render(par7);
this.field_110701_S.render(par7);
}
}
if (!flag)
{
GL11.glPushMatrix();
GL11.glScalef(f7, 0.5F + f7 * 0.5F, f7);
GL11.glTranslatef(0.0F, 0.95F * (1.0F - f7), 0.0F);
}
this.backLeftLeg.render(par7);
this.backLeftShin.render(par7);
this.backLeftHoof.render(par7);
this.backRightLeg.render(par7);
this.backRightShin.render(par7);
this.backRightHoof.render(par7);
this.frontRightLeg.render(par7);
this.frontLeftShin.render(par7);
this.frontLeftHoof.render(par7);
this.field_110684_D.render(par7);
this.frontRightShin.render(par7);
this.frontRightHoof.render(par7);
if (!flag)
{
GL11.glPopMatrix();
GL11.glPushMatrix();
GL11.glScalef(f7, f7, f7);
GL11.glTranslatef(0.0F, 1.35F * (1.0F - f7), 0.0F);
}
this.body.render(par7);
this.tailBase.render(par7);
this.tailMiddle.render(par7);
this.tailTip.render(par7);
this.neck.render(par7);
this.mane.render(par7);
if (!flag)
{
GL11.glPopMatrix();
GL11.glPushMatrix();
float f8 = 0.5F + f7 * f7 * 0.5F;
GL11.glScalef(f8, f8, f8);
if (f6 <= 0.0F)
{
GL11.glTranslatef(0.0F, 1.35F * (1.0F - f7), 0.0F);
}
else
{
GL11.glTranslatef(0.0F, 0.9F * (1.0F - f7) * f6 + 1.35F * (1.0F - f7) * (1.0F - f6), 0.15F * (1.0F - f7) * f6);
}
}
if (flag3)
{
this.field_110703_f.render(par7);
this.field_110704_g.render(par7);
}
else
{
this.horseLeftEar.render(par7);
this.horseRightEar.render(par7);
}
this.head.render(par7);
if (!flag)
{
GL11.glPopMatrix();
}
if (flag2)
{
this.field_110687_G.render(par7);
this.field_110695_H.render(par7);
}
}
private void func_110682_a(ModelRenderer par1ModelRenderer, float par2, float par3, float par4)
{
par1ModelRenderer.rotateAngleX = par2;
par1ModelRenderer.rotateAngleY = par3;
par1ModelRenderer.rotateAngleZ = par4;
}
private float func_110683_a(float par1, float par2, float par3)
{
float f3;
for (f3 = par2 - par1; f3 < -180.0F; f3 += 360.0F)
{
;
}
while (f3 >= 180.0F)
{
f3 -= 360.0F;
}
return par1 + par3 * f3;
}
/**
* 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)
{
super.setLivingAnimations(par1EntityLivingBase, par2, par3, par4);
float f3 = this.func_110683_a(par1EntityLivingBase.prevRenderYawOffset, par1EntityLivingBase.renderYawOffset, par4);
float f4 = this.func_110683_a(par1EntityLivingBase.prevRotationYawHead, par1EntityLivingBase.rotationYawHead, par4);
float f5 = par1EntityLivingBase.prevRotationPitch + (par1EntityLivingBase.rotationPitch - par1EntityLivingBase.prevRotationPitch) * par4;
float f6 = f4 - f3;
float f7 = f5 / (180F / (float)Math.PI);
if (f6 > 20.0F)
{
f6 = 20.0F;
}
if (f6 < -20.0F)
{
f6 = -20.0F;
}
if (par3 > 0.2F)
{
f7 += MathHelper.cos(par2 * 0.4F) * 0.15F * par3;
}
EntitySpiritHorse entityhorse = (EntitySpiritHorse)par1EntityLivingBase;
float f8 = entityhorse.getGrassEatingAmount(par4);
float f9 = entityhorse.getRearingAmount(par4);
float f10 = 1.0F - f9;
float f11 = entityhorse.func_110201_q(par4);
boolean flag = entityhorse.field_110278_bp != 0;
boolean flag1 = entityhorse.isHorseSaddled();
boolean flag2 = entityhorse.riddenByEntity != null;
float f12 = (float)par1EntityLivingBase.ticksExisted + par4;
float f13 = MathHelper.cos(par2 * 0.6662F + (float)Math.PI);
float f14 = f13 * 0.8F * par3;
this.head.rotationPointY = 4.0F;
this.head.rotationPointZ = -10.0F;
this.tailBase.rotationPointY = 3.0F;
this.tailMiddle.rotationPointZ = 14.0F;
this.field_110695_H.rotationPointY = 3.0F;
this.field_110695_H.rotationPointZ = 10.0F;
this.body.rotateAngleX = 0.0F;
this.head.rotateAngleX = 0.5235988F + f7;
this.head.rotateAngleY = f6 / (180F / (float)Math.PI);
this.head.rotateAngleX = f9 * (0.2617994F + f7) + f8 * 2.18166F + (1.0F - Math.max(f9, f8)) * this.head.rotateAngleX;
this.head.rotateAngleY = f9 * (f6 / (180F / (float)Math.PI)) + (1.0F - Math.max(f9, f8)) * this.head.rotateAngleY;
this.head.rotationPointY = f9 * -6.0F + f8 * 11.0F + (1.0F - Math.max(f9, f8)) * this.head.rotationPointY;
this.head.rotationPointZ = f9 * -1.0F + f8 * -10.0F + (1.0F - Math.max(f9, f8)) * this.head.rotationPointZ;
this.tailBase.rotationPointY = f9 * 9.0F + f10 * this.tailBase.rotationPointY;
this.tailMiddle.rotationPointZ = f9 * 18.0F + f10 * this.tailMiddle.rotationPointZ;
this.field_110695_H.rotationPointY = f9 * 5.5F + f10 * this.field_110695_H.rotationPointY;
this.field_110695_H.rotationPointZ = f9 * 15.0F + f10 * this.field_110695_H.rotationPointZ;
this.body.rotateAngleX = f9 * -((float)Math.PI / 4F) + f10 * this.body.rotateAngleX;
this.horseLeftEar.rotationPointY = this.head.rotationPointY;
this.horseRightEar.rotationPointY = this.head.rotationPointY;
this.field_110703_f.rotationPointY = this.head.rotationPointY;
this.field_110704_g.rotationPointY = this.head.rotationPointY;
this.neck.rotationPointY = this.head.rotationPointY;
this.mouthTop.rotationPointY = 0.02F;
this.mouthBottom.rotationPointY = 0.0F;
this.mane.rotationPointY = this.head.rotationPointY;
this.horseLeftEar.rotationPointZ = this.head.rotationPointZ;
this.horseRightEar.rotationPointZ = this.head.rotationPointZ;
this.field_110703_f.rotationPointZ = this.head.rotationPointZ;
this.field_110704_g.rotationPointZ = this.head.rotationPointZ;
this.neck.rotationPointZ = this.head.rotationPointZ;
this.mouthTop.rotationPointZ = 0.02F - f11 * 1.0F;
this.mouthBottom.rotationPointZ = 0.0F + f11 * 1.0F;
this.mane.rotationPointZ = this.head.rotationPointZ;
this.horseLeftEar.rotateAngleX = this.head.rotateAngleX;
this.horseRightEar.rotateAngleX = this.head.rotateAngleX;
this.field_110703_f.rotateAngleX = this.head.rotateAngleX;
this.field_110704_g.rotateAngleX = this.head.rotateAngleX;
this.neck.rotateAngleX = this.head.rotateAngleX;
this.mouthTop.rotateAngleX = 0.0F - 0.09424778F * f11;
this.mouthBottom.rotateAngleX = 0.0F + 0.15707964F * f11;
this.mane.rotateAngleX = this.head.rotateAngleX;
this.horseLeftEar.rotateAngleY = this.head.rotateAngleY;
this.horseRightEar.rotateAngleY = this.head.rotateAngleY;
this.field_110703_f.rotateAngleY = this.head.rotateAngleY;
this.field_110704_g.rotateAngleY = this.head.rotateAngleY;
this.neck.rotateAngleY = this.head.rotateAngleY;
this.mouthTop.rotateAngleY = 0.0F;
this.mouthBottom.rotateAngleY = 0.0F;
this.mane.rotateAngleY = this.head.rotateAngleY;
this.field_110687_G.rotateAngleX = f14 / 5.0F;
this.field_110695_H.rotateAngleX = -f14 / 5.0F;
float f15 = ((float)Math.PI / 2F);
float f16 = ((float)Math.PI * 3F / 2F);
float f17 = -1.0471976F;
float f18 = 0.2617994F * f9;
float f19 = MathHelper.cos(f12 * 0.6F + (float)Math.PI);
this.frontRightLeg.rotationPointY = -2.0F * f9 + 9.0F * f10;
this.frontRightLeg.rotationPointZ = -2.0F * f9 + -8.0F * f10;
this.field_110684_D.rotationPointY = this.frontRightLeg.rotationPointY;
this.field_110684_D.rotationPointZ = this.frontRightLeg.rotationPointZ;
this.backLeftShin.rotationPointY = this.backLeftLeg.rotationPointY + MathHelper.sin(((float)Math.PI / 2F) + f18 + f10 * -f13 * 0.5F * par3) * 7.0F;
this.backLeftShin.rotationPointZ = this.backLeftLeg.rotationPointZ + MathHelper.cos(((float)Math.PI * 3F / 2F) + f18 + f10 * -f13 * 0.5F * par3) * 7.0F;
this.backRightShin.rotationPointY = this.backRightLeg.rotationPointY + MathHelper.sin(((float)Math.PI / 2F) + f18 + f10 * f13 * 0.5F * par3) * 7.0F;
this.backRightShin.rotationPointZ = this.backRightLeg.rotationPointZ + MathHelper.cos(((float)Math.PI * 3F / 2F) + f18 + f10 * f13 * 0.5F * par3) * 7.0F;
float f20 = (-1.0471976F + f19) * f9 + f14 * f10;
float f21 = (-1.0471976F + -f19) * f9 + -f14 * f10;
this.frontLeftShin.rotationPointY = this.frontRightLeg.rotationPointY + MathHelper.sin(((float)Math.PI / 2F) + f20) * 7.0F;
this.frontLeftShin.rotationPointZ = this.frontRightLeg.rotationPointZ + MathHelper.cos(((float)Math.PI * 3F / 2F) + f20) * 7.0F;
this.frontRightShin.rotationPointY = this.field_110684_D.rotationPointY + MathHelper.sin(((float)Math.PI / 2F) + f21) * 7.0F;
this.frontRightShin.rotationPointZ = this.field_110684_D.rotationPointZ + MathHelper.cos(((float)Math.PI * 3F / 2F) + f21) * 7.0F;
this.backLeftLeg.rotateAngleX = f18 + -f13 * 0.5F * par3 * f10;
this.backLeftShin.rotateAngleX = -0.08726646F * f9 + (-f13 * 0.5F * par3 - Math.max(0.0F, f13 * 0.5F * par3)) * f10;
this.backLeftHoof.rotateAngleX = this.backLeftShin.rotateAngleX;
this.backRightLeg.rotateAngleX = f18 + f13 * 0.5F * par3 * f10;
this.backRightShin.rotateAngleX = -0.08726646F * f9 + (f13 * 0.5F * par3 - Math.max(0.0F, -f13 * 0.5F * par3)) * f10;
this.backRightHoof.rotateAngleX = this.backRightShin.rotateAngleX;
this.frontRightLeg.rotateAngleX = f20;
this.frontLeftShin.rotateAngleX = (this.frontRightLeg.rotateAngleX + (float)Math.PI * Math.max(0.0F, 0.2F + f19 * 0.2F)) * f9 + (f14 + Math.max(0.0F, f13 * 0.5F * par3)) * f10;
this.frontLeftHoof.rotateAngleX = this.frontLeftShin.rotateAngleX;
this.field_110684_D.rotateAngleX = f21;
this.frontRightShin.rotateAngleX = (this.field_110684_D.rotateAngleX + (float)Math.PI * Math.max(0.0F, 0.2F - f19 * 0.2F)) * f9 + (-f14 + Math.max(0.0F, -f13 * 0.5F * par3)) * f10;
this.frontRightHoof.rotateAngleX = this.frontRightShin.rotateAngleX;
this.backLeftHoof.rotationPointY = this.backLeftShin.rotationPointY;
this.backLeftHoof.rotationPointZ = this.backLeftShin.rotationPointZ;
this.backRightHoof.rotationPointY = this.backRightShin.rotationPointY;
this.backRightHoof.rotationPointZ = this.backRightShin.rotationPointZ;
this.frontLeftHoof.rotationPointY = this.frontLeftShin.rotationPointY;
this.frontLeftHoof.rotationPointZ = this.frontLeftShin.rotationPointZ;
this.frontRightHoof.rotationPointY = this.frontRightShin.rotationPointY;
this.frontRightHoof.rotationPointZ = this.frontRightShin.rotationPointZ;
if (flag1)
{
this.field_110696_I.rotationPointY = f9 * 0.5F + f10 * 2.0F;
this.field_110696_I.rotationPointZ = f9 * 11.0F + f10 * 2.0F;
this.field_110697_J.rotationPointY = this.field_110696_I.rotationPointY;
this.field_110698_K.rotationPointY = this.field_110696_I.rotationPointY;
this.field_110691_L.rotationPointY = this.field_110696_I.rotationPointY;
this.field_110693_N.rotationPointY = this.field_110696_I.rotationPointY;
this.field_110692_M.rotationPointY = this.field_110696_I.rotationPointY;
this.field_110694_O.rotationPointY = this.field_110696_I.rotationPointY;
this.field_110687_G.rotationPointY = this.field_110695_H.rotationPointY;
this.field_110697_J.rotationPointZ = this.field_110696_I.rotationPointZ;
this.field_110698_K.rotationPointZ = this.field_110696_I.rotationPointZ;
this.field_110691_L.rotationPointZ = this.field_110696_I.rotationPointZ;
this.field_110693_N.rotationPointZ = this.field_110696_I.rotationPointZ;
this.field_110692_M.rotationPointZ = this.field_110696_I.rotationPointZ;
this.field_110694_O.rotationPointZ = this.field_110696_I.rotationPointZ;
this.field_110687_G.rotationPointZ = this.field_110695_H.rotationPointZ;
this.field_110696_I.rotateAngleX = this.body.rotateAngleX;
this.field_110697_J.rotateAngleX = this.body.rotateAngleX;
this.field_110698_K.rotateAngleX = this.body.rotateAngleX;
this.field_110702_R.rotationPointY = this.head.rotationPointY;
this.field_110701_S.rotationPointY = this.head.rotationPointY;
this.field_110717_i.rotationPointY = this.head.rotationPointY;
this.field_110700_P.rotationPointY = this.head.rotationPointY;
this.field_110699_Q.rotationPointY = this.head.rotationPointY;
this.field_110702_R.rotationPointZ = this.head.rotationPointZ;
this.field_110701_S.rotationPointZ = this.head.rotationPointZ;
this.field_110717_i.rotationPointZ = this.head.rotationPointZ;
this.field_110700_P.rotationPointZ = this.head.rotationPointZ;
this.field_110699_Q.rotationPointZ = this.head.rotationPointZ;
this.field_110702_R.rotateAngleX = f7;
this.field_110701_S.rotateAngleX = f7;
this.field_110717_i.rotateAngleX = this.head.rotateAngleX;
this.field_110700_P.rotateAngleX = this.head.rotateAngleX;
this.field_110699_Q.rotateAngleX = this.head.rotateAngleX;
this.field_110717_i.rotateAngleY = this.head.rotateAngleY;
this.field_110700_P.rotateAngleY = this.head.rotateAngleY;
this.field_110702_R.rotateAngleY = this.head.rotateAngleY;
this.field_110699_Q.rotateAngleY = this.head.rotateAngleY;
this.field_110701_S.rotateAngleY = this.head.rotateAngleY;
if (flag2)
{
this.field_110691_L.rotateAngleX = -1.0471976F;
this.field_110692_M.rotateAngleX = -1.0471976F;
this.field_110693_N.rotateAngleX = -1.0471976F;
this.field_110694_O.rotateAngleX = -1.0471976F;
this.field_110691_L.rotateAngleZ = 0.0F;
this.field_110692_M.rotateAngleZ = 0.0F;
this.field_110693_N.rotateAngleZ = 0.0F;
this.field_110694_O.rotateAngleZ = 0.0F;
}
else
{
this.field_110691_L.rotateAngleX = f14 / 3.0F;
this.field_110692_M.rotateAngleX = f14 / 3.0F;
this.field_110693_N.rotateAngleX = f14 / 3.0F;
this.field_110694_O.rotateAngleX = f14 / 3.0F;
this.field_110691_L.rotateAngleZ = f14 / 5.0F;
this.field_110692_M.rotateAngleZ = f14 / 5.0F;
this.field_110693_N.rotateAngleZ = -f14 / 5.0F;
this.field_110694_O.rotateAngleZ = -f14 / 5.0F;
}
}
f15 = -1.3089F + par3 * 1.5F;
if (f15 > 0.0F)
{
f15 = 0.0F;
}
if (flag)
{
this.tailBase.rotateAngleY = MathHelper.cos(f12 * 0.7F);
f15 = 0.0F;
}
else
{
this.tailBase.rotateAngleY = 0.0F;
}
this.tailMiddle.rotateAngleY = this.tailBase.rotateAngleY;
this.tailTip.rotateAngleY = this.tailBase.rotateAngleY;
this.tailMiddle.rotationPointY = this.tailBase.rotationPointY;
this.tailTip.rotationPointY = this.tailBase.rotationPointY;
this.tailMiddle.rotationPointZ = this.tailBase.rotationPointZ;
this.tailTip.rotationPointZ = this.tailBase.rotationPointZ;
this.tailBase.rotateAngleX = f15;
this.tailMiddle.rotateAngleX = f15;
this.tailTip.rotateAngleX = -0.2618F + f15;
}
}
@@ -1,190 +0,0 @@
package electroblob.wizardry.client.model;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.MathHelper;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.entity.living.EntitySpiritWolf;
@SideOnly(Side.CLIENT)
public class ModelSpiritWolf extends ModelBase
{
/** main box for the wolf head */
public ModelRenderer wolfHeadMain;
/** The wolf's body */
public ModelRenderer wolfBody;
/** Wolf'se first leg */
public ModelRenderer wolfLeg1;
/** Wolf's second leg */
public ModelRenderer wolfLeg2;
/** Wolf's third leg */
public ModelRenderer wolfLeg3;
/** Wolf's fourth leg */
public ModelRenderer wolfLeg4;
/** The wolf's tail */
ModelRenderer wolfTail;
/** The wolf's mane */
ModelRenderer wolfMane;
public ModelSpiritWolf()
{
float f = 0.0F;
float f1 = 13.5F;
this.wolfHeadMain = new ModelRenderer(this, 0, 0);
this.wolfHeadMain.addBox(-3.0F, -3.0F, -2.0F, 6, 6, 4, f);
this.wolfHeadMain.setRotationPoint(-1.0F, f1, -7.0F);
this.wolfBody = new ModelRenderer(this, 18, 14);
this.wolfBody.addBox(-4.0F, -2.0F, -3.0F, 6, 9, 6, f);
this.wolfBody.setRotationPoint(0.0F, 14.0F, 2.0F);
this.wolfMane = new ModelRenderer(this, 21, 0);
this.wolfMane.addBox(-4.0F, -3.0F, -3.0F, 8, 6, 7, f);
this.wolfMane.setRotationPoint(-1.0F, 14.0F, 2.0F);
this.wolfLeg1 = new ModelRenderer(this, 0, 18);
this.wolfLeg1.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, f);
this.wolfLeg1.setRotationPoint(-2.5F, 16.0F, 7.0F);
this.wolfLeg2 = new ModelRenderer(this, 0, 18);
this.wolfLeg2.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, f);
this.wolfLeg2.setRotationPoint(0.5F, 16.0F, 7.0F);
this.wolfLeg3 = new ModelRenderer(this, 0, 18);
this.wolfLeg3.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, f);
this.wolfLeg3.setRotationPoint(-2.5F, 16.0F, -4.0F);
this.wolfLeg4 = new ModelRenderer(this, 0, 18);
this.wolfLeg4.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, f);
this.wolfLeg4.setRotationPoint(0.5F, 16.0F, -4.0F);
this.wolfTail = new ModelRenderer(this, 9, 18);
this.wolfTail.addBox(-1.0F, 0.0F, -1.0F, 2, 8, 2, f);
this.wolfTail.setRotationPoint(-1.0F, 12.0F, 8.0F);
this.wolfHeadMain.setTextureOffset(16, 14).addBox(-3.0F, -5.0F, 0.0F, 2, 2, 1, f);
this.wolfHeadMain.setTextureOffset(16, 14).addBox(1.0F, -5.0F, 0.0F, 2, 2, 1, f);
this.wolfHeadMain.setTextureOffset(0, 10).addBox(-1.5F, 0.0F, -5.0F, 3, 3, 4, f);
}
/**
* 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)
{
super.render(par1Entity, par2, par3, par4, par5, par6, par7);
this.setRotationAngles(par2, par3, par4, par5, par6, par7, par1Entity);
if (this.isChild)
{
float f6 = 2.0F;
GL11.glPushMatrix();
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glTranslatef(0.0F, 5.0F * par7, 2.0F * par7);
this.wolfHeadMain.renderWithRotation(par7);
GL11.glDisable(GL11.GL_BLEND);
GL11.glPopMatrix();
GL11.glPushMatrix();
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glScalef(1.0F / f6, 1.0F / f6, 1.0F / f6);
GL11.glTranslatef(0.0F, 24.0F * par7, 0.0F);
this.wolfBody.render(par7);
this.wolfLeg1.render(par7);
this.wolfLeg2.render(par7);
this.wolfLeg3.render(par7);
this.wolfLeg4.render(par7);
this.wolfTail.renderWithRotation(par7);
this.wolfMane.render(par7);
GL11.glDisable(GL11.GL_BLEND);
GL11.glPopMatrix();
}
else
{
this.wolfHeadMain.renderWithRotation(par7);
this.wolfBody.render(par7);
this.wolfLeg1.render(par7);
this.wolfLeg2.render(par7);
this.wolfLeg3.render(par7);
this.wolfLeg4.render(par7);
this.wolfTail.renderWithRotation(par7);
this.wolfMane.render(par7);
}
}
/**
* 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)
{
EntitySpiritWolf EntitySpiritWolf = (EntitySpiritWolf)par1EntityLivingBase;
if (EntitySpiritWolf.isAngry())
{
this.wolfTail.rotateAngleY = 0.0F;
}
else
{
this.wolfTail.rotateAngleY = MathHelper.cos(par2 * 0.6662F) * 1.4F * par3;
}
if (EntitySpiritWolf.isSitting())
{
this.wolfMane.setRotationPoint(-1.0F, 16.0F, -3.0F);
this.wolfMane.rotateAngleX = ((float)Math.PI * 2F / 5F);
this.wolfMane.rotateAngleY = 0.0F;
this.wolfBody.setRotationPoint(0.0F, 18.0F, 0.0F);
this.wolfBody.rotateAngleX = ((float)Math.PI / 4F);
this.wolfTail.setRotationPoint(-1.0F, 21.0F, 6.0F);
this.wolfLeg1.setRotationPoint(-2.5F, 22.0F, 2.0F);
this.wolfLeg1.rotateAngleX = ((float)Math.PI * 3F / 2F);
this.wolfLeg2.setRotationPoint(0.5F, 22.0F, 2.0F);
this.wolfLeg2.rotateAngleX = ((float)Math.PI * 3F / 2F);
this.wolfLeg3.rotateAngleX = 5.811947F;
this.wolfLeg3.setRotationPoint(-2.49F, 17.0F, -4.0F);
this.wolfLeg4.rotateAngleX = 5.811947F;
this.wolfLeg4.setRotationPoint(0.51F, 17.0F, -4.0F);
}
else
{
this.wolfBody.setRotationPoint(0.0F, 14.0F, 2.0F);
this.wolfBody.rotateAngleX = ((float)Math.PI / 2F);
this.wolfMane.setRotationPoint(-1.0F, 14.0F, -3.0F);
this.wolfMane.rotateAngleX = this.wolfBody.rotateAngleX;
this.wolfTail.setRotationPoint(-1.0F, 12.0F, 8.0F);
this.wolfLeg1.setRotationPoint(-2.5F, 16.0F, 7.0F);
this.wolfLeg2.setRotationPoint(0.5F, 16.0F, 7.0F);
this.wolfLeg3.setRotationPoint(-2.5F, 16.0F, -4.0F);
this.wolfLeg4.setRotationPoint(0.5F, 16.0F, -4.0F);
this.wolfLeg1.rotateAngleX = MathHelper.cos(par2 * 0.6662F) * 1.4F * par3;
this.wolfLeg2.rotateAngleX = MathHelper.cos(par2 * 0.6662F + (float)Math.PI) * 1.4F * par3;
this.wolfLeg3.rotateAngleX = MathHelper.cos(par2 * 0.6662F + (float)Math.PI) * 1.4F * par3;
this.wolfLeg4.rotateAngleX = MathHelper.cos(par2 * 0.6662F) * 1.4F * par3;
}
this.wolfHeadMain.rotateAngleZ = EntitySpiritWolf.getInterestedAngle(par4) + EntitySpiritWolf.getShakeAngle(par4, 0.0F);
this.wolfMane.rotateAngleZ = EntitySpiritWolf.getShakeAngle(par4, -0.08F);
this.wolfBody.rotateAngleZ = EntitySpiritWolf.getShakeAngle(par4, -0.16F);
this.wolfTail.rotateAngleZ = EntitySpiritWolf.getShakeAngle(par4, -0.2F);
}
/**
* 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)
{
super.setRotationAngles(par1, par2, par3, par4, par5, par6, par7Entity);
this.wolfHeadMain.rotateAngleX = par5 / (180F / (float)Math.PI);
this.wolfHeadMain.rotateAngleY = par4 / (180F / (float)Math.PI);
this.wolfTail.rotateAngleX = par3;
}
}
@@ -2,174 +2,128 @@ package electroblob.wizardry.client.model;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity;
public class ModelWizard extends ModelBiped
{
//fields
ModelRenderer Shape5;
ModelRenderer Shape8;
ModelRenderer Shape9;
ModelRenderer Shape10;
ModelRenderer Shape7;
ModelRenderer Shape11;
ModelRenderer Shape12;
ModelRenderer beard;
ModelRenderer Shape13;
public ModelWizard()
{
//super(0, 0, 64, 32);
/*
bipedRightLeg = new ModelRenderer(this, 32, 0); // 32 and 0 are the x and y texture offsets respectively.
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.mirror = true;
setRotation(bipedRightLeg, 0F, 0F, 0F);
bipedLeftLeg.mirror = true;
bipedLeftLeg = new ModelRenderer(this, 32, 0);
bipedLeftLeg.addBox(-2F, 0F, -2F, 4, 12, 4);
bipedLeftLeg.setRotationPoint(2F, 12F, 0F);
bipedLeftLeg.setTextureSize(64, 64);
bipedLeftLeg.mirror = true;
setRotation(bipedLeftLeg, 0F, 0F, 0F);
bipedLeftLeg.mirror = false;
bipedBody = new ModelRenderer(this, 0, 16);
bipedBody.addBox(0F, 0F, 0F, 8, 12, 4);
bipedBody.setRotationPoint(-4F, 0F, -2F);
bipedBody.setTextureSize(64, 64);
bipedBody.mirror = true;
setRotation(bipedBody, 0F, 0F, 0F);
bipedLeftArm.mirror = true;
bipedLeftArm = new ModelRenderer(this, 48, 0);
bipedLeftArm.addBox(-1F, 0F, -2F, 4, 12, 4);
bipedLeftArm.setRotationPoint(4F, 0F, 0F);
bipedLeftArm.setTextureSize(64, 64);
bipedLeftArm.mirror = true;
setRotation(bipedLeftArm, 0F, 0F, 0F);
bipedLeftArm.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 = true;
setRotation(bipedRightArm, 0F, 0F, 0F);
bipedHead = new ModelRenderer(this, 0, 0);
bipedHead.addBox(-4F, -8F, -4F, 8, 8, 8);
bipedHead.setRotationPoint(0F, 0F, 0F);
bipedHead.setTextureSize(64, 64);
bipedHead.mirror = true;
setRotation(bipedHead, 0F, 0F, 0F);
*/
Shape5 = new ModelRenderer(this, 0, 51);
Shape5.addBox(0F, 0F, 0F, 12, 1, 12);
Shape5.setRotationPoint(-6F, -7F, -6F);
Shape5.setTextureSize(64, 64);
Shape5.mirror = true;
setRotation(Shape5, 0F, 0F, 0F);
Shape8 = new ModelRenderer(this, 0, 32);
Shape8.addBox(0F, 0F, 0F, 6, 1, 6);
Shape8.setRotationPoint(-3F, -9F, -3F);
Shape8.setTextureSize(64, 64);
Shape8.mirror = true;
setRotation(Shape8, -0.0349066F, 0F, 0F);
Shape9 = new ModelRenderer(this, 24, 32);
Shape9.addBox(0F, 0F, 0F, 3, 3, 3);
Shape9.setRotationPoint(-1.5F, -13F, -0.5F);
Shape9.setTextureSize(64, 64);
Shape9.mirror = true;
setRotation(Shape9, -0.2511622F, 0F, 0F);
Shape10 = new ModelRenderer(this, 0, 39);
Shape10.addBox(0F, 0F, 0F, 5, 1, 5);
Shape10.setRotationPoint(-2.5F, -10F, -2.5F);
Shape10.setTextureSize(64, 64);
Shape10.mirror = true;
setRotation(Shape10, -0.0698132F, 0F, 0F);
Shape7 = new ModelRenderer(this, 0, 45);
Shape7.addBox(0F, 0F, 0F, 4, 2, 4);
Shape7.setRotationPoint(-2F, -11F, -1.5F);
Shape7.setTextureSize(64, 64);
Shape7.mirror = true;
setRotation(Shape7, -0.1396263F, 0F, 0F);
Shape11 = new ModelRenderer(this, 20, 39);
Shape11.addBox(0F, 0F, 0F, 2, 3, 2);
Shape11.setRotationPoint(-1F, -15F, 1F);
Shape11.setTextureSize(64, 64);
Shape11.mirror = true;
setRotation(Shape11, -0.4363323F, 0F, 0F);
Shape12 = new ModelRenderer(this, 28, 39);
Shape12.addBox(0F, 0F, 0F, 1, 2, 1);
Shape12.setRotationPoint(-0.5F, -16F, 2.5F);
Shape12.setTextureSize(64, 64);
Shape12.mirror = true;
setRotation(Shape12, -0.715585F, 0F, 0F);
beard = new ModelRenderer(this, 32, 0);
beard.addBox(0F, 0F, 0F, 8, 5, 0);
beard.setRotationPoint(-4F, 0F, -4F);
beard.setTextureSize(64, 64);
beard.mirror = true;
setRotation(beard, 0F, 0F, 0F);
Shape13 = new ModelRenderer(this, 36, 16);
Shape13.addBox(4F, 0F, 2F, 8, 20, 6);
Shape13.setRotationPoint(-4F, 0F, -3F);
Shape13.setTextureSize(64, 64);
Shape13.mirror = true;
setRotation(Shape13, 0F, 0F, 0F);
// Makes head bits move with head
//bipedHead.addChild(Shape5);
bipedHead.addChild(beard);
//bipedHead.addChild(Shape7);
//bipedHead.addChild(Shape8);
//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);
}
*/
public class ModelWizard extends ModelBiped {
// fields
ModelRenderer Shape5;
ModelRenderer Shape8;
ModelRenderer Shape9;
ModelRenderer Shape10;
ModelRenderer Shape7;
ModelRenderer Shape11;
ModelRenderer Shape12;
ModelRenderer beard;
ModelRenderer Shape13;
public ModelWizard(){
// super(0, 0, 64, 32);
/* bipedRightLeg = new ModelRenderer(this, 32, 0); // 32 and 0 are the x and y texture offsets respectively.
* 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.mirror = true; setRotation(bipedRightLeg, 0F, 0F, 0F);
*
* bipedLeftLeg.mirror = true; bipedLeftLeg = new ModelRenderer(this, 32, 0); bipedLeftLeg.addBox(-2F, 0F, -2F,
* 4, 12, 4); bipedLeftLeg.setRotationPoint(2F, 12F, 0F); bipedLeftLeg.setTextureSize(64, 64);
* bipedLeftLeg.mirror = true; setRotation(bipedLeftLeg, 0F, 0F, 0F); bipedLeftLeg.mirror = false;
*
* bipedBody = new ModelRenderer(this, 0, 16); bipedBody.addBox(0F, 0F, 0F, 8, 12, 4);
* bipedBody.setRotationPoint(-4F, 0F, -2F); bipedBody.setTextureSize(64, 64); bipedBody.mirror = true;
* setRotation(bipedBody, 0F, 0F, 0F);
*
* bipedLeftArm.mirror = true; bipedLeftArm = new ModelRenderer(this, 48, 0); bipedLeftArm.addBox(-1F, 0F, -2F,
* 4, 12, 4); bipedLeftArm.setRotationPoint(4F, 0F, 0F); bipedLeftArm.setTextureSize(64, 64);
* bipedLeftArm.mirror = true; setRotation(bipedLeftArm, 0F, 0F, 0F); bipedLeftArm.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 =
* true; setRotation(bipedRightArm, 0F, 0F, 0F);
*
* bipedHead = new ModelRenderer(this, 0, 0); bipedHead.addBox(-4F, -8F, -4F, 8, 8, 8);
* bipedHead.setRotationPoint(0F, 0F, 0F); bipedHead.setTextureSize(64, 64); bipedHead.mirror = true;
* setRotation(bipedHead, 0F, 0F, 0F); */
Shape5 = new ModelRenderer(this, 0, 51);
Shape5.addBox(0F, 0F, 0F, 12, 1, 12);
Shape5.setRotationPoint(-6F, -7F, -6F);
Shape5.setTextureSize(64, 64);
Shape5.mirror = true;
setRotation(Shape5, 0F, 0F, 0F);
Shape8 = new ModelRenderer(this, 0, 32);
Shape8.addBox(0F, 0F, 0F, 6, 1, 6);
Shape8.setRotationPoint(-3F, -9F, -3F);
Shape8.setTextureSize(64, 64);
Shape8.mirror = true;
setRotation(Shape8, -0.0349066F, 0F, 0F);
Shape9 = new ModelRenderer(this, 24, 32);
Shape9.addBox(0F, 0F, 0F, 3, 3, 3);
Shape9.setRotationPoint(-1.5F, -13F, -0.5F);
Shape9.setTextureSize(64, 64);
Shape9.mirror = true;
setRotation(Shape9, -0.2511622F, 0F, 0F);
Shape10 = new ModelRenderer(this, 0, 39);
Shape10.addBox(0F, 0F, 0F, 5, 1, 5);
Shape10.setRotationPoint(-2.5F, -10F, -2.5F);
Shape10.setTextureSize(64, 64);
Shape10.mirror = true;
setRotation(Shape10, -0.0698132F, 0F, 0F);
Shape7 = new ModelRenderer(this, 0, 45);
Shape7.addBox(0F, 0F, 0F, 4, 2, 4);
Shape7.setRotationPoint(-2F, -11F, -1.5F);
Shape7.setTextureSize(64, 64);
Shape7.mirror = true;
setRotation(Shape7, -0.1396263F, 0F, 0F);
Shape11 = new ModelRenderer(this, 20, 39);
Shape11.addBox(0F, 0F, 0F, 2, 3, 2);
Shape11.setRotationPoint(-1F, -15F, 1F);
Shape11.setTextureSize(64, 64);
Shape11.mirror = true;
setRotation(Shape11, -0.4363323F, 0F, 0F);
Shape12 = new ModelRenderer(this, 28, 39);
Shape12.addBox(0F, 0F, 0F, 1, 2, 1);
Shape12.setRotationPoint(-0.5F, -16F, 2.5F);
Shape12.setTextureSize(64, 64);
Shape12.mirror = true;
setRotation(Shape12, -0.715585F, 0F, 0F);
beard = new ModelRenderer(this, 32, 0);
beard.addBox(0F, 0F, 0F, 8, 5, 0);
beard.setRotationPoint(-4F, 0F, -4F);
beard.setTextureSize(64, 64);
beard.mirror = true;
setRotation(beard, 0F, 0F, 0F);
Shape13 = new ModelRenderer(this, 36, 16);
Shape13.addBox(4F, 0F, 2F, 8, 20, 6);
Shape13.setRotationPoint(-4F, 0F, -3F);
Shape13.setTextureSize(64, 64);
Shape13.mirror = true;
setRotation(Shape13, 0F, 0F, 0F);
// Makes head bits move with head
// bipedHead.addChild(Shape5);
bipedHead.addChild(beard);
// bipedHead.addChild(Shape7);
// bipedHead.addChild(Shape8);
// 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,113 +1,109 @@
package electroblob.wizardry.client.model;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.model.ModelRenderer;
import net.minecraft.entity.Entity;
public class ModelWizardArmour extends ModelBiped
{
ModelRenderer Shape1;
ModelRenderer Shape2;
ModelRenderer Shape3;
ModelRenderer Shape4;
ModelRenderer Shape5;
ModelRenderer Shape6;
ModelRenderer Shape7;
ModelRenderer robe;
public ModelWizardArmour(float scale){
super(scale, 0, 64, 64);
// This is necessary to stop the head from scaling.
this.bipedHead = new ModelRenderer(this, 0, 0);
this.bipedHead.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.1f);
this.bipedHead.setRotationPoint(0.0F, 0.0F + 0, 0.0F);
Shape1 = new ModelRenderer(this, -16, 32);
Shape1.addBox(-8F, -7F, -8F, 16, 0, 16);
Shape1.setRotationPoint(0F, 0F, 0F);
Shape1.setTextureSize(64, 64);
Shape1.mirror = true;
setRotation(Shape1, 0F, 0F, 0F);
Shape2 = new ModelRenderer(this, 0, 48);
Shape2.addBox(0F, 0F, 0F, 6, 2, 6);
Shape2.setRotationPoint(-3F, -10F, -3F);
Shape2.setTextureSize(64, 64);
Shape2.mirror = true;
setRotation(Shape2, -0.1396263F, 0F, 0F);
Shape3 = new ModelRenderer(this, 0, 56);
Shape3.addBox(0F, 0F, 0F, 5, 2, 5);
Shape3.setRotationPoint(-2.5F, -11.53333F, -2F);
Shape3.setTextureSize(64, 64);
Shape3.mirror = true;
setRotation(Shape3, -0.2443461F, 0F, 0F);
Shape4 = new ModelRenderer(this, 24, 48);
Shape4.addBox(0F, 0F, 0F, 4, 2, 4);
Shape4.setRotationPoint(-2F, -13F, -1F);
Shape4.setTextureSize(64, 64);
Shape4.mirror = true;
setRotation(Shape4, -0.4014257F, 0F, 0F);
Shape5 = new ModelRenderer(this, 24, 54);
Shape5.addBox(0F, 0F, 0F, 3, 2, 3);
Shape5.setRotationPoint(-1.5F, -14F, 0F);
Shape5.setTextureSize(64, 64);
Shape5.mirror = true;
setRotation(Shape5, -0.5759587F, 0F, 0F);
Shape6 = new ModelRenderer(this, 20, 59);
Shape6.addBox(0F, 0F, 0F, 2, 2, 2);
Shape6.setRotationPoint(-1F, -14F, 0F);
Shape6.setTextureSize(64, 64);
Shape6.mirror = true;
setRotation(Shape6, 0.3316126F, 0F, 0F);
Shape7 = new ModelRenderer(this, 28, 59);
Shape7.addBox(0F, 0F, 0F, 1, 1, 3);
Shape7.setRotationPoint(-0.5F, -14.5F, 2F);
Shape7.setTextureSize(64, 64);
Shape7.mirror = true;
setRotation(Shape7, -0.5585054F, 0F, 0F);
robe = new ModelRenderer(this, 40, 42);
robe.addBox(-4F, 0F, -2F, 8, 18, 4, scale);
robe.setRotationPoint(0F, 0F, 0F);
robe.setTextureSize(64, 64);
robe.mirror = true;
setRotation(robe, 0F, 0F, 0F);
// Makes the hat rotate with the head.
bipedHead.addChild(Shape1);
bipedHead.addChild(Shape2);
bipedHead.addChild(Shape3);
bipedHead.addChild(Shape4);
bipedHead.addChild(Shape5);
bipedHead.addChild(Shape6);
bipedHead.addChild(Shape7);
// Makes the robe move with the body
bipedBody.addChild(robe);
}
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);
}
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);
}
public class ModelWizardArmour extends ModelWtfMojang {
ModelRenderer Shape1;
ModelRenderer Shape2;
ModelRenderer Shape3;
ModelRenderer Shape4;
ModelRenderer Shape5;
ModelRenderer Shape6;
ModelRenderer Shape7;
ModelRenderer robe;
public ModelWizardArmour(float scale){
super(scale, 0, 64, 64);
// This is necessary to stop the head from scaling.
this.bipedHead = new ModelRenderer(this, 0, 0);
this.bipedHead.addBox(-4.0F, -8.0F, -4.0F, 8, 8, 8, 0.1f);
this.bipedHead.setRotationPoint(0.0F, 0.0F + 0, 0.0F);
Shape1 = new ModelRenderer(this, -16, 32);
Shape1.addBox(-8F, -7F, -8F, 16, 0, 16);
Shape1.setRotationPoint(0F, 0F, 0F);
Shape1.setTextureSize(64, 64);
Shape1.mirror = true;
setRotation(Shape1, 0F, 0F, 0F);
Shape2 = new ModelRenderer(this, 0, 48);
Shape2.addBox(0F, 0F, 0F, 6, 2, 6);
Shape2.setRotationPoint(-3F, -10F, -3F);
Shape2.setTextureSize(64, 64);
Shape2.mirror = true;
setRotation(Shape2, -0.1396263F, 0F, 0F);
Shape3 = new ModelRenderer(this, 0, 56);
Shape3.addBox(0F, 0F, 0F, 5, 2, 5);
Shape3.setRotationPoint(-2.5F, -11.53333F, -2F);
Shape3.setTextureSize(64, 64);
Shape3.mirror = true;
setRotation(Shape3, -0.2443461F, 0F, 0F);
Shape4 = new ModelRenderer(this, 24, 48);
Shape4.addBox(0F, 0F, 0F, 4, 2, 4);
Shape4.setRotationPoint(-2F, -13F, -1F);
Shape4.setTextureSize(64, 64);
Shape4.mirror = true;
setRotation(Shape4, -0.4014257F, 0F, 0F);
Shape5 = new ModelRenderer(this, 24, 54);
Shape5.addBox(0F, 0F, 0F, 3, 2, 3);
Shape5.setRotationPoint(-1.5F, -14F, 0F);
Shape5.setTextureSize(64, 64);
Shape5.mirror = true;
setRotation(Shape5, -0.5759587F, 0F, 0F);
Shape6 = new ModelRenderer(this, 20, 59);
Shape6.addBox(0F, 0F, 0F, 2, 2, 2);
Shape6.setRotationPoint(-1F, -14F, 0F);
Shape6.setTextureSize(64, 64);
Shape6.mirror = true;
setRotation(Shape6, 0.3316126F, 0F, 0F);
Shape7 = new ModelRenderer(this, 28, 59);
Shape7.addBox(0F, 0F, 0F, 1, 1, 3);
Shape7.setRotationPoint(-0.5F, -14.5F, 2F);
Shape7.setTextureSize(64, 64);
Shape7.mirror = true;
setRotation(Shape7, -0.5585054F, 0F, 0F);
// The robe is now the body
bipedBody = new ModelRenderer(this, 40, 42);
bipedBody.addBox(-4F, 0F, -2F, 8, 18, 4, scale);
bipedBody.setRotationPoint(0F, 0F, 0F);
bipedBody.setTextureSize(64, 64);
bipedBody.mirror = true;
setRotation(bipedBody, 0F, 0F, 0F);
// Makes the hat rotate with the head.
bipedHead.addChild(Shape1);
bipedHead.addChild(Shape2);
bipedHead.addChild(Shape3);
bipedHead.addChild(Shape4);
bipedHead.addChild(Shape5);
bipedHead.addChild(Shape6);
bipedHead.addChild(Shape7);
// Makes the robe move with the body
// bipedBody.addChild(robe);
}
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);
}
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);
}
}
@@ -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);
}
}
@@ -0,0 +1,198 @@
package electroblob.wizardry.client.model;
import electroblob.wizardry.registry.WizardryBlocks;
import electroblob.wizardry.registry.WizardryItems;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.NonNullList;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.oredict.OreDictionary;
/**
* Class responsible for registering all of wizardry's item (and itemblock) models.
*
* @author Electroblob
* @since Wizardry 2.1
*/
@SideOnly(Side.CLIENT)
@Mod.EventBusSubscriber(Side.CLIENT)
public final class WizardryItemModels {
@SubscribeEvent
public static void register(ModelRegistryEvent event){
// ItemBlocks
registerItemModel(Item.getItemFromBlock(WizardryBlocks.arcane_workbench));
registerItemModel(Item.getItemFromBlock(WizardryBlocks.crystal_ore));
registerItemModel(Item.getItemFromBlock(WizardryBlocks.crystal_flower));
registerItemModel(Item.getItemFromBlock(WizardryBlocks.transportation_stone));
registerItemModel(Item.getItemFromBlock(WizardryBlocks.crystal_block));
// Items
registerItemModel(WizardryItems.magic_crystal);
registerItemModel(WizardryItems.magic_wand);
registerItemModel(WizardryItems.apprentice_wand);
registerItemModel(WizardryItems.advanced_wand);
registerItemModel(WizardryItems.master_wand);
registerItemModel(WizardryItems.spell_book);
// Wildcard registered for wizard trades.
registerItemModel(WizardryItems.spell_book, OreDictionary.WILDCARD_VALUE, "normal");
registerItemModel(WizardryItems.arcane_tome);
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.apprentice_ice_wand);
registerItemModel(WizardryItems.apprentice_lightning_wand);
registerItemModel(WizardryItems.apprentice_necromancy_wand);
registerItemModel(WizardryItems.apprentice_earth_wand);
registerItemModel(WizardryItems.apprentice_sorcery_wand);
registerItemModel(WizardryItems.apprentice_healing_wand);
registerItemModel(WizardryItems.advanced_fire_wand);
registerItemModel(WizardryItems.advanced_ice_wand);
registerItemModel(WizardryItems.advanced_lightning_wand);
registerItemModel(WizardryItems.advanced_necromancy_wand);
registerItemModel(WizardryItems.advanced_earth_wand);
registerItemModel(WizardryItems.advanced_sorcery_wand);
registerItemModel(WizardryItems.advanced_healing_wand);
registerItemModel(WizardryItems.master_fire_wand);
registerItemModel(WizardryItems.master_ice_wand);
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.spectral_sword);
registerItemModel(WizardryItems.spectral_pickaxe);
registerItemModel(WizardryItems.spectral_bow);
registerItemModel(WizardryItems.mana_flask);
registerItemModel(WizardryItems.storage_upgrade);
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.frost_axe);
registerItemModel(WizardryItems.firebomb);
registerItemModel(WizardryItems.poison_bomb);
registerItemModel(WizardryItems.blank_scroll);
registerItemModel(WizardryItems.scroll);
registerItemModel(WizardryItems.armour_upgrade);
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.wizard_robe_fire);
registerItemModel(WizardryItems.wizard_leggings_fire);
registerItemModel(WizardryItems.wizard_boots_fire);
registerItemModel(WizardryItems.wizard_hat_ice);
registerItemModel(WizardryItems.wizard_robe_ice);
registerItemModel(WizardryItems.wizard_leggings_ice);
registerItemModel(WizardryItems.wizard_boots_ice);
registerItemModel(WizardryItems.wizard_hat_lightning);
registerItemModel(WizardryItems.wizard_robe_lightning);
registerItemModel(WizardryItems.wizard_leggings_lightning);
registerItemModel(WizardryItems.wizard_boots_lightning);
registerItemModel(WizardryItems.wizard_hat_necromancy);
registerItemModel(WizardryItems.wizard_robe_necromancy);
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
/**
* 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 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
* <b>must</b> allow null to be passed in for the creative tab parameter in the aforementioned method, or a
* {@link NullPointerException} will result.
*/
private static void registerItemModel(Item item){
if(item.getHasSubtypes()){
NonNullList<ItemStack> items = NonNullList.create();
item.getSubItems(item.getCreativeTab(), items); // Client-only method, but we're client-side so this is OK.
for(ItemStack stack : items){
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!
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 values which
* aren't displayed in the creative menu, for example the wildcard spell book used in wizard trades.
*/
private static void registerItemModel(Item item, int metadata, String variant){
ModelLoader.setCustomModelResourceLocation(item, metadata,
new ModelResourceLocation(item.getRegistryName(), variant));
}
}
@@ -1,139 +0,0 @@
package electroblob.wizardry.client.particle;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.Wizardry;
import net.minecraft.client.particle.EffectRenderer;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
@SideOnly(Side.CLIENT)
public class EntityBlizzardFX extends EntitySnowFX
{
/** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would
* be any, but I may as well.) */
public static final String NAME = Wizardry.MODID + "blizzard";
private boolean gravity = false;
private double angle;
private double radius;
private double speed;
public EntityBlizzardFX(World world, float red, float green, float blue, int maxAge, double originX, double originZ, double radius, double yPos)
{
super(world, 0, 0, 0, 0, 0, 0, maxAge);
this.angle = this.rand.nextDouble() * Math.PI * 2;
double x = originX - Math.cos(angle)*radius;
double z = originZ + radius*Math.sin(angle);
this.radius = radius;
this.setPosition(x, yPos, z);
//this.particleScale *= 0.75F;
this.noClip = true;
particleRed = red;
particleGreen = green;
particleBlue = blue;
if(rand.nextBoolean()){
speed = rand.nextDouble()*2 + 1;
}else{
speed = rand.nextDouble()*-2 - 1;
}
}
public EntityBlizzardFX(World world, double x, double y, double z, double vx, double vy, double vz, float red, float green, float blue)
{
super(world, x, y, z, vx, vy, vz);
//this.particleScale *= 0.75F;
this.particleMaxAge = 48 + this.rand.nextInt(12);
this.noClip = true;
particleRed = red;
particleGreen = green;
particleBlue = blue;
}
public void setColour(int par1)
{
float f = (float)((par1 & 16711680) >> 16) / 255.0F;
float f1 = (float)((par1 & 65280) >> 8) / 255.0F;
float f2 = (float)((par1 & 255) >> 0) / 255.0F;
float f3 = 1.0F;
this.setRBGColorF(f * f3, f1 * f3, f2 * f3);
}
/**
* returns the bounding box for this entity
*/
public AxisAlignedBB getBoundingBox()
{
return null;
}
/**
* Returns true if this entity should push and be pushed by other entities when colliding.
*/
public boolean canBePushed()
{
return false;
}
public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7)
{
if (this.particleAge < this.particleMaxAge / 3 || (this.particleAge + this.particleMaxAge) / 3 % 2 == 0)
{
super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7);
}
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if (this.particleAge++ >= this.particleMaxAge)
{
this.setDead();
}
// This is in radians per tick...
double omega = (Math.PI*2)/20 - speed/(20*radius);
if(speed < 0){
omega = -(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.moveEntity(motionX, motionY, motionZ);
if(this.gravity){
this.motionY -= 0.05d;
}
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 par1)
{
return 15728880;
}
@Override
public float getBrightness(float par1)
{
return 1.0F;
}
*/
}
@@ -1,93 +0,0 @@
package electroblob.wizardry.client.particle;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.Wizardry;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.world.World;
@SideOnly(Side.CLIENT)
public class EntityDarkMagicFX extends EntityFX
{
/** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would
* be any, but I may as well.) */
public static final String NAME = Wizardry.MODID + "darkmagic";
/** Base spell texture index */
private int baseSpellTextureIndex = 128;
public EntityDarkMagicFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float r, float g, float b)
{
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;
this.particleMaxAge = (int)(8.0D / (Math.random() * 0.8D + 0.2D));
this.noClip = true;
}
public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7)
{
float f6 = ((float)this.particleAge + par2) / (float)this.particleMaxAge * 32.0F;
if (f6 < 0.0F)
{
f6 = 0.0F;
}
if (f6 > 1.0F)
{
f6 = 1.0F;
}
super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7);
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if (this.particleAge++ >= this.particleMaxAge)
{
this.setDead();
}
this.setParticleTextureIndex(this.baseSpellTextureIndex + (7 - this.particleAge * 8 / this.particleMaxAge));
this.motionY += 0.004D;
this.moveEntity(this.motionX, this.motionY, this.motionZ);
/*
if (this.posY == this.prevPosY)
{
this.motionX *= 1.1D;
this.motionZ *= 1.1D;
}
*/
this.motionX *= 0.9599999785423279D;
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;
}
}
@@ -1,67 +0,0 @@
package electroblob.wizardry.client.particle;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.Wizardry;
import net.minecraft.block.material.Material;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
@SideOnly(Side.CLIENT)
public class EntityDustFX extends EntityFX
{
/** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would
* be any, but I may as well.) */
public static final String NAME = Wizardry.MODID + "dust";
private final boolean shaded;
public EntityDustFX(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;
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
//this.moveEntity(this.motionX, this.motionY, this.motionZ);
if (this.particleMaxAge-- <= 0)
{
this.setDead();
}
}
@Override
public int getBrightnessForRender(float par1)
{
return shaded ? super.getBrightnessForRender(par1) : 15728880;
}
@Override
public float getBrightness(float par1)
{
return shaded ? super.getBrightness(par1) : 1.0F;
}
}
@@ -1,199 +0,0 @@
package electroblob.wizardry.client.particle;
import java.lang.reflect.Field;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.Wizardry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
@SideOnly(Side.CLIENT)
public class EntityIceFX extends EntityFX
{
/** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would
* be any, but I may as well.) */
public static final String NAME = Wizardry.MODID + "ice";
private static final ResourceLocation iceTextures = new ResourceLocation("wizardry:textures/particle/ice_particles.png");
public EntityIceFX(World world, double x, double y, double z, double vx, double vy, double vz)
{
super(world, x, y, z, vx, vy, vz);
this.particleRed = 1.0F;
this.particleGreen = 1.0F;
this.particleBlue = 1.0F;
this.setParticleTextureIndex(rand.nextInt(8));
this.setSize(0.02F, 0.02F);
this.particleScale *= 0.75f;
this.motionX = vx;
this.motionY = vy;
this.motionZ = vz;
this.particleMaxAge = 40 + rand.nextInt(10);
this.noClip = true;
}
public EntityIceFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, int maxAge){
this(par1World, par2, par4, par6, par8, par10, par12);
this.particleMaxAge = maxAge;
this.noClip = true;
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate(){
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if (this.particleAge++ >= this.particleMaxAge)
{
this.setDead();
}
this.moveEntity(this.motionX, this.motionY, this.motionZ);
this.motionX *= 0.9800000190734863D;
this.motionY *= 0.9800000190734863D;
this.motionZ *= 0.9800000190734863D;
// Gravity
this.motionY -= 0.05d;
}
/* There are 4 layers of particles, specified as 0-3 by the method below.
* - Layer 0 causes the normal particles.png to be bound to the render engine for normal particles.
* - Layer 1 causes the block textures to be bound to the render engine for digging fx and falling fx.
* - Layer 2 causes the item textures to be bound to the render engine for tool breaking fx, snowballpoofs, slime particles, etc.
* - Layer 3 is not used in vanilla minecraft and was presumably added by forge for exactly this reason.
* This means no texture is bound by vanilla minecraft, meaning you are free to do as you wish without possibly
* overwriting vanilla particles. Mod particles won't be overwritten anyway since they bind their own textures.
* It is of course important to bind the texture every time you render a custom particle, but I don't see how
* you could do it any other way, since you don't have access to EffectRenderer.
*/
@Override
public int getFXLayer() {
// This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer.
return 3;
}
@Override
public void setParticleTextureIndex(int par1)
{
this.particleTextureIndexX = par1 % 4;
this.particleTextureIndexY = par1 / 4;
}
// Overwitten from entityfx to bind the new texture.
@Override
public void renderParticle(Tessellator tessellator, float partialTicks, float par3, float par4, float par5, float par6, float par7)
{
// Resets the tessellator and binds the new texture. Used to check if tessellator is drawing, but that field
// is no longer visible. If this results in an IllegalStateException (tessellator not drawing), look into this.
// Perhaps I could use reflection (ooooooh) to access it? Like this:
/*
Field f = null;
boolean isDrawing = false;
try {
f = tessellator.getClass().getDeclaredField("isDrawing");
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
if(f != null){
f.setAccessible(true);
try {
isDrawing = (Boolean)f.get(tessellator);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
if(isDrawing)*/
//tessellator.draw();
GL11.glPushMatrix();
// This stuff does the shading. The parameter does nothing apparently.
int j = this.getBrightnessForRender(0);
int k = j % 65536;
int l = j / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F);
RenderHelper.disableStandardItemLighting();
Minecraft.getMinecraft().renderEngine.bindTexture(iceTextures);
tessellator.startDrawingQuads();
float f6 = (float)this.particleTextureIndexX / 4.0F;
float f7 = f6 + 0.0624375F*4;
float f8 = (float)this.particleTextureIndexY / 4.0F;
float f9 = f8 + 0.0624375F*4;
float f10 = 0.1F * this.particleScale;
if (this.particleIcon != null)
{
f6 = this.particleIcon.getMinU();
f7 = this.particleIcon.getMaxU();
f8 = this.particleIcon.getMinV();
f9 = this.particleIcon.getMaxV();
}
// Fix which gets proper values for interpPos so the particles don't appear to move.
Entity player = Minecraft.getMinecraft().thePlayer;
this.interpPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)partialTicks;
this.interpPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)partialTicks;
this.interpPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)partialTicks;
float f11 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX);
float f12 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY);
float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ);
float f14 = 1.0F;
tessellator.setColorRGBA_F(this.particleRed * f14, this.particleGreen * f14, this.particleBlue * f14, this.particleAlpha);
tessellator.addVertexWithUV((double)(f11 - par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 - par5 * f10 - par7 * f10), (double)f7, (double)f9);
tessellator.addVertexWithUV((double)(f11 - par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 - par5 * f10 + par7 * f10), (double)f7, (double)f8);
tessellator.addVertexWithUV((double)(f11 + par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 + par5 * f10 + par7 * f10), (double)f6, (double)f8);
tessellator.addVertexWithUV((double)(f11 + par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 + par5 * f10 - par7 * f10), (double)f6, (double)f9);
tessellator.draw();
GL11.glPopMatrix();
// Re-binds the normal particles so that the mod texture isn't on all of them
//Minecraft.getMinecraft().renderEngine.bindTexture(new ResourceLocation("textures/particle/particles.png"));
//tessellator.startDrawingQuads();
}
public int getBrightnessForRender(float par1)
{
return 15728880;
}
/**
* Gets how bright this entity is.
*/
public float getBrightness(float par1)
{
return 1.0F;
}
}
@@ -1,180 +0,0 @@
package electroblob.wizardry.client.particle;
import java.lang.reflect.Field;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.Wizardry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
@SideOnly(Side.CLIENT)
public class EntityLeafFX extends EntityFX
{
/** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would
* be any, but I may as well.) */
public static final String NAME = Wizardry.MODID + "leaf";
private static final ResourceLocation leafTextures = new ResourceLocation("wizardry:textures/particle/leaf_particles.png");
public EntityLeafFX(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(rand.nextInt(16));
this.setSize(0.02F, 0.02F);
this.particleScale *= 1.4f;
this.motionX = par8;
this.motionY = par10;
this.motionZ = par12;
this.particleMaxAge = 40 + rand.nextInt(10);
}
public EntityLeafFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, int maxAge){
this(par1World, par2, par4, par6, par8, par10, par12);
this.particleMaxAge = maxAge;
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
this.moveEntity(this.motionX, this.motionY, this.motionZ);
if (this.particleMaxAge-- <= 0)
{
this.setDead();
}
}
/* There are 4 layers of particles, specified as 0-3 by the method below.
* - Layer 0 causes the normal particles.png to be bound to the render engine for normal particles.
* - Layer 1 causes the block textures to be bound to the render engine for digging fx and falling fx.
* - Layer 2 causes the item textures to be bound to the render engine for tool breaking fx, snowballpoofs, slime particles, etc.
* - Layer 3 is not used in vanilla minecraft and was presumably added by forge for exactly this reason.
* This means no texture is bound by vanilla minecraft, meaning you are free to do as you wish without possibly
* overwriting vanilla particles. Mod particles won't be overwritten anyway since they bind their own textures.
* It is of course important to bind the texture every time you render a custom particle, but I don't see how
* you could do it any other way, since you don't have access to EffectRenderer.
*/
@Override
public int getFXLayer() {
// This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer.
return 3;
}
/**
* Public method to set private field particleTextureIndex.
*/
public void setParticleTextureIndex(int par1)
{
this.particleTextureIndexX = par1 % 4;
this.particleTextureIndexY = par1 / 4;
}
// Overwitten from entityfx to bind the new texture.
@Override
public void renderParticle(Tessellator tessellator, float partialTicks, float par3, float par4, float par5, float par6, float par7)
{
// Resets the tessellator and binds the new texture. Used to check if tessellator is drawing, but that field
// is no longer visible. If this results in an IllegalStateException (tessellator not drawing), look into this.
// Perhaps I could use reflection (ooooooh) to access it? Like this:
/*
Field f = null;
boolean isDrawing = false;
try {
f = tessellator.getClass().getDeclaredField("isDrawing");
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
if(f != null){
f.setAccessible(true);
try {
isDrawing = (Boolean)f.get(tessellator);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
if(isDrawing)*/
//tessellator.draw();
GL11.glPushMatrix();
// This stuff does the shading. The parameter does nothing apparently.
int j = this.getBrightnessForRender(0);
int k = j % 65536;
int l = j / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F);
RenderHelper.disableStandardItemLighting();
Minecraft.getMinecraft().renderEngine.bindTexture(leafTextures);
tessellator.startDrawingQuads();
float f6 = (float)this.particleTextureIndexX / 4.0F;
float f7 = f6 + 0.0624375F*4;
float f8 = (float)this.particleTextureIndexY / 4.0F;
float f9 = f8 + 0.0624375F*4;
float f10 = 0.1F * this.particleScale;
if (this.particleIcon != null)
{
f6 = this.particleIcon.getMinU();
f7 = this.particleIcon.getMaxU();
f8 = this.particleIcon.getMinV();
f9 = this.particleIcon.getMaxV();
}
// Fix which gets proper values for interpPos so the particles don't appear to move.
Entity player = Minecraft.getMinecraft().thePlayer;
this.interpPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)partialTicks;
this.interpPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)partialTicks;
this.interpPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)partialTicks;
float f11 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX);
float f12 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY);
float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ);
float f14 = 1.0F;
tessellator.setColorRGBA_F(this.particleRed * f14, this.particleGreen * f14, this.particleBlue * f14, this.particleAlpha);
tessellator.addVertexWithUV((double)(f11 - par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 - par5 * f10 - par7 * f10), (double)f7, (double)f9);
tessellator.addVertexWithUV((double)(f11 - par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 - par5 * f10 + par7 * f10), (double)f7, (double)f8);
tessellator.addVertexWithUV((double)(f11 + par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 + par5 * f10 + par7 * f10), (double)f6, (double)f8);
tessellator.addVertexWithUV((double)(f11 + par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 + par5 * f10 - par7 * f10), (double)f6, (double)f9);
tessellator.draw();
GL11.glPopMatrix();
// Re-binds the normal particles so that the mod texture isn't on all of them
//Minecraft.getMinecraft().renderEngine.bindTexture(new ResourceLocation("textures/particle/particles.png"));
//tessellator.startDrawingQuads();
}
}
@@ -1,52 +0,0 @@
package electroblob.wizardry.client.particle;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.Wizardry;
import net.minecraft.block.material.Material;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
@SideOnly(Side.CLIENT)
public class EntityMagicBubbleFX extends EntityFX
{
/** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would
* be any, but I may as well.) */
public static final String NAME = Wizardry.MODID + "magicbubble";
public EntityMagicBubbleFX(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));
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
this.motionY += 0.002D;
this.moveEntity(this.motionX, this.motionY, this.motionZ);
this.motionX *= 0.8500000238418579D;
this.motionY *= 0.8500000238418579D;
this.motionZ *= 0.8500000238418579D;
if (this.particleMaxAge-- <= 0)
{
this.setDead();
}
}
}
@@ -1,108 +0,0 @@
package electroblob.wizardry.client.particle;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.Wizardry;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.world.World;
@SideOnly(Side.CLIENT)
public class EntityMagicFireFX extends EntityFX
{
/** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would
* be any, but I may as well.) */
public static final String NAME = Wizardry.MODID + "magicfire";
/** the scale of the flame FX */
private float flameScale;
public EntityMagicFireFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, int maxAge, float scale)
{
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;
double d6 = par2 + (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F);
d6 = par4 + (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F);
d6 = par6 + (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F);
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;
}
this.noClip = true;
this.setParticleTextureIndex(48);
}
public void renderParticle(Tessellator par1Tessellator, float par2, float par3, float par4, float par5, float par6, float par7)
{
float f6 = ((float)this.particleAge + par2) / (float)this.particleMaxAge;
this.particleScale = this.flameScale * (1.0F - f6 * f6 * 0.5F);
super.renderParticle(par1Tessellator, par2, par3, par4, par5, par6, par7);
}
public int getBrightnessForRender(float par1)
{
float f1 = ((float)this.particleAge + par1) / (float)this.particleMaxAge;
if (f1 < 0.0F)
{
f1 = 0.0F;
}
if (f1 > 1.0F)
{
f1 = 1.0F;
}
int i = super.getBrightnessForRender(par1);
int j = i & 255;
int k = i >> 16 & 255;
j += (int)(f1 * 15.0F * 16.0F);
if (j > 240)
{
j = 240;
}
//return j | k << 16;
return 256;
}
/**
* Gets how bright this entity is.
*/
public float getBrightness(float par1)
{
return 1.0f;
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if (this.particleAge++ >= this.particleMaxAge)
{
this.setDead();
}
this.moveEntity(this.motionX, this.motionY, this.motionZ);
this.motionX *= 0.9599999785423279D;
this.motionY *= 0.9599999785423279D;
this.motionZ *= 0.9599999785423279D;
if (this.onGround)
{
this.motionX *= 0.699999988079071D;
this.motionZ *= 0.699999988079071D;
}
}
}
@@ -1,181 +0,0 @@
package electroblob.wizardry.client.particle;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.spell.Clairvoyance;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.Entity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
@SideOnly(Side.CLIENT)
public class EntityPathFX extends EntityFX
{
/** The name used to identify this particle, without gravity. Uses the mod id to avoid any possible conflicts (Not that there would
* be any, but I may as well.) */
public static final String NAME = Wizardry.MODID + "path";
private static final ResourceLocation pathTextures = new ResourceLocation("wizardry:textures/particle/path_particles.png");
private final double originX, originY, originZ;
public EntityPathFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float red, float green, float blue, int maxAge)
{
super(par1World, par2, par4, par6);
this.motionX = par8;
this.motionY = par10;
this.motionZ = par12;
// Set to a constant to remove the randomness from EntityFX.
this.particleScale = 1.25F;
this.particleMaxAge = maxAge;
this.noClip = true;
particleRed = red;
particleGreen = green;
particleBlue = blue;
this.originX = par2;
this.originY = par4;
this.originZ = par6;
}
public EntityPathFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float red, float green, float blue)
{
super(par1World, par2, par4, par6);
this.motionX = par8;
this.motionY = par10;
this.motionZ = par12;
// Set to a constant to remove the randomness from EntityFX.
this.particleScale = 1.25F;
this.particleMaxAge = 48 + this.rand.nextInt(12);
this.noClip = true;
particleRed = red;
particleGreen = green;
particleBlue = blue;
this.originX = par2;
this.originY = par4;
this.originZ = par6;
}
/**
* returns the bounding box for this entity
*/
public AxisAlignedBB getBoundingBox()
{
return null;
}
/**
* Returns true if this entity should push and be pushed by other entities when colliding.
*/
public boolean canBePushed()
{
return false;
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if (this.particleAge++ >= this.particleMaxAge)
{
this.setDead();
}
this.moveEntity(this.motionX, this.motionY, this.motionZ);
if (this.particleAge > this.particleMaxAge / 2)
{
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);
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
}
}
/* There are 4 layers of particles, specified as 0-3 by the method below.
* - Layer 0 causes the normal particles.png to be bound to the render engine for normal particles.
* - Layer 1 causes the block textures to be bound to the render engine for digging fx and falling fx.
* - Layer 2 causes the item textures to be bound to the render engine for tool breaking fx, snowballpoofs, slime particles, etc.
* - Layer 3 is not used in vanilla minecraft and was presumably added by forge for exactly this reason.
* This means no texture is bound by vanilla minecraft, meaning you are free to do as you wish without possibly
* overwriting vanilla particles. Mod particles won't be overwritten anyway since they bind their own textures.
* It is of course important to bind the texture every time you render a custom particle, but I don't see how
* you could do it any other way, since you don't have access to EffectRenderer.
*/
@Override
public int getFXLayer() {
// This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer.
return 3;
}
@Override
public void renderParticle(Tessellator tessellator, float partialTicks, float par3, float par4, float par5, float par6, float par7){
GL11.glPushMatrix();
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
RenderHelper.disableStandardItemLighting();
Minecraft.getMinecraft().renderEngine.bindTexture(pathTextures);
tessellator.startDrawingQuads();
float f10 = 0.1F * this.particleScale;
// Fix which gets proper values for interpPos so the particles don't appear to move.
Entity player = Minecraft.getMinecraft().thePlayer;
this.interpPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)partialTicks;
this.interpPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)partialTicks;
this.interpPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)partialTicks;
float f11 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX);
float f12 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY);
float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ);
float f14 = 1.0F;
tessellator.setColorRGBA_F(this.particleRed * f14, this.particleGreen * f14, this.particleBlue * f14, this.particleAlpha);
tessellator.addVertexWithUV((double)(f11 - par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 - par5 * f10 - par7 * f10), 1, 1);
tessellator.addVertexWithUV((double)(f11 - par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 - par5 * f10 + par7 * f10), 1, 0);
tessellator.addVertexWithUV((double)(f11 + par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 + par5 * f10 + par7 * f10), 0, 0);
tessellator.addVertexWithUV((double)(f11 + par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 + par5 * f10 - par7 * f10), 0, 1);
tessellator.draw();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_BLEND);
GL11.glPopMatrix();
}
@Override
public int getBrightnessForRender(float par1)
{
return 15728880;
}
@Override
public float getBrightness(float par1)
{
return 1.0F;
}
}
@@ -1,131 +0,0 @@
package electroblob.wizardry.client.particle;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.Wizardry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
@SideOnly(Side.CLIENT)
public class EntitySnowFX extends EntityFX
{
/** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would
* be any, but I may as well.) */
public static final String NAME = Wizardry.MODID + "snow";
private static final ResourceLocation snowTextures = new ResourceLocation("wizardry:textures/particle/snow_particles.png");
public EntitySnowFX(World world, double x, double y, double z, double velX, double velY, double velZ)
{
super(world, x, y, z, velX, velY, velZ);
this.particleRed = 1.0F;
this.particleGreen = 1.0F;
this.particleBlue = 1.0F;
this.setParticleTextureIndex(rand.nextInt(8));
this.setSize(0.02F, 0.02F);
this.particleScale *= 0.6f;
this.motionX = velX;
this.motionY = velY;
this.motionZ = velZ;
this.particleMaxAge = 40 + rand.nextInt(10);
}
public EntitySnowFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, int maxAge){
this(par1World, par2, par4, par6, par8, par10, par12);
this.particleMaxAge = maxAge;
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
this.moveEntity(this.motionX, this.motionY, this.motionZ);
if (this.particleMaxAge-- <= 0)
{
this.setDead();
}
}
/**
* Public method to set private field particleTextureIndex.
*/
public void setParticleTextureIndex(int par1)
{
this.particleTextureIndexX = par1 % 4;
this.particleTextureIndexY = par1 / 4;
}
@Override
public int getFXLayer() {
// This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer.
return 3;
}
// Overwitten from entityfx to bind the new texture.
@Override
public void renderParticle(Tessellator tessellator, float partialTicks, float par3, float par4, float par5, float par6, float par7)
{
GL11.glPushMatrix();
// This stuff does the shading. The parameter does nothing apparently.
int j = this.getBrightnessForRender(0);
int k = j % 65536;
int l = j / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)k / 1.0F, (float)l / 1.0F);
RenderHelper.disableStandardItemLighting();
Minecraft.getMinecraft().renderEngine.bindTexture(snowTextures);
tessellator.startDrawingQuads();
float f6 = (float)this.particleTextureIndexX / 4.0F;
float f7 = f6 + 0.0624375F*4;
float f8 = (float)this.particleTextureIndexY / 4.0F;
float f9 = f8 + 0.0624375F*4;
float f10 = 0.1F * this.particleScale;
if (this.particleIcon != null)
{
f6 = this.particleIcon.getMinU();
f7 = this.particleIcon.getMaxU();
f8 = this.particleIcon.getMinV();
f9 = this.particleIcon.getMaxV();
}
// Fix which gets proper values for interpPos so the particles don't appear to move.
Entity player = Minecraft.getMinecraft().thePlayer;
this.interpPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)partialTicks;
this.interpPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)partialTicks;
this.interpPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)partialTicks;
float f11 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX);
float f12 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY);
float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ);
float f14 = 1.0F;
tessellator.setColorRGBA_F(this.particleRed * f14, this.particleGreen * f14, this.particleBlue * f14, this.particleAlpha);
tessellator.addVertexWithUV((double)(f11 - par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 - par5 * f10 - par7 * f10), (double)f7, (double)f9);
tessellator.addVertexWithUV((double)(f11 - par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 - par5 * f10 + par7 * f10), (double)f7, (double)f8);
tessellator.addVertexWithUV((double)(f11 + par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 + par5 * f10 + par7 * f10), (double)f6, (double)f8);
tessellator.addVertexWithUV((double)(f11 + par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 + par5 * f10 - par7 * f10), (double)f6, (double)f9);
tessellator.draw();
GL11.glPopMatrix();
}
}
@@ -1,117 +0,0 @@
package electroblob.wizardry.client.particle;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.Wizardry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
@SideOnly(Side.CLIENT)
public class EntitySparkFX extends EntityFX
{
/** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would
* be any, but I may as well.) */
public static final String NAME = Wizardry.MODID + "spark";
private static final ResourceLocation sparkTextures = new ResourceLocation("wizardry:textures/particle/lightning_particles.png");
public EntitySparkFX(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(rand.nextInt(8));
this.setSize(0.02F, 0.02F);
this.particleScale *= 1.4f;
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 = 3;
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if(this.particleAge++ >= this.particleMaxAge)
{
this.setDead();
}
}
/**
* Public method to set private field particleTextureIndex.
*/
public void setParticleTextureIndex(int par1)
{
this.particleTextureIndexY = par1;
}
@Override
public int getFXLayer() {
// This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer.
return 3;
}
// Overwitten from entityfx to bind the new texture.
@Override
public void renderParticle(Tessellator par1Tessellator, float partialTicks, float par3, float par4, float par5, float par6, float par7)
{
GL11.glPushMatrix();
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
RenderHelper.disableStandardItemLighting();
Minecraft.getMinecraft().renderEngine.bindTexture(sparkTextures);
par1Tessellator.startDrawingQuads();
// Particles are now animated using a strip of 4 from left to right.
float f6 = (float)this.particleAge / 4.0F;
float f7 = f6 + 0.0624375F*4;
float f8 = (float)this.particleTextureIndexY / 8.0f;
float f9 = f8 + 0.0624375F*2;
float f10 = 0.1F * this.particleScale;
// Fix which gets proper values for interpPos so the particles don't appear to move.
Entity player = Minecraft.getMinecraft().thePlayer;
this.interpPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)partialTicks;
this.interpPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)partialTicks;
this.interpPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)partialTicks;
float f11 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX);
float f12 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY);
float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ);
float f14 = 1.0F;
par1Tessellator.setColorRGBA_F(this.particleRed * f14, this.particleGreen * f14, this.particleBlue * f14, this.particleAlpha);
par1Tessellator.addVertexWithUV((double)(f11 - par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 - par5 * f10 - par7 * f10), (double)f7, (double)f9);
par1Tessellator.addVertexWithUV((double)(f11 - par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 - par5 * f10 + par7 * f10), (double)f7, (double)f8);
par1Tessellator.addVertexWithUV((double)(f11 + par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 + par5 * f10 + par7 * f10), (double)f6, (double)f8);
par1Tessellator.addVertexWithUV((double)(f11 + par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 + par5 * f10 - par7 * f10), (double)f6, (double)f9);
par1Tessellator.draw();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_BLEND);
GL11.glPopMatrix();
}
}
@@ -1,203 +0,0 @@
package electroblob.wizardry.client.particle;
import org.lwjgl.opengl.GL11;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.Wizardry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.EffectRenderer;
import net.minecraft.client.particle.EntityFX;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.Entity;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
@SideOnly(Side.CLIENT)
public class EntitySparkleFX extends EntityFX
{
/** The name used to identify this particle, without gravity. Uses the mod id to avoid any possible conflicts (Not that there would
* be any, but I may as well.) */
public static final String NAME = Wizardry.MODID + "sparkle";
/** The name used to identify this particle, with gravity. Uses the mod id to avoid any possible conflicts (Not that there would
* be any, but I may as well.) */
public static final String NAME_GRAVITY = Wizardry.MODID + "sparkleGravity";
private static final ResourceLocation sparkleTextures = new ResourceLocation("wizardry:textures/particle/sparkle_particles.png");
private boolean gravity = false;
public EntitySparkleFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float red, float green, float blue, int maxAge)
{
super(par1World, par2, par4, par6);
this.motionX = par8;
this.motionY = par10;
this.motionZ = par12;
this.particleScale *= 0.75F;
this.particleMaxAge = maxAge;
this.noClip = true;
particleRed = red;
particleGreen = green;
particleBlue = blue;
}
public EntitySparkleFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float red, float green, float blue)
{
super(par1World, par2, par4, par6);
this.motionX = par8;
this.motionY = par10;
this.motionZ = par12;
this.particleScale *= 0.75F;
this.particleMaxAge = 48 + this.rand.nextInt(12);
this.noClip = true;
particleRed = red;
particleGreen = green;
particleBlue = blue;
}
public EntitySparkleFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float red, float green, float blue, boolean doGravity){
this(par1World, par2, par4, par6, par8, par10, par12, red, green, blue);
this.gravity = doGravity;
}
public EntitySparkleFX(World par1World, double par2, double par4, double par6, double par8, double par10, double par12, float red, float green, float blue, int maxAge, boolean doGravity){
this(par1World, par2, par4, par6, par8, par10, par12, red, green, blue, maxAge);
this.gravity = doGravity;
}
/**
* returns the bounding box for this entity
*/
public AxisAlignedBB getBoundingBox()
{
return null;
}
/**
* Returns true if this entity should push and be pushed by other entities when colliding.
*/
public boolean canBePushed()
{
return false;
}
@Override
public void setParticleTextureIndex(int par1)
{
this.particleTextureIndexX = par1 % 4;
this.particleTextureIndexY = par1 / 4;
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate()
{
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if (this.particleAge++ >= this.particleMaxAge)
{
this.setDead();
}
this.moveEntity(this.motionX, this.motionY, this.motionZ);
this.motionX *= 0.9800000190734863D;
this.motionY *= 0.9800000190734863D;
this.motionZ *= 0.9800000190734863D;
if(this.gravity){
this.motionY -= 0.05d;
}
if (this.particleAge > this.particleMaxAge / 2)
{
this.setAlphaF(1.0F - ((float)this.particleAge - (float)(this.particleMaxAge / 2)) / (float)this.particleMaxAge);
}
this.setParticleTextureIndex((this.particleAge * 11)/this.particleMaxAge);
}
/* There are 4 layers of particles, specified as 0-3 by the method below.
* - Layer 0 causes the normal particles.png to be bound to the render engine for normal particles.
* - Layer 1 causes the block textures to be bound to the render engine for digging fx and falling fx.
* - Layer 2 causes the item textures to be bound to the render engine for tool breaking fx, snowballpoofs, slime particles, etc.
* - Layer 3 is not used in vanilla minecraft and was presumably added by forge for exactly this reason.
* This means no texture is bound by vanilla minecraft, meaning you are free to do as you wish without possibly
* overwriting vanilla particles. Mod particles won't be overwritten anyway since they bind their own textures.
* It is of course important to bind the texture every time you render a custom particle, but I don't see how
* you could do it any other way, since you don't have access to EffectRenderer.
*/
@Override
public int getFXLayer() {
// This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer.
return 3;
}
@Override
public void renderParticle(Tessellator tessellator, float partialTicks, float par3, float par4, float par5, float par6, float par7){
GL11.glPushMatrix();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240, 240);
RenderHelper.disableStandardItemLighting();
Minecraft.getMinecraft().renderEngine.bindTexture(sparkleTextures);
tessellator.startDrawingQuads();
float f6 = (float)this.particleTextureIndexX / 4.0F;
float f7 = f6 + 0.0624375F*4;
float f8 = (float)this.particleTextureIndexY / 4.0F;
float f9 = f8 + 0.0624375F*4;
float f10 = 0.1F * this.particleScale;
if (this.particleIcon != null)
{
f6 = this.particleIcon.getMinU();
f7 = this.particleIcon.getMaxU();
f8 = this.particleIcon.getMinV();
f9 = this.particleIcon.getMaxV();
}
// Fix which gets proper values for interpPos so the particles don't appear to move.
Entity player = Minecraft.getMinecraft().thePlayer;
this.interpPosX = player.lastTickPosX + (player.posX - player.lastTickPosX) * (double)partialTicks;
this.interpPosY = player.lastTickPosY + (player.posY - player.lastTickPosY) * (double)partialTicks;
this.interpPosZ = player.lastTickPosZ + (player.posZ - player.lastTickPosZ) * (double)partialTicks;
float f11 = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX);
float f12 = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY);
float f13 = (float)(this.prevPosZ + (this.posZ - this.prevPosZ) * (double)partialTicks - interpPosZ);
float f14 = 1.0F;
tessellator.setColorRGBA_F(this.particleRed * f14, this.particleGreen * f14, this.particleBlue * f14, this.particleAlpha);
tessellator.addVertexWithUV((double)(f11 - par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 - par5 * f10 - par7 * f10), (double)f7, (double)f9);
tessellator.addVertexWithUV((double)(f11 - par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 - par5 * f10 + par7 * f10), (double)f7, (double)f8);
tessellator.addVertexWithUV((double)(f11 + par3 * f10 + par6 * f10), (double)(f12 + par4 * f10), (double)(f13 + par5 * f10 + par7 * f10), (double)f6, (double)f8);
tessellator.addVertexWithUV((double)(f11 + par3 * f10 - par6 * f10), (double)(f12 - par4 * f10), (double)(f13 + par5 * f10 - par7 * f10), (double)f6, (double)f9);
tessellator.draw();
GL11.glPopMatrix();
}
@Override
public int getBrightnessForRender(float par1)
{
return 15728880;
}
@Override
public float getBrightness(float par1)
{
return 1.0F;
}
}
@@ -1,135 +0,0 @@
package electroblob.wizardry.client.particle;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import electroblob.wizardry.Wizardry;
import net.minecraft.block.Block;
import net.minecraft.client.particle.EntityDiggingFX;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.init.Blocks;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
@SideOnly(Side.CLIENT)
public class EntityTornadoFX extends EntityDiggingFX
{
/** The name used to identify this particle. Uses the mod id to avoid any possible conflicts (Not that there would
* be any, but I may as well.) */
public static final String NAME = Wizardry.MODID + "tornado";
private boolean gravity = false;
private double angle;
private double radius;
private double speed;
private double velX, velZ;
private boolean fullBrightness = false;
public EntityTornadoFX(World world, int maxAge, double originX, double originZ, double radius, double yPos, double velX, double velZ, Block block, int metadata, int side)
{
super(world, 0, 0, 0, 0, 0, 0, block, metadata, side);
this.angle = this.rand.nextDouble() * Math.PI * 2;
double x = originX - Math.cos(angle)*radius;
double z = originZ + radius*Math.sin(angle);
this.radius = radius;
this.setPosition(x, yPos, z);
//this.particleScale *= 0.75F;
this.particleMaxAge = maxAge;
this.noClip = true;
// Grass has special treatment, since it has a colourised top but the rest is normal.
if(block != Blocks.grass || side == 1) this.setColour(block.getRenderColor(side));
if(block.getLightValue() == 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;
}
public EntityTornadoFX(World world, double x, double y, double z, double vx, double vy, double vz, float red, float green, float blue)
{
super(world, x, y, z, vx, vy, vz, Blocks.dirt, 0);
//this.particleScale *= 0.75F;
this.particleMaxAge = 48 + this.rand.nextInt(12);
this.noClip = true;
particleRed = red;
particleGreen = green;
particleBlue = blue;
}
public void setColour(int par1)
{
float f = (float)((par1 & 16711680) >> 16) / 255.0F;
float f1 = (float)((par1 & 65280) >> 8) / 255.0F;
float f2 = (float)((par1 & 255) >> 0) / 255.0F;
float f3 = 1.0F;
this.setRBGColorF(f * f3, f1 * f3, f2 * f3);
}
/**
* returns the bounding box for this entity
*/
public AxisAlignedBB getBoundingBox()
{
return null;
}
/**
* Returns true if this entity should push and be pushed by other entities when colliding.
*/
public boolean canBePushed()
{
return false;
}
@Override
public void onUpdate()
{
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if (this.particleAge++ >= this.particleMaxAge)
{
this.setDead();
}
// 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.moveEntity(motionX + velX, 0, motionZ + velZ);
if(this.gravity){
this.motionY -= 0.05d;
}
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 par1)
{
return fullBrightness ? 15728880 : super.getBrightnessForRender(par1);
}
@Override
public float getBrightness(float par1)
{
return fullBrightness ? 1.0F : super.getBrightness(par1);
}
}
@@ -0,0 +1,74 @@
package electroblob.wizardry.client.particle;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
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){
super(world, 0, 0, 0, 0, 0, 0, maxAge);
this.angle = this.rand.nextDouble() * Math.PI * 2;
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 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){
// super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ);
// }
// }
@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.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);
}
}
}
@@ -0,0 +1,217 @@
package electroblob.wizardry.client.particle;
import org.lwjgl.opengl.GL11;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.Entity;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
/**
* 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
* choose), and any properties like gravity and collisions.
*
* @author Electroblob
* @since Wizardry 1.2
*/
@SideOnly(Side.CLIENT)
public abstract class ParticleCustomTexture extends Particle {
/** True if the particle always renders at full brightness. Defaults to false. */
protected boolean fullBrightness = false;
public ParticleCustomTexture(World world, double x, double y, double z, double vx, double vy, double vz){
super(world, x, y, z, vx, vy, vz);
this.motionX = vx;
this.motionY = vy;
this.motionZ = vz;
this.init();
}
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.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.
*/
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.
*/
public abstract ResourceLocation getTexture();
/** Returns how many 'frames' there are in the x direction on the texture. */
protected abstract int getXFrames();
/** Returns how many 'frames' there are in the y direction on the texture. */
protected abstract int getYFrames();
/* There are 4 layers of particles, specified as 0-3 by the method below. - Layer 0 causes the normal particles.png
* to be bound to the render engine for normal particles. - Layer 1 causes the block textures to be bound to the
* render engine for digging fx and falling fx. - Layer 2 causes the item textures to be bound to the render engine
* for tool breaking fx, snowballpoofs, slime particles, etc. - Layer 3 is not used in vanilla minecraft and was
* presumably added by forge for exactly this reason. This means no texture is bound by vanilla minecraft, meaning
* you are free to do as you wish without possibly overwriting vanilla particles. Mod particles won't be overwritten
* anyway since they bind their own textures. It is of course important to bind the texture every time you render a
* custom particle, but I don't see how you could do it any other way, since you don't have access to
* EffectRenderer. */
@Override
public int getFXLayer(){
// This can only be 0-3 or it will cause an ArrayIndexOutOfBoundsException in EffectRenderer.
return 3;
}
@Override
public void setParticleTextureIndex(int index){
this.particleTextureIndexX = index % getXFrames();
this.particleTextureIndexY = index / getYFrames();
}
// Overridden to fix the bug with vanilla that makes particles frictionless. (y != y... seriously, Mojang?)
// TESTME: Probably no longer necessary.
// @Override
// public void move(double x, double y, double z){
//
// double d0 = y;
//
// if (this.canCollide)
// {
// List<AxisAlignedBB> list = this.world.getCollisionBoxes((Entity)null, this.getBoundingBox().addCoord(x, y, z));
//
// for (AxisAlignedBB axisalignedbb : list)
// {
// y = axisalignedbb.calculateYOffset(this.getBoundingBox(), y);
// }
//
// this.setBoundingBox(this.getBoundingBox().offset(0.0D, y, 0.0D));
//
// for (AxisAlignedBB axisalignedbb1 : list)
// {
// x = axisalignedbb1.calculateXOffset(this.getBoundingBox(), x);
// }
//
// this.setBoundingBox(this.getBoundingBox().offset(x, 0.0D, 0.0D));
//
// for (AxisAlignedBB axisalignedbb2 : list)
// {
// z = axisalignedbb2.calculateZOffset(this.getBoundingBox(), z);
// }
//
// this.setBoundingBox(this.getBoundingBox().offset(0.0D, 0.0D, z));
// }
// else
// {
// this.setBoundingBox(this.getBoundingBox().offset(x, y, z));
// }
//
// 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)
// {
// this.motionX = 0.0D;
// }
//
// if (z != z)
// {
// this.motionZ = 0.0D;
// }
// */
// }
// 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.
@Override
public void renderParticle(BufferBuilder buffer, Entity viewer, float partialTicks, float rotationX, float rotationZ,
float rotationYZ, float rotationXY, float rotationXZ){
GlStateManager.pushMatrix();
this.applyGLStateChanges();
// 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 lightmapX = brightness % 65536;
int lightmapY = brightness / 65536;
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, (float)lightmapX / 1.0F,
(float)lightmapY / 1.0F);
RenderHelper.disableStandardItemLighting();
Minecraft.getMinecraft().getTextureManager().bindTexture(getTexture());
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR);
float u1 = (float)this.particleTextureIndexX / (float)getXFrames();
float u2 = u1 + 1.0f / getXFrames();
float v1 = (float)this.particleTextureIndexY / (float)getYFrames();
float v2 = v1 + 1.0f / getYFrames();
float scale = 0.1F * this.particleScale;
// I'm pretty sure these were always static.
Particle.interpPosX = viewer.lastTickPosX + (viewer.posX - viewer.lastTickPosX) * (double)partialTicks;
Particle.interpPosY = viewer.lastTickPosY + (viewer.posY - viewer.lastTickPosY) * (double)partialTicks;
Particle.interpPosZ = viewer.lastTickPosZ + (viewer.posZ - viewer.lastTickPosZ) * (double)partialTicks;
float x = (float)(this.prevPosX + (this.posX - this.prevPosX) * (double)partialTicks - interpPosX);
float y = (float)(this.prevPosY + (this.posY - this.prevPosY) * (double)partialTicks - interpPosY);
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),
(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();
this.undoGLStateChanges();
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).
*/
public void applyGLStateChanges(){
}
/**
* 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
public int getBrightnessForRender(float partialTick){
return fullBrightness ? 15728880 : super.getBrightnessForRender(partialTick);
}
}
@@ -0,0 +1,78 @@
package electroblob.wizardry.client.particle;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.entity.Entity;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
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){
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;
this.particleMaxAge = (int)(8.0D / (Math.random() * 0.8D + 0.2D));
this.canCollide = true;
}
@Override
public void renderParticle(BufferBuilder buffer, Entity entity, float partialTicks, float rotationX, float rotationZ,
float rotationYZ, float rotationXY, float rotationXZ){
float f6 = ((float)this.particleAge + partialTicks) / (float)this.particleMaxAge * 32.0F;
if(f6 < 0.0F){
f6 = 0.0F;
}
if(f6 > 1.0F){
f6 = 1.0F;
}
super.renderParticle(buffer, entity, partialTicks, rotationX, rotationZ, rotationYZ, rotationXY, rotationXZ);
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate(){
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if(this.particleAge++ >= this.particleMaxAge){
this.setExpired();
}
this.setParticleTextureIndex(this.baseSpellTextureIndex + (7 - this.particleAge * 8 / this.particleMaxAge));
this.motionY += 0.004D;
this.move(this.motionX, this.motionY, this.motionZ);
/* if (this.posY == this.prevPosY) { this.motionX *= 1.1D; this.motionZ *= 1.1D; } */
this.motionX *= 0.9599999785423279D;
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;
}
}
@@ -0,0 +1,48 @@
package electroblob.wizardry.client.particle;
import net.minecraft.client.particle.Particle;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ParticleDust extends Particle {
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;
}
/**
* Called to update the entity's position/logic.
*/
public void onUpdate(){
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
// this.moveEntity(this.motionX, this.motionY, this.motionZ);
if(this.particleMaxAge-- <= 0){
this.setExpired();
}
}
@Override
public int getBrightnessForRender(float par1){
return shaded ? super.getBrightnessForRender(par1) : 15728880;
}
/* @Override public float getBrightness(float par1) { return shaded ? super.getBrightness(par1) : 1.0F; } */
}
@@ -0,0 +1,49 @@
package electroblob.wizardry.client.particle;
import electroblob.wizardry.Wizardry;
import net.minecraft.client.particle.Particle;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
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 be
* any, but I may as well.)
*/
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));
}
/**
* Called to update the entity's position/logic.
*/
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();
}
}
}
@@ -0,0 +1,46 @@
package electroblob.wizardry.client.particle;
import electroblob.wizardry.Wizardry;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ParticleIce extends ParticleCustomTexture {
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){
super(world, x, y, z, vx, vy, vz);
}
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);
}
@Override
public void init(){
this.setParticleTextureIndex(rand.nextInt(8));
this.particleScale *= 0.75f;
this.particleGravity = 1;
this.canCollide = true;
this.fullBrightness = true;
}
@Override
public ResourceLocation getTexture(){
return TEXTURE;
}
@Override
protected int getXFrames(){
return 4;
}
@Override
protected int getYFrames(){
return 4;
}
}
@@ -0,0 +1,45 @@
package electroblob.wizardry.client.particle;
import electroblob.wizardry.Wizardry;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ParticleLeaf extends ParticleCustomTexture {
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){
super(world, x, y, z, vx, vy, vz);
}
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);
}
@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
protected int getXFrames(){
return 4;
}
@Override
protected int getYFrames(){
return 4;
}
}
@@ -0,0 +1,46 @@
package electroblob.wizardry.client.particle;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.entity.Entity;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
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){
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 void renderParticle(BufferBuilder buffer, Entity entity, float partialTicks, float rotationX, float rotationZ,
float rotationYZ, float rotationXY, float rotationXZ){
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;
}
}
@@ -0,0 +1,107 @@
package electroblob.wizardry.client.particle;
import org.lwjgl.opengl.GL11;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.spell.Clairvoyance;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
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){
super(world, x, y, z, vx, vy, vz);
this.setRBGColorF(r, g, b);
this.originX = x;
this.originY = y;
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){
super(world, x, y, z, vx, vy, vz, maxAge);
this.setRBGColorF(r, g, b);
this.originX = x;
this.originY = y;
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
public void onUpdate(){
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if(this.particleAge++ >= this.particleMaxAge){
this.setExpired();
}
this.move(this.motionX, this.motionY, this.motionZ);
// Fading
if(this.particleAge > this.particleMaxAge / 2){
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);
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
}
}
@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();
}
}
@@ -0,0 +1,61 @@
package electroblob.wizardry.client.particle;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
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){
super(world, 0, 0, 0, 0, 0, 0, r, g, b, maxAge);
this.angle = this.rand.nextDouble() * Math.PI * 2;
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 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.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);
}
}
}
@@ -0,0 +1,45 @@
package electroblob.wizardry.client.particle;
import electroblob.wizardry.Wizardry;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ParticleSnow extends ParticleCustomTexture {
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){
super(world, x, y, z, vx, vy, vz);
}
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);
}
@Override
public void init(){
this.setParticleTextureIndex(rand.nextInt(8));
this.particleScale *= 0.6f;
this.particleGravity = 0;
this.canCollide = true;
}
@Override
public ResourceLocation getTexture(){
return TEXTURE;
}
@Override
protected int getXFrames(){
return 4;
}
@Override
protected int getYFrames(){
return 4;
}
}
@@ -0,0 +1,70 @@
package electroblob.wizardry.client.particle;
import org.lwjgl.opengl.GL11;
import electroblob.wizardry.Wizardry;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
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
public void onUpdate(){
super.onUpdate();
// Well this is handy! Looks like vanilla uses the texture index like this too.
this.nextTextureIndexX();
}
@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();
}
}
@@ -0,0 +1,111 @@
package electroblob.wizardry.client.particle;
import electroblob.wizardry.Wizardry;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class ParticleSparkle extends ParticleCustomTexture {
/* 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
* that in the particle spawning method itself. */
private static final ResourceLocation TEXTURE = new ResourceLocation(Wizardry.MODID,
"textures/particle/sparkle_particles.png");
// NOTE: Uncomment once 2.1.0 is released
// private final float initialRed;
// private final float initialGreen;
// private final float initialBlue;
// TODO: Assign these via the constructors, as part of the refactoring for particle parameters.
// NOTE: Uncomment once 2.1.0 is released
// private final float fadeRed = 1;
// private final float fadeGreen = 1;
// 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){
super(world, x, y, z, vx, vy, vz);
this.setRBGColorF(r, g, b);
// NOTE: Uncomment once 2.1.0 is released
// initialRed = r;
// initialGreen = g;
// initialBlue = b;
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){
super(world, x, y, z, vx, vy, vz, maxAge);
this.setRBGColorF(r, g, b);
// NOTE: Uncomment once 2.1.0 is released
// initialRed = r;
// initialGreen = g;
// 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 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. */
}
@@ -0,0 +1,85 @@
package electroblob.wizardry.client.particle;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.particle.ParticleDigging;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
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){
super(world, 0, 0, 0, 0, 0, 0, block);
this.angle = this.rand.nextDouble() * Math.PI * 2;
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;
// 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 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);
}
}
@@ -0,0 +1,154 @@
package electroblob.wizardry.client.renderer;
import java.util.Map.Entry;
import org.lwjgl.opengl.GL11;
import electroblob.wizardry.client.ClientProxy;
import electroblob.wizardry.spell.Petrify;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.ModelBase;
import net.minecraft.client.model.ModelBiped;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.GlStateManager.DestFactor;
import net.minecraft.client.renderer.GlStateManager.SourceFactor;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.client.renderer.entity.RenderLivingBase;
import net.minecraft.client.renderer.entity.layers.LayerRenderer;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
/**
* Layer used to render the stone texture on a petrified creature. Handles dynamic tiling of the stone texture.
*
* @author Electroblob
* @since Wizardry 1.2
*/
public class LayerStone implements LayerRenderer<EntityLivingBase> {
protected ModelBase model;
private final RenderLivingBase<?> renderer;
private static final ResourceLocation texture = new ResourceLocation("textures/blocks/stone.png");
public static void initialiseLayers(){
for(Entry<Class<? extends Entity>, Render<? extends Entity>> entry : Minecraft.getMinecraft()
.getRenderManager().entityRenderMap.entrySet()){
// Because the zombie classes are now split properly, their renderers play nicely like everything else.
if(entry.getValue() instanceof RenderLivingBase){
// 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.
((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()
}
}
public LayerStone(RenderLivingBase<?> renderer){
this.renderer = renderer;
this.model = renderer.getMainModel();
}
@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();
int i = this.getBlockBrightnessForEntity(entity, partialTicks);
int j = i % 65536;
int k = i / 65536;
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(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){
GlStateManager.pushMatrix();
// Enables tiling (Also used for guardian beam, beacon beam and ender crystal beam)
// 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_T, GL11.GL_REPEAT);
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.
// Changes the scale at which the texture is applied to the model. See LayerCreeper for a similar example,
// 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.loadIdentity();
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
// (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){
scaleX = (double)model.boxList.get(0).textureWidth / 16d;
scaleY = (double)model.boxList.get(0).textureHeight / 16d;
}else{ // Fallback to model fields; should never be needed
scaleX = (double)model.textureWidth / 16d;
scaleY = (double)model.textureHeight / 16d;
}
GlStateManager.scale(scaleX, scaleY, 1);
GlStateManager.matrixMode(GL11.GL_MODELVIEW);
// 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.render(entity, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale);
if(this.model instanceof ModelBiped) ((ModelBiped)this.model).bipedHeadwear.isHidden = false;
// Undoes the texture scaling
GlStateManager.matrixMode(GL11.GL_TEXTURE);
GlStateManager.loadIdentity();
GlStateManager.matrixMode(GL11.GL_MODELVIEW);
GlStateManager.popMatrix();
}
@Override
public boolean shouldCombineTextures(){
return false;
}
}
@@ -7,8 +7,9 @@ class RayHelper implements Comparable<RayHelper> {
double x1, y1, z1;
double x2, y2, z2;
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.x1 = x1;
this.y1 = y1;
@@ -20,20 +21,20 @@ class RayHelper implements Comparable<RayHelper> {
this.offsetY = offsetY;
this.offsetZ = offsetZ;
}
double getDistanceFromViewpoint(){
double midX = (x1+x2)/2;
double midY = (y1+y2)/2;
double midZ = (z1+z2)/2;
double absoluteX = offsetX+midX;
double absoluteY = offsetY+midY;
double absoluteZ = offsetZ+midZ;
return Math.sqrt(absoluteX*absoluteX + absoluteY*absoluteY + absoluteZ*absoluteZ);
double midX = (x1 + x2) / 2;
double midY = (y1 + y2) / 2;
double midZ = (z1 + z2) / 2;
double absoluteX = offsetX + midX;
double absoluteY = offsetY + midY;
double absoluteZ = offsetZ + midZ;
return Math.sqrt(absoluteX * absoluteX + absoluteY * absoluteY + absoluteZ * absoluteZ);
}
@Override
public int compareTo(RayHelper ray){
if(this.getDistanceFromViewpoint() > ray.getDistanceFromViewpoint()){
@@ -1,136 +1,133 @@
package electroblob.wizardry.client.renderer;
import java.util.Random;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.entity.EntityArc;
import electroblob.wizardry.entity.projectile.EntityMagicMissile;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityClientPlayerMP;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.Render;
import net.minecraft.entity.Entity;
import net.minecraft.util.MathHelper;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.ResourceLocation;
public class RenderArc extends Render {
public class RenderArc extends Render<EntityArc> {
private static final ResourceLocation[] textures = new ResourceLocation[16];
public RenderArc(){
for(int i=0;i<16;i++){
textures[i] = new ResourceLocation("wizardry:textures/entity/arc_" + i + ".png");
public RenderArc(RenderManager renderManager){
super(renderManager);
for(int i = 0; i < 16; i++){
textures[i] = new ResourceLocation(Wizardry.MODID, "textures/entity/arc_" + i + ".png");
}
}
@Override
public void doRender(Entity entity, double d0, double d1, double d2,
float fa, float fb) {
GL11.glPushMatrix();
GL11.glTranslatef((float)d0, (float)d1, (float)d2);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); //This line fixes the weird brightness bug.
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
//System.out.println("Entity coords: " + entity.posX + ", " + entity.posY + ", " + entity.posZ);
//System.out.println("doRender parameters: " + d0 + ", " + d1 + ", " + d2 + ", " + fa + ", " + fb);
Tessellator tessellator = Tessellator.instance;
if(entity instanceof EntityArc){
EntityArc arc = (EntityArc)entity;
bindTexture(textures[arc.textureIndex]); // This MUST be after the tessellator declaration and the gl stuff
/**
* Note: A lot of the maths here works on similar triangles and the ratios between them, avoiding too much
* pythagoras and eliminating the need for any trig. Ratios are used for the positioning of the arc endpoints.
* Ratios are usually used swapping x and z because the triangles are rotated through 90 degrees.
*/
double dx = -d0;
double dy = -d1;
double dz = -d2;
if(arc.x1 != 0){
dx = arc.x1 - arc.posX;// - d2/lengthOffsetRatio;
dy = arc.y1 - arc.posY + 0.3;
dz = arc.z1 - arc.posZ;// + d0/lengthOffsetRatio;
//The distance from caster to target
double arcLength = Math.sqrt(dz*dz+dx*dx);
//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).
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 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);
//Half the width of the arc
double arcWidth = 0.3d;
//Right hand side of vertical plane
tessellator.startDrawingQuads();
//Target end
tessellator.addVertexWithUV(0, -0.5, 0, 1, 1);
tessellator.addVertexWithUV(0, 0.5, 0, 1, 0);
//Caster end
tessellator.addVertexWithUV(dx, dy, dz, 0, 0);
tessellator.addVertexWithUV(dx, dy-1, dz, 0, 1);
tessellator.draw();
//Left
tessellator.startDrawingQuads();
//Target end
tessellator.addVertexWithUV(0, -0.5, 0, 1, 1);
//Caster end
tessellator.addVertexWithUV(dx, dy-1, dz, 0, 1);
tessellator.addVertexWithUV(dx, dy, dz, 0, 0);
//Target end
tessellator.addVertexWithUV(0, 0.5, 0, 1, 0);
tessellator.draw();
//Bottom of horizontal plane
tessellator.startDrawingQuads();
tessellator.addVertexWithUV((arcWidth/arcLength)*dz, 0, (-arcWidth/arcLength)*dx, 1, 1);
tessellator.addVertexWithUV(dx + (arcWidth/arcLength)*dz, dy-0.5, dz - (arcWidth/arcLength)*dx, 0, 1);
tessellator.addVertexWithUV(dx - (arcWidth/arcLength)*dz, dy-0.5, dz + (arcWidth/arcLength)*dx, 0, 0);
tessellator.addVertexWithUV((-arcWidth/arcLength)*dz, 0, (arcWidth/arcLength)*dx, 1, 0);
tessellator.draw();
//Top
tessellator.startDrawingQuads();
tessellator.addVertexWithUV((arcWidth/arcLength)*dz, 0, (-arcWidth/arcLength)*dx, 1, 1);
tessellator.addVertexWithUV((-arcWidth/arcLength)*dz, 0, (arcWidth/arcLength)*dx, 1, 0);
tessellator.addVertexWithUV(dx - (arcWidth/arcLength)*dz, dy-0.5, dz + (arcWidth/arcLength)*dx, 0, 0);
tessellator.addVertexWithUV(dx + (arcWidth/arcLength)*dz, dy-0.5, dz - (arcWidth/arcLength)*dx, 0, 1);
tessellator.draw();
}
}
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_BLEND);
GL11.glPopMatrix();
}
@Override
protected ResourceLocation getEntityTexture(Entity entity) {
if(entity instanceof EntityArc){
return textures[((EntityArc)entity).textureIndex];
public void doRender(EntityArc arc, double d0, double d1, double d2, float fa, float fb){
GlStateManager.pushMatrix();
GlStateManager.translate((float)d0, (float)d1, (float)d2);
GlStateManager.disableLighting();
GlStateManager.enableBlend();
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);
// System.out.println("Entity coords: " + entity.posX + ", " + entity.posY + ", " + entity.posZ);
// System.out.println("doRender parameters: " + d0 + ", " + d1 + ", " + d2 + ", " + fa + ", " + fb);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buffer = tessellator.getBuffer();
bindTexture(textures[arc.textureIndex]); // This MUST be after the tessellator declaration and the gl stuff
/**
* Note: A lot of the maths here works on similar triangles and the ratios between them, avoiding too much
* pythagoras and eliminating the need for any trig. Ratios are used for the positioning of the arc endpoints.
* Ratios are usually used swapping x and z because the triangles are rotated through 90 degrees.
*/
double dx = -d0;
double dy = -d1;
double dz = -d2;
if(arc.x1 != 0){
dx = arc.x1 - arc.posX;// - d2/lengthOffsetRatio;
dy = arc.y1 - arc.posY + 0.3;
dz = arc.z1 - arc.posZ;// + d0/lengthOffsetRatio;
// The distance from caster to target
double arcLength = Math.sqrt(dz * dz + dx * dx);
// 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).
// double lengthOffsetRatio = arcLength/0.3;
// EntityClientPlayerMP player = Minecraft.getMinecraft().player;
// double xViewDist = player.posX - d0;
// 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);
// Half the width of the arc
double arcWidth = 0.3d;
// Right hand side of vertical plane
buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX);
// Target end
buffer.pos(0, -0.5, 0).tex(1, 1).endVertex();
buffer.pos(0, 0.5, 0).tex(1, 0).endVertex();
// Caster end
buffer.pos(dx, dy, dz).tex(0, 0).endVertex();
buffer.pos(dx, dy - 1, dz).tex(0, 1).endVertex();
tessellator.draw();
// Left
buffer.begin(GL11.GL_QUADS, net.minecraft.client.renderer.vertex.DefaultVertexFormats.POSITION_TEX);
// Target end
buffer.pos(0, -0.5, 0).tex(1, 1).endVertex();
// Caster end
buffer.pos(dx, dy - 1, dz).tex(0, 1).endVertex();
buffer.pos(dx, dy, dz).tex(0, 0).endVertex();
// Target end
buffer.pos(0, 0.5, 0).tex(1, 0).endVertex();
tessellator.draw();
// Bottom of horizontal plane
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(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, 0)
.endVertex();
buffer.pos((-arcWidth / arcLength) * dz, 0, (arcWidth / arcLength) * dx).tex(1, 0).endVertex();
tessellator.draw();
// Top
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, 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, 1)
.endVertex();
tessellator.draw();
}
return null;
GlStateManager.enableLighting();
GlStateManager.disableBlend();
GlStateManager.popMatrix();
}
@Override
protected ResourceLocation getEntityTexture(EntityArc entity){
return textures[entity.textureIndex];
}
}
@@ -1,105 +1,98 @@
package electroblob.wizardry.client.renderer;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.opengl.GL11;
import electroblob.wizardry.Wizardry;
import electroblob.wizardry.tileentity.ContainerArcaneWorkbench;
import electroblob.wizardry.tileentity.TileEntityArcaneWorkbench;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
public class RenderArcaneWorkbench extends TileEntitySpecialRenderer<TileEntityArcaneWorkbench> {
private static final ResourceLocation runeTexture = new ResourceLocation(Wizardry.MODID, "textures/entity/rune.png");
public RenderArcaneWorkbench(){}
public class RenderArcaneWorkbench extends TileEntitySpecialRenderer
{
private final RenderBlocks renderBlocksInstance = new RenderBlocks();
private static final ResourceLocation runeTexture = new ResourceLocation("wizardry:textures/entity/rune.png");
public RenderArcaneWorkbench(){
}
@Override
public void renderTileEntityAt(TileEntity tileentity, double x, double y, double z, float f) {
GL11.glPushMatrix();
// It seems that these next two lines make stuff render in the same place relative to the world wherever
// the player is.
GL11.glTranslatef((float)x + 0.5F, (float)y +1.5F, (float)z + 0.5F);
GL11.glRotatef(180, 0F, 0F, 1F);
GL11.glPushMatrix();
double angle = 0.0d;
if(x < -0.5){
angle = Math.toDegrees(Math.atan((z+0.5)/(x+0.5))) + 180;
}else{
angle = Math.toDegrees(Math.atan((z+0.5)/(x+0.5)));
}
this.renderEffect((TileEntityArcaneWorkbench)tileentity);
this.renderWand((TileEntityArcaneWorkbench)tileentity, angle);
GL11.glPopMatrix();
GL11.glPopMatrix();
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.rotate(180, 0F, 0F, 1F);
GlStateManager.pushMatrix();
double angle = 0.0d;
if(x < -0.5){
angle = Math.toDegrees(Math.atan((z + 0.5) / (x + 0.5))) + 180;
}else{
angle = Math.toDegrees(Math.atan((z + 0.5) / (x + 0.5)));
}
this.renderEffect(tileentity);
this.renderWand(tileentity, angle);
GlStateManager.popMatrix();
GlStateManager.popMatrix();
}
private void renderEffect(TileEntityArcaneWorkbench tileentity) {
ItemStack itemstack = tileentity.getStackInSlot(ContainerArcaneWorkbench.WAND_SLOT);
if(itemstack != null){
GL11.glPushMatrix();
GL11.glDisable(GL11.GL_LIGHTING);
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); //This line fixes the weird brightness bug.
GL11.glRotatef(tileentity.timer, 0.0f, 1.0f, 0.0f);
GL11.glTranslatef(0.0f, 0.65f, 0.0f);
Tessellator tessellator = Tessellator.instance;
private void renderEffect(TileEntityArcaneWorkbench tileentity){
ItemStack itemstack = tileentity.getStackInSlot(ContainerArcaneWorkbench.WAND_SLOT);
if(!itemstack.isEmpty()){
GlStateManager.pushMatrix();
GlStateManager.disableLighting();
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
GlStateManager.enableBlend();
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();
BufferBuilder buffer = tessellator.getBuffer();
bindTexture(runeTexture);
tessellator.startDrawingQuads();
tessellator.addVertexWithUV(-0.5f, 0, -0.5f, 0, 0);
tessellator.addVertexWithUV(0.5f, 0, -0.5f, 1, 0);
tessellator.addVertexWithUV(0.5f, 0, 0.5f, 1, 1);
tessellator.addVertexWithUV(-0.5f, 0, 0.5f, 0, 1);
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(1, 0).endVertex();
buffer.pos(0.5f, 0, 0.5f).tex(1, 1).endVertex();
buffer.pos(-0.5f, 0, 0.5f).tex(0, 1).endVertex();
tessellator.draw();
GL11.glDisable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glPopMatrix();
}
GlStateManager.disableBlend();
GlStateManager.enableLighting();
GlStateManager.popMatrix();
}
}
/**
* 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
*/
private void renderWand(TileEntityArcaneWorkbench tileentity, double viewAngle)
{
ItemStack itemstack = tileentity.getStackInSlot(ContainerArcaneWorkbench.WAND_SLOT);
if (itemstack != null)
{
EntityItem entityitem = new EntityItem(tileentity.getWorldObj(), 0.0d, 0.0d, 0.0d, itemstack);
entityitem.hoverStart = 0.0F;
GL11.glPushMatrix();
GL11.glRotatef(180.0F, 1.0F, 0.0F, 0.0F);
GL11.glRotatef(90.0F, 1.0F, 0.0F, 0.0F);
GL11.glRotated(180, 0, 1, 0);
// View angle is negated because of the 180 flip.
GL11.glRotated(-viewAngle-90, 0, 0, 1);
// Does the floaty thing
GL11.glTranslatef(0.0F, -0.25F, (float)tileentity.yOffset/5000.0F - 0.55f);
GL11.glScalef(1.5F, 1.5F, 1.5F);
RenderItem.renderInFrame = true; // Not too sure what this is
RenderManager.instance.renderEntityWithPosYaw(entityitem, 0.0d, 0.0d, 0.0d, 0.0F, 0.0F);
RenderItem.renderInFrame = false;
GL11.glPopMatrix();
}
}
private void renderWand(TileEntityArcaneWorkbench tileentity, double viewAngle){
ItemStack stack = tileentity.getStackInSlot(ContainerArcaneWorkbench.WAND_SLOT);
if(!stack.isEmpty()){
GlStateManager.pushMatrix();
//GlStateManager.rotate(180.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((float)(viewAngle - 90f), 0, 0, 1);
// Does the floaty thing
GlStateManager.translate(0.0F, 0.0F, (float)tileentity.yOffset / 5000.0F + 0.55f);
GlStateManager.scale(0.75F, 0.75F, 0.75F);
// This is what the item frame uses so it's definitely what we want.
Minecraft.getMinecraft().getRenderItem().renderItem(stack, TransformType.FIXED);
GlStateManager.popMatrix();
}
}
}

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